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

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.

Related

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"}
}
}
}
]
}

Vega Wordcloud Faceting

i really like the look of the vega Word Clouds:
https://vega.github.io/vega/examples/word-cloud/
I'm currently using the spec from the link as follows in colab:
spec = "insert spec here"
#Option one:
from altair import vega
vega.renderers.enable('colab')
vega.Vega(spec)
#Option two:
import panel as pn
from vega import Vega
pn.extension('vega')
pn.pane.Vega(spec)
But actually i want to make faceted wordclouds with vega. I currently load my data as json from my github account which is also slightly annoying, but i found no way to reference python variables in the vega spec.
Does anyone maybe have a hint, how i could layout the vega wordcloud in a grid by groups specified in my data? My json has this structure: [{"text":text,"group":group}], drawing the wordclouds from this works, but not the faceting by the group field. I know vega-lite can do faceting, but it can't draw the beautiful wordcloud it seems.
Thanks for any help!
Here is a working example of Vega spec using facet with your data.
For illustration only, the formula field for angle places words with larger field size in horizontal position.
View in Vega online editor
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A word cloud visualization depicting Vega research paper abstracts.",
"title": "A Wordcloud",
"width": 400,
"height": 400,
"padding": 10,
"background": "ghostwhite",
"layout": {
"bounds": "flush",
"columns": 2,
"padding": 10
},
"data": [
{
"name": "table",
"url": "https://raw.githubusercontent.com/nyanxo/vega_facet_wordcloud/main/split.json",
"transform": [
{
"type": "formula",
"as": "angle",
"expr": "datum.size >= 3 ? 0 : [-45,-30, -15, 0, 15, 30, 45][floor(random() * 7)]"
}
]
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "table", "field": "text_split"},
"range": ["#d5a928", "#652c90", "#939597"]
}
],
"marks": [
{
"type": "group",
"from": {
"facet": {
"name": "facet",
"data": "table",
"groupby": "group"
}
},
"title": {
"text": {"signal": "parent.group"},
"frame": "group"
},
"encode": {
"update": {
"width": {"signal": "width"},
"height": {"signal": "height"}
}
},
"marks": [
{
"type": "rect",
"encode": {
"enter": {
"x": {"value": 0},
"width": {"signal": "width" },
"y": {"value": 0},
"height": {"signal": "height"},
"fill": {"value": "beige"}
}
}
},
{
"type": "text",
"from": {"data": "facet"},
"encode": {
"enter": {
"text": {"field": "text_split"},
"align": {"value": "center"},
"baseline": {"value": "alphabetic"},
"fill": {"scale": "color", "field": "text_split"}
},
"update": {"fillOpacity": {"value": 1}},
"hover": {"fillOpacity": {"value": 0.5}}
},
"transform": [
{
"type": "wordcloud",
"size": {"signal": "[width, height]"},
"text": {"field": "text_split"},
"rotate": {"field": "datum.angle"},
"font": "Helvetica Neue, Arial",
"fontSize": {"field": "datum.size"},
"fontSizeRange": [12, 28],
"padding": 2
}
]
}
]
}
]
}
You can't facet a word cloud as it requires a CountPattern transform which will destroy any faceting field you try to use. Instead you will need to provide a separate data object for each word cloud you want and then concatenate them together.
Edit
Link
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A word cloud visualization depicting Vega research paper abstracts.",
"title": "A Wordcloud",
"width": 420,
"height": 400,
"padding": 0,
"data": [
{
"name": "table",
"url": "https://raw.githubusercontent.com/nyanxo/vega_facet_wordcloud/main/split.json"
}
],
"scales": [
{
"name": "color",
"type": "ordinal",
"domain": {"data": "table", "field": "text_split"},
"range": ["#d5a928", "#652c90", "#939597"]
}
],
"layout": {"padding": 20, "columns": 2, "bounds": "full", "align": "all"},
"marks": [
{
"name": "cell",
"type": "group",
"style": "cell",
"from": {
"facet": {"name": "facet", "data": "table", "groupby": ["group"]}
},
"encode": {
"update": {"width": {"signal": "400"}, "height": {"signal": "400"}}
},
"marks": [
{
"type": "text",
"from": {"data": "facet"},
"encode": {
"enter": {
"text": {"field": "text_split"},
"align": {"value": "center"},
"baseline": {"value": "alphabetic"},
"fill": {"scale": "color", "field": "text_split"}
},
"update": {"fillOpacity": {"value": 1}},
"hover": {"fillOpacity": {"value": 0.5}}
},
"transform": [
{
"type": "wordcloud",
"size": [400, 400],
"text": {"field": "text_split"},
"font": "Helvetica Neue, Arial",
"fontSizeRange": [12, 56],
"padding": 2
}
]
}
]
}
]
}

How to display multiple charts with varying x-scales side by side in Vega

I have a set of charts with the same y-scale but varying x-scales. I am using hconcat to display them side by side. In order to conserve space and avoid repetition, I have disabled the y-axis for all but the first chart. However, this is causing the title of the first chart to offset:
This is a link to a Vega Editor.
As the blue circle indicates, the two titles, "Chain" and "Mini Invaders," are not in line. Is there a way to fix this?
I have tried to express these charts using facet but as far as I can tell, facets do not permit varying x-scales. However, please do let me know if this is somehow possible with facets.
You need labelBound: true in your spec.
Editor
{
"config": {
"view": {
"continuousWidth": 400,
"continuousHeight": 300,
"stroke": "#000000",
"strokeOpacity": 1,
"strokeWidth": 2
},
"axis": {"labelFontSize": 24, "titleFontSize": 24, "labelBound":true},
"legend": {"labelFontSize": 24, "labelLimit": 0, "titleFontSize": 32},
"title": {"baseline": "bottom", "fontSize": 24}
},
"hconcat": [
{
"layer": [
{
"mark": {"type": "area", "clip": true, "opacity": 0.2},
"encoding": {
"color": {
"field": "Variations",
"legend": {
"orient": "top",
"symbolOpacity": 1,
"symbolSize": 200,
"symbolStrokeWidth": 3,
"symbolType": "stroke"
},
"scale": {
"domain": ["Original Algorithm"],
"range": [
"#e41a1c",
"#377eb8",
"#4daf4a",
"#984ea3",
"#a65628",
"#646464"
]
},
"type": "nominal"
},
"x": {"field": "step", "type": "quantitative"},
"y": {
"axis": {"labels": true, "tickCount": 5, "title": null},
"field": "lower",
"type": "quantitative"
},
"y2": {"field": "upper"}
}
},
{
"mark": {"type": "line", "clip": true},
"encoding": {
"color": {"field": "Variations", "type": "nominal"},
"x": {"field": "step", "type": "quantitative"},
"y": {
"field": "regret",
"scale": {"domain": [0, 1]},
"type": "quantitative"
}
}
}
],
"height": 200,
"title": "Chain",
"transform": [{"filter": "(datum.domain === 'Chain')"}],
"width": 200
},
{
"layer": [
{
"mark": {"type": "area", "clip": true, "opacity": 0.2},
"encoding": {
"color": {
"field": "Variations",
"legend": {
"orient": "top",
"symbolOpacity": 1,
"symbolSize": 200,
"symbolStrokeWidth": 3,
"symbolType": "stroke"
},
"scale": {
"domain": ["Original Algorithm"],
"range": [
"#e41a1c",
"#377eb8",
"#4daf4a",
"#984ea3",
"#a65628",
"#646464"
]
},
"type": "nominal"
},
"x": {"field": "step", "type": "quantitative"},
"y": {
"axis": {"labels": false, "tickCount": 5, "title": null},
"field": "lower",
"type": "quantitative"
},
"y2": {"field": "upper"}
}
},
{
"mark": {"type": "line", "clip": true},
"encoding": {
"color": {"field": "Variations", "type": "nominal"},
"x": {"field": "step", "type": "quantitative"},
"y": {
"field": "regret",
"scale": {"domain": [0, 1]},
"type": "quantitative"
}
}
}
],
"height": 200,
"title": "Mini Invaders",
"transform": [{"filter": "(datum.domain === 'Mini Invaders')"}],
"width": 200
}

Vertical Violin Plot in 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

Brushing/linking in vega (not vega-lite)

I'm trying to brush/link two plots in vega, more specifically a node-link diagram and a couple of scatterplots. Based on how dragging works with signals in the node-link diagram I did get quite far, but not far enough...
For the sake of simplicity, I'll provide a little test code here using just two scatterplots:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"padding": 0,
"autosize": "none",
"width": 800,
"height": 400,
"signals": [
{ "description": "Any datapoint is activated",
"name": "datapoint_is_activated", "value": false,
"on": [
{
"events": "symbol:mouseover",
"update": "true"
},
{
"events": "symbol:mouseout",
"update": "false"
}
]
},
{ "description": "Active datapoint",
"name": "activated_datapoint", "value": null,
"on": [
{
"events": "symbol:mouseover",
"update": "item()"
},
{
"events": "symbol:mouseout",
"update": "null"
}
]
}
],
"data": [
{
"name": "table",
"values": [
{"name": "point A", "a": 1, "b": 2, "c": 3},
{"name": "point B", "a": 4, "b": 5, "c": 6},
{"name": "point C", "a": 9, "b": 8, "c": 7}
]
}
],
"scales": [
{ "name": "xscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
},
{ "name": "yscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
}
],
"layout": {"padding": 20},
"marks": [
{ "name": "plot1",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "b", "scale": "yscale"},
"tooltip": {"field": "name"}
},
"update": {
"size": {"value": 100},
"fill": {"value": "grey"}
}
}
}
]
},
{ "name": "plot2",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"on": [
{
"trigger": "datapoint_is_activated",
"modify": "activated_datapoint",
"values": "{fill: \"red\"}"
},
{
"trigger": "!datapoint_is_activated",
"modify": "activated_datapoint",
"values": "{fill: \"grey\"}"
}
],
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "c", "scale": "yscale"},
"size": {"value": 100},
"tooltip": {"field": "name"}
},
"update": {
"fill": {"value": "grey"}
}
}
}
]
}
]
}
The resulting image looks like this:
The idea is that hovering over a datapoint in the left plot will highlight the corresponding datapoint in the right plot. I know this is straightforward in vega-lite, but that does not (yet) support node-link diagrams. Hence: vega.
My approach in the code is to:
create a signal in the outer scope that tracks (a) if there is a point activated, and (b) which point this is
in plot 2 to have a trigger that takes the activated datapoint and changes its colour to 'red'.
I have an inkling feeling that it has to do with my definition of the modify and values part, but I can't figure it out.
Any help very much appreciated!
Thank you,
jan.
After a lot of trial and error, I did find a way to do this. Instead of using a trigger (which I believe would be the canonical way of doing this), I merely use a test in the fill section: datapoint_is_activated && datum === activated_datapoint.datum. See code and image below.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"padding": 0,
"autosize": "none",
"width": 800,
"height": 400,
"signals": [
{ "description": "Any datapoint is activated",
"name": "datapoint_is_activated", "value": false,
"on": [
{
"events": "symbol:mouseover",
"update": "true"
},
{
"events": "symbol:mouseout",
"update": "false"
}
]
},
{ "description": "Active datapoint",
"name": "activated_datapoint", "value": null,
"on": [
{
"events": "symbol:mouseover",
"update": "item()"
},
{
"events": "symbol:mouseout",
"update": "null"
}
]
}
],
"data": [
{
"name": "table",
"values": [
{"name": "point A", "a": 2, "b": 2, "c": 4},
{"name": "point B", "a": 4, "b": 5, "c": 6},
{"name": "point C", "a": 5, "b": 3, "c": 5}
]
}
],
"scales": [
{ "name": "xscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
},
{ "name": "yscale",
"type": "linear",
"domain": [0,10],
"range": [0,200]
}
],
"layout": {"padding": 20},
"marks": [
{ "name": "plot1",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "b", "scale": "yscale"},
"tooltip": {"field": "name"},
"size": {"value": 200}
},
"update": {
"fill": [
{"test": "datapoint_is_activated && datum === activated_datapoint.datum",
"value": "red"},
{"value": "lightgrey"}
]
}
}
}
]
},
{ "name": "plot2",
"type": "group",
"axes": [
{"orient": "bottom", "scale": "xscale"},
{"orient": "right", "scale": "yscale"}
],
"marks": [
{
"type": "symbol",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"field": "a", "scale": "xscale"},
"y": {"field": "c", "scale": "yscale"},
"size": {"value": 200},
"tooltip": {"field": "name"}
},
"update": {
"fill": [
{"test": "datapoint_is_activated && datum === activated_datapoint.datum",
"value": "red"},
{"value": "lightgrey"}
]
}
}
}
]
}
]
}