Vertical Violin Plot in Vega - vega

I'm trying to swap the axes on the violin plot example provided by the Vega documentation here. When attempting this myself (link here) I seem successful in swapping the axes, and the rectangles seem to render fine. However the area chart (the actual violin) is completely absent. I'm completely at a loss on this. Any help would be much appriciated.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A violin plot example showing distributions for pengiun body mass.",
"width": 800,
"height": 600,
"padding": 5,
"config": {
"axisBand": {"bandPosition": 1, "tickExtra": true, "tickOffset": 0}
},
"signals": [
{"name": "plotWidth", "update": "(width - 30)/3"},
{"name": "height", "update": "height * 1"},
{"name": "trim", "value": true, "bind": {"input": "checkbox"}},
{
"name": "bandwidth",
"value": 0,
"bind": {"input": "range", "min": 0, "max": 200, "step": 1}
}
],
"data": [
{
"name": "penguins",
"url": "data/penguins.json",
"transform": [
{
"type": "filter",
"expr": "datum.Species != null && datum['Body Mass (g)'] != null"
}
]
},
{
"name": "density",
"source": "penguins",
"transform": [
{
"type": "kde",
"field": "Body Mass (g)",
"groupby": ["Species"],
"bandwidth": {"signal": "bandwidth"},
"extent": {"signal": "trim ? null : [2000, 6500]"}
}
]
},
{
"name": "stats",
"source": "penguins",
"transform": [
{
"type": "aggregate",
"groupby": ["Species"],
"fields": ["Body Mass (g)", "Body Mass (g)", "Body Mass (g)"],
"ops": ["q1", "median", "q3"],
"as": ["q1", "median", "q3"]
}
]
}
],
"scales": [
{
"name": "layout",
"type": "band",
"range": "width",
"domain": {"data": "penguins", "field": "Species"}
},
{
"name": "yscale",
"type": "linear",
"range": "height",
"round": true,
"domain": {"data": "penguins", "field": "Body Mass (g)"},
"domainMin": 0,
"zero": false,
"nice": true
},
{
"name": "hscale",
"type": "linear",
"range": [0, {"signal": "plotWidth"}],
"domain": {"data": "density", "field": "density"}
},
{
"name": "color",
"type": "ordinal",
"domain": {"data": "penguins", "field": "Species"},
"range": "category"
}
],
"axes": [
{"orient": "bottom", "scale": "layout", "zindex": 1},
{"orient": "left", "scale": "yscale", "zindex": 1}
],
"marks": [
{
"type": "group",
"from": {
"facet": {"data": "density", "name": "violin", "groupby": "Species"}
},
"encode": {
"enter": {
"xc": {"scale": "layout", "field": "Species", "band": 0.5},
"width": {"signal": "plotWidth"},
"height": {"signal": "height"}
}
},
"data": [
{
"name": "summary",
"source": "stats",
"transform": [
{"type": "filter", "expr": "datum.Species === parent.Species"}
]
}
],
"marks": [
{
"type": "area",
"from": {"data": "violin"},
"encode": {
"enter": {
"fill": {"scale": "color", "field": {"parent": "Species"}}
},
"update": {
"y": {"scale": "yscale", "field": "value"},
"xc": {"signal": "plotWidth / 2"},
"width": {"scale": "hscale", "field": "density"}
}
}
},
{
"type": "rect",
"from": {"data": "summary"},
"encode": {
"enter": {"fill": {"value": "black"}, "width": {"value": 2}},
"update": {
"y": {"scale": "yscale", "field": "q1"},
"y2": {"scale": "yscale", "field": "q3"},
"xc": {"signal": "plotWidth / 2"}
}
}
},
{
"type": "rect",
"from": {"data": "summary"},
"encode": {
"enter": {
"fill": {"value": "black"},
"height": {"value": 2},
"width": {"value": 8}
},
"update": {
"y": {"scale": "yscale", "field": "median"},
"xc": {"signal": "plotWidth / 2"}
}
}
}
]
}
]
}
Chart Image

Was able to figure this out, required an "orient" parameter in the encoding of the area mark.
"marks": [
{
"type": "area",
"from": {"data": "violin"},
"encode": {
"enter": {
"orient": {"value":"horizontal"},
"fill": {"scale": "color", "field": {"parent": "Species"}}
},
"update": {
"y": {"field":"value", "scale":"yscale"},
"xc": {"signal": "plotWidth / 2"},
"width": {"scale": "hscale", "field": "density"}
}
}
},
Example Here

Related

What type of Vega marks to show a point along a scale? (see image)

I am attempting to create a visualization where we are showing a score along a scale, something like this:
The scale is based on quartiles of a large dataset (these are pre-calculated and don’t need to be calculated within Vega). In this particular example, the scale looks like this:
Break
Value
Min
0
Low
26.3
Mid
42.9
High
54.8
Max
70.7
So in the example image above, the score we are reporting is something like 56 (I will display the score with a tooltip).
At this point, I’m not even sure what type of marks I should be using in Vega to attempt to create this display. Any help getting started is greatly appreciated!
Here is a complete example in Vega.
Open in Vega on-line editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 100,
"padding": 5,
"data": [
{
"name": "data_segments",
"values": [
{"segmentLabel": "min", "segmentStart": 0, "segmentEnd": 26.3},
{"segmentLabel": "low", "segmentStart": 26.3, "segmentEnd": 42.9},
{"segmentLabel": "mid", "segmentStart": 42.9, "segmentEnd": 54.8},
{"segmentLabel": "high", "segmentStart": 54.8, "segmentEnd": 70.7}
]
}
],
"signals": [
{
"name": "signal_score",
"value": "56",
"bind": {"input": "range", "min": 0, "max": 70.7, "step": 0.01, "name": "Score: "}
},
{
"name": "signal_score_mid",
"value": "42.9"
}
],
"scales": [
{
"name": "scale_x",
"type": "linear",
"domain": {"data": "data_segments", "fields": ["segmentStart", "segmentEnd"]},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "scale_y",
"domain": [0, 1],
"range": "height"
},
{
"name": "scale_segment_color",
"type": "ordinal",
"domain": ["min", "low", "mid", "high"],
"range": ["grey", "green", "orange", "red"]
},
{
"name": "scale_segment_opacity",
"type": "ordinal",
"domain": ["min", "low", "mid", "high"],
"range": [0.5, 0.5, 0.5, 0.5]
}
],
"axes": [
{ "orient": "bottom", "scale": "scale_x" },
{ "orient": "left", "scale": "scale_y", "domainOpacity": 0, "tickOpacity": 0, "labelOpacity": 0}
],
"marks": [
{
"type": "rect",
"from": {"data":"data_segments"},
"encode": {
"enter": {
"x": {"scale": "scale_x", "field": "segmentStart"},
"x2": {"scale": "scale_x", "field": "segmentEnd"},
"y": {"scale": "scale_y", "value": 0.5},
"y2": {"scale": "scale_y", "value": 0.7},
"fill": {"scale": "scale_segment_color", "field": "segmentLabel"},
"fillOpacity":{"scale": "scale_segment_opacity", "field": "segmentLabel"},
"stroke": {"value": "white"}
}
}
},
{
"type": "text",
"from": {"data":"data_segments"},
"encode": {
"enter": {
"align": {"value": "center"},
"baseline": {"value": "top"},
"fill": {"value": "black"},
"fillOpacity": {"signal": "datum['segmentLabel'] == 'min' ? 0 : 1 "},
"x": {"scale": "scale_x", "field": "segmentStart"},
"y": {"scale": "scale_y", "value": 0.4},
"text": {"field": "segmentLabel"}
}
}
},
{
"type": "rect",
"from": {"data":"data_segments"},
"encode": {
"update": {
"x": {"signal": "scale('scale_x', signal_score) - 5"},
"x2": {"signal": "scale('scale_x', signal_score) + 5"},
"y": {"scale": "scale_y", "value": 0.45},
"y2": {"scale": "scale_y", "value": 0.75},
"fill": {"value": "red"},
"fillOpacity":{"value": 0.7},
"stroke": {"value": "grey"},
"tooltip": {"signal": "signal_score"}
}
}
},
{
"type": "rule",
"from": {"data":"data_segments"},
"encode": {
"update": {
"x": {"signal": "scale('scale_x', signal_score_mid)"},
"x2": {"signal": "scale('scale_x', signal_score) + ((signal_score > signal_score_mid) ? -15 : 15)"},
"y": {"scale": "scale_y", "value": 0.6},
"stroke": {"value": "blue"},
"strokeWidth": {"value": 2},
"opacity": {"value": 1}
}
}
},
{
"type": "symbol",
"from": {"data":"data_segments"},
"encode": {
"update": {
"x": {"signal": "scale('scale_x', signal_score) + ((signal_score > signal_score_mid) ? -15 : 15)"},
"y": {"scale": "scale_y", "value": 0.6},
"angle": {"signal": "signal_score > signal_score_mid ? 90 : -90"},
"size": {"value": 100},
"shape": {"value": "triangle"},
"opacity": {"value": 1},
"fill": {"value": "blue"}
}
}
}
]
}

Labels on Rects in Vega Stacked Bar Chart

In the old vega-label documentation there is reference to a labeled stacked bar chart example. The example spec doesn’t work in the online Vega editor, throwing an error that a.map is not a function.
I am trying to do almost exactly what is referenced in the above example: create a vertically-stacked bar chart where each segment is labeled with its value. I have seen a few examples of this in Vega-Lite with layers, but how can it be achieved in Vega?
I’ve attempted to recreate the above spec using a group containing the rect mark and the text mark, but I’m not getting it right. I also see how to display the value as a tooltip on hover, but I’d like it displayed in the rectangle of each segment of the bar itself.
Ideally I would end up with a chart like this:
Here’s the spec I’ve been working with:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A basic stacked bar chart example.",
"width": 294,
"height": 200,
"padding": 5,
"autosize": {"type": "fit-x", "contains": "padding"},
"data": [
{
"name": "categories",
"values": [
{"y": 5, "c": 0, "name": "other"},
{"y": 7, "c": 1, "name": "corn"},
{"y": 22, "c": 2, "name": "pasture/hay"},
{"y": 31, "c": 3, "name": "developed"},
{"y": 35, "c": 4, "name": "forest"}
],
"transform": [
{
"type": "stack",
"field": "y"
}
]
}
],
"scales": [
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true, "zero": true,
"domain": {"data": "categories", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "categories", "field": "c"}
}
],
"axes": [
],
"marks": [
{
"name": "categoriesBars",
"type": "group",
"from": {"data": "categories"},
"zindex": 1,
"marks": [
{
"type": "rect",
"from": {"data": "categories"},
"encode": {
"enter": {
"x": {"value": 0},
"width": {"value": 294},
"y": {"scale": "y", "field": "y0"},
"y2": {"scale": "y", "field": "y1"},
"fill": {"scale": "color", "field": "c"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
}
},
{
"type": "text",
"encode": {
"enter": {
"y": {"field": {"parent": "y"}},
"x": {"value": 130},
"fill": [
{"test": "contrast('white', datum.fill) > contrast('black', datum.fill)", "value": "white"},
{"value": "black"}
],
"align": {"value": "center"},
"baseline": {"value": "middle"},
"text": {"field": {"parent": "name"}}
}
}
}
]
}
]
}
Is this what you're after?
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A basic stacked bar chart example.",
"width": 294,
"height": 200,
"padding": 5,
"autosize": {"type": "fit-x", "contains": "padding"},
"data": [
{
"name": "categories",
"values": [
{"y": 5, "c": 0, "name": "other"},
{"y": 7, "c": 1, "name": "corn"},
{"y": 22, "c": 2, "name": "pasture/hay"},
{"y": 31, "c": 3, "name": "developed"},
{"y": 35, "c": 4, "name": "forest"}
],
"transform": [{"type": "stack", "field": "y"}]
}
],
"scales": [
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": true,
"domain": {"data": "categories", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": {"scheme": "pastel2"},
"domain": {"data": "categories", "field": "c"}
}
],
"axes": [],
"marks": [
{
"name": "i",
"type": "rect",
"from": {"data": "categories"},
"encode": {
"enter": {
"x": {"value": 0},
"width": {"value": 294},
"y": {"scale": "y", "field": "y0"},
"y2": {"scale": "y", "field": "y1"},
"fill": {"scale": "color", "field": "c"}
},
"update": {"fillOpacity": {"value": 1}},
"hover": {"fillOpacity": {"value": 0.5}}
}
},
{
"type": "text",
"from": {"data": "i"},
"encode": {
"update": {
"y": {"field": "y"},
"dy": {"signal": "(datum.y2 - datum.y)/2"},
"x": {"signal": "width/2"},
"fill": [
{
"test": "contrast('white', datum.fill) > contrast('black', datum.fill)",
"value": "white"
},
{"value": "black"}
],
"align": {"value": "center"},
"baseline": {"value": "middle"},
"text": {"field": "datum.name"}
}
}
}
]
}

How can I get my Vega marks to update when a signal changes?

I am using Vega to plot a bar chart. I also have a drop down list 'signal' that is used to specify the sort order of the data:
...
"signals": [
{
"name": "sortby",
"value": "name",
"bind": {"input": "select", "options": ["name", "net_worth"]}
}
],
"data": [
{
"name": "people",
"values": [
{"name": "Grimes", "net_worth": 1.2},
{"name": "Johnny", "net_worth": 6},
{"name": "Elon", "net_worth": 100},
{"name": "Amber", "net_worth": 0.1}
],
"transform": [
{
"type": "collect",
"sort": {"field": {"signal": "sortby"}, "order": "ascending"}
}
]
}
],
...
The sort transform is working correctly, when the chart is initially rendered, the data is sorted according to the default sort value of 'name'.
When I change the selected sortby value I see that the 'people' data is correctly sorted (I can see this by inspecting the Data Viewer tab in the Vega editor), however the marks do not update.
I've made sure that the encode.update definition for the marks holds all the positional data. I'm a bit stumped as to why the chart doesn't update, it feels like it's probably just due to a simple oversight by me and I'm hoping that someone here can spot what the issue is!
The full code is pasted below and is also available in the editor: Open the Chart in the Vega Editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 400,
"padding": 5,
"signals": [
{
"name": "sortby",
"value": "name",
"bind": {"input": "select", "options": ["name", "net_worth"]}
}
],
"data": [
{
"name": "people",
"values": [
{"name": "Grimes", "net_worth": 1.2},
{"name": "Johnny", "net_worth": 6},
{"name": "Elon", "net_worth": 100},
{"name": "Amber", "net_worth": 0.1}
],
"transform": [
{
"type": "collect",
"sort": {"field": {"signal": "sortby"}, "order": "ascending"}
}
]
}
],
"scales": [
{
"name": "yscale",
"type": "band",
"domain": {"data": "people", "field": "name"},
"range": "height",
"padding": 0.1
},
{
"name": "xscale",
"domain": {"data": "people", "field": "net_worth"},
"nice": true,
"range": "width"
}
],
"axes": [
{"orient": "top", "scale": "xscale"},
{"orient": "bottom", "scale": "xscale"},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {"data": "people"},
"encode": {
"enter": {"fill": {"value": "steelblue"}},
"update": {
"height": {"scale": "yscale", "band": 1},
"width": {"scale": "xscale", "field": "net_worth"},
"x": {"scale": "xscale", "value": 0},
"y": {"scale": "yscale", "field": "name"}
},
"exit": {"width": {"scale": "xscale", "value": 0}}
}
}
]
}
This is currently an open bug as described here: https://github.com/vega/vega/issues/1417. You can register your interest on that page to see when it will be fixed. In the meantime, I have used the workaround described to get the functionality you're after.
Editor.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 400,
"padding": 5,
"signals": [
{
"name": "sortby",
"value": "name",
"bind": {"input": "select", "options": ["name", "net_worth"]}
}
],
"data": [
{
"name": "people",
"values": [
{"name": "Grimes", "net_worth": 1.2},
{"name": "Johnny", "net_worth": 6},
{"name": "Elon", "net_worth": 100},
{"name": "Amber", "net_worth": 0.1}
],
"transform": [
{
"type": "window",
"sort": {"field": {"signal": "sortby"}},
"ops": ["row_number"],
"fields": [null],
"as": ["rank"]
}
]
}
],
"scales": [
{
"name": "yscale",
"type": "band",
"domain": {
"data": "people",
"field": "name",
"sort": {"field": "rank", "op": "min"}
},
"range": "height",
"padding": 0.1
},
{
"name": "xscale",
"domain": {"data": "people", "field": "net_worth"},
"nice": true,
"range": "width"
}
],
"axes": [
{"orient": "top", "scale": "xscale"},
{"orient": "bottom", "scale": "xscale"},
{"orient": "left", "scale": "yscale"}
],
"marks": [
{
"type": "rect",
"from": {"data": "people"},
"encode": {
"enter": {"fill": {"value": "steelblue"}},
"update": {
"height": {"scale": "yscale", "band": 1},
"width": {"scale": "xscale", "field": "net_worth"},
"x": {"scale": "xscale", "value": 0},
"y": {"scale": "yscale", "field": "name"}
},
"exit": {"width": {"scale": "xscale", "value": 0}}
}
}
]
}

Vega How to SUM all descendants value of every node on a treemap

I am trying to access the sum of values for a node in VEGA. In other words, I want to display sum of "percentage" values of all leaves for each parent node.
Got the following Vega specs (https://gist.github.com/omerakko/655674f9f37e9361fe5378b6d440e411)
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "An example of treemap layout for hierarchical data.",
"width": 960,
"height": 500,
"padding": 2.5,
"autosize": "none",
"data": [
{
"name": "tree",
"url": "https://raw.githubusercontent.com/omerakko/VEGA/main/vegaTreemapData.json",
"transform": [
{
"type": "stratify",
"key": "id",
"parentKey": "parent"
},
{
"type": "treemap",
"field": "percentage",
"sort": {"field": "value", "order":"descending"},
"round": true,
"method": "resquarify",
"ratio": 1,
"size": [{"signal": "width"}, {"signal": "height"}],
"paddingOuter": 2,
"paddingInner":2
}
]
},
{
"name": "nodes",
"source": "tree",
"transform": [{ "type": "filter", "expr": "datum.children" }]
},
{
"name": "leaves",
"source": "tree",
"transform": [{ "type": "filter", "expr": "!datum.children" },
{"type": "filter", "expr": "datum.percentage > 0"}]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "nodes", "field": "name"},
"range": [
"transparent", "#dd96ba", "#dea84e", "#c83836", "#dfde9b",
"#5eafb9", "#adc35d"]
},
{
"name": "size",
"type": "ordinal",
"domain": [0, 1, 2, 3],
"range": [256, 28, 20, 14]
},
{
"name": "opacity",
"type": "ordinal",
"domain": [0, 1, 2, 3],
"range": [0.15, 0.5, 0.8, 1.0]
}
],
"marks": [
{
"type": "rect",
"from": {"data": "nodes"},
"interactive": false,
"encode": {
"enter": {
"fill": {"value":"#333238"},
"stroke": {"scale": "color", "field": "name"},
"strokeWidth":{"value": 5}
},
"update": {
"x": {"field": "x0"},
"y": {"field": "y0"},
"x2": {"field": "x1"},
"y2": {"field": "y1"},
"stroke": {"scale": "color", "field": "name"}
}
}
},
{
"type": "rect",
"from": {"data": "leaves"},
"encode": {
"enter": {
"stroke": {"value": "#fff"}
},
"update": {
"x": {"field": "x0"},
"y": {"field": "y0"},
"x2": {"field": "x1"},
"y2": {"field": "y1"},
"fill": {"value": "transparent"}
},
"hover": {
"fill": {"value": "red"}
}
}
},
{
"type": "text",
"from": {"data": "nodes"},
"interactive": false,
"encode": {
"enter": {
"font": {"value": "Helvetica Neue, Arial"},
"align": {"value": "center"},
"baseline": {"value": "middle"},
"fill": {"scale": "color", "field": "name"},
"text": {"field": "name"},
"fontSize": {"scale": "size", "field": "depth"}
},
"update": {
"x": {"signal": "0.5 * (datum.x0 + datum.x1)"},
"y": {"signal": "0.5 * (datum.y0 + datum.y1)"}
}
}
}
]
}
There is doc available https://vega.github.io/vega/docs/transforms/treemap/ here saying that I can access to what I want, but I couldnt manage to apply it to the specs.
It seems like it's not currently possible in Vega. There's this PR that hasn't been merged yet.
But you can work around that by manually aggregating the values and then looking them up. Here a gist in which there's now a total field for each node, the relevant part being:
{
"name": "leaves",
"source": "tree",
"transform": [
{"type": "filter", "expr": "!datum.children"},
{"type": "filter", "expr": "datum.percentage > 0.3"}
]
},
{
"name": "totals",
"source": "leaves",
"transform": [
{
"type": "aggregate",
"groupby": ["parent"],
"fields": ["percentage"],
"as": ["total"],
"ops": ["sum"]
}
]
},
{
"name": "nodes",
"source": "tree",
"transform": [
{"type": "filter", "expr": "datum.children"},
{
"type": "lookup",
"from": "totals",
"key": "parent",
"fields": ["id"],
"values": ["total"],
"as": ["total"]
}
]
},
Basically you just get sums of all the leaves by parent in totals and then, after constructing the base nodes dataset, look the total up in totals.
Note that this will only work for this particular example, where there are exactly two levels in the hierarchy.

How to include a range slider to transform Data in Vega?

What I have tried:
I included a range slider. This range slider is meant to change the way the data is filtered (see transform). (Almost like in this example https://vega.github.io/vega/examples/population-pyramid/)
The Issue:
When I change the slider's position on the graph, there is no change in the graph's input.
Question:
How could I change the code, so that my input parameters are changed through the user's interaction with the range slider?
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 200,
"padding": 20,
"signals": [
{
"name": "tooltip",
"value": {},
"on": [
{"events": "rect:mouseover", "update": "datum"},
{"events": "rect:mouseout", "update": "{}"}
]
},
{
"name": "Y_Value",
"bind":{"input": "range", "min": 0, "max": 100, "step": 1},
"value": 100
}
],
"data": [
{
"name": "table",
"values": [
{"category": "A", "amount": 28},
{"category": "B", "amount": 55},
{"category": "C", "amount": 43},
{"category": "D", "amount": 91},
{"category": "E", "amount": 81},
{"category": "F", "amount": 53},
{"category": "G", "amount": 19},
{"category": "H", "amount": 87}
]
},
{
"name": "range",
"source": "table",
"transform": [
{"type": "filter", "expr": "datum.amount <= Y_Value"}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {"data": "table", "field": "category"},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {"data": "table", "field": "amount"},
"nice": true,
"range": "height"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale",
"encode": {
"labels": {
"interactive": true,
"update": {
"tooltip": {"signal": "datum.label"}
}
}
}
},
{ "orient": "left", "scale": "yscale" }
],
"marks": [
{
"type": "rect",
"from": {"data":"table"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "category"},
"width": {"scale": "xscale", "band": 1},
"y": {"scale": "yscale", "field": "amount"},
"y2": {"scale": "yscale", "value": 0}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {
"fill": {"value": "red"}
}
}
},
{
"type": "text",
"encode": {
"enter": {
"align": {"value": "center"},
"baseline": {"value": "bottom"},
"fill": {"value": "#333"}
},
"update": {
"x": {"scale": "xscale", "signal": "tooltip.category", "band": 0.5},
"y": {"scale": "yscale", "signal": "tooltip.amount", "offset": -2},
"text": {"signal": "tooltip.amount"},
"fillOpacity": [
{"test": "datum === tooltip", "value": 0},
{"value": 1}
]
}
}
}
]
}
After some time I have figured this:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 200,
"padding": 20,
"title": {"text":"A title", "anchor":"middle"},
"signals": [
{
"name": "tooltip",
"value": {},
"on": [
{"events": "rect:mouseover", "update": "datum"},
{"events": "rect:mouseout", "update": "{}"}
]
},
{
"name": "Threshold",
"bind":{"input": "range", "min": 0, "max": 100, "step": 1},
"value": 0
}
],
"data": [
{
"name": "table",
"values": [
{"category": "Mon", "amount": 28},
{"category": "Tue", "amount": 55},
{"category": "wed", "amount": 43},
{"category": "Thu", "amount": 91},
{"category": "Fri", "amount": 81},
{"category": "Sat", "amount": 53},
{"category": "Sun", "amount": 19}
]
},
{
"name": "range",
"source": "table",
"transform": [
{"type": "filter", "expr": "datum.amount >= Threshold"}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {"data": "table", "field": "category"},
"range": "width",
"padding": 0.05,
"round": true
},
{
"name": "yscale",
"domain": {"data": "table", "field": "amount"},
"nice": true,
"range": "height"
}
],
"axes": [
{
"orient": "bottom",
"scale": "xscale",
"encode": {
"labels": {
"interactive": true,
"update": {
"tooltip": {"signal": "datum.label"}
}
}
}
},
{ "orient": "left", "scale": "yscale", "title": "Y Title" }
],
"marks": [
{
"type": "rect",
"from": {"data":"range"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "category"},
"width": {"scale": "xscale", "band": 1},
"y": {"scale": "yscale", "field": "amount"},
"y2": {"scale": "yscale", "value": 0}
},
"update": {
"fill": {"value": "steelblue"}
},
"hover": {
"fill": {"value": "red"}
}
}
},
{
"type": "text",
"encode": {
"enter": {
"align": {"value": "center"},
"baseline": {"value": "bottom"},
"fill": {"value": "#333"}
},
"update": {
"x": {"scale": "xscale", "signal": "tooltip.category", "band": 0.5},
"y": {"scale": "yscale", "signal": "tooltip.amount", "offset": -2},
"text": {"signal": "tooltip.amount"},
"fillOpacity": [
{"test": "datum === tooltip", "value": 0},
{"value": 1}
],
"align": {"value": "center"},
"baseline": {"value": "bottom"},
"fill": {"value": "#333"}
}
}
}
]
}