I have several vconcat
plots that all share an x-axis. As I have a helpful label assigned to each selection, I would like the selection to be shared by all plots. That is, if I create a selection on any plot, that selection should appear on all plots. If I remove a selection from any plot, it should be removed from all plots.
At no time should the selections differ.
This is similar to my previous question Synchronized Selections except that now I would like for the selections to be identical across all vconcat
plots. The selection of each plot is tied to the x
encoding; no selection is bound to the plot scales.
For example:
As with the answer to the linked question, I am starting from Overview and Detail example on vega-lite's site, using the v5 schema. The steps:
For every layer, patch the generated Vega to push the s1_x
signal to the outer scope.
Patch the brush visuals to use the appropriate row from the now multi-row s1_store
table.
vlSpec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "https://raw.githubusercontent.com/vega/vega-datasets/main/data/sp500.csv"},
"vconcat": [
{
"params": [
{ "name": "s1",
"select":
{ "type": "interval",
"encodings": ["x"]
}
}
],
"width": 480,
"mark": "area",
"encoding": {
"x": {
"field": "date",
"type": "temporal",
"axis": {"title": ""}
},
"y": {"field": "price", "type": "quantitative"}
}
},
{
"params": [
{ "name": "s1",
"select":
{ "type": "interval",
"encodings": ["x"]
}
}
],
"width": 480,
"height": 60,
"mark": "area",
"encoding": {
"x": {"field": "date", "type": "temporal"},
"y": {
"field": "price",
"type": "quantitative",
"axis": {"tickCount": 3, "grid": false}
}
}
}
]
}
vegaEmbed( '#vis', vlSpec, {"patch": spec => {
spec.signals.push({"name": "s1_x", "value": []});
for (const [idx, group] of spec.marks.entries()) {
let s1_x = group.signals.find(i => i.name == "s1_x")
delete s1_x.value
s1_x.push = "outer"
for (const mark of group.marks) {
if (!mark.name.startsWith("s1_brush")) {
continue
}
console.log("mark: ", mark)
for (const set of Object.values(mark.encode.update)) {
for (const prop of set) {
if (!Object.hasOwn(prop, "test")) {
continue
}
console.log("found one", prop)
prop.test = prop.test.replace("[0].unit ", `[${idx}].unit `)
}
}
}
}
return spec
}}).then(function(result) {
}).catch(console.error);