Reputation: 91
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:
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.
Upvotes: 3
Views: 283
Reputation: 91
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"}
]
}
}
}
]
}
]
}
Upvotes: 2