Skip to content

Commit

Permalink
feat: Expose react option for params (#9374)
Browse files Browse the repository at this point in the history
## PR Description

Currently the Vega-Lite schema does not officially support the use of
the option `react` to params. It still works to use it in the online
editor, but it raises an error when validating the spec in Altair. We
want to use it to create a constant color domain like in [this
example](https://vega.github.io/editor/#/url/vega-lite/N4Igxg9gdgZglgcxALlANzgUwO4tJKAFzigFcJSBnAdTgBNCALFAZgAY2AacaYsiygAlMiRoVYcAvpO50AhoTl4QpAE4AbFCDGEADpWQB6Q2DpQAdACtKdTOrhpV5qJkKGougLaG0mBHIBaeUVKV0oAATQARnMAJgBOczZDYLkTOVVKK0poEBkQXQy5T0oUAG1QKGLMLULVYoB9FhBuUPVMMHFUEEIAT10a5AKIEnFuTChIOhIEUuQynnUIVRAAXXyAIxI6LXaECZ2ZSuraos8AFhaQTAAPXRWhughPORIACgBySCXVD4BKPKcY6eQaLZYNJ4vEhXVSYOSdFAwOTqULjO4PApnS6SVbcQj1KCUGDLTzlUDwdSETAPUB1YqneqeJp5HHcF6qADWyj6A1qIyIVwp7R2yHxpEw+QmUxmym+y2U8DsIpAAHlVIhoXj+qCoM8SMirpQwMjBqBIa8oMpbvctHLVBDnhaWfkbgqsOplYJlqFdBBsNSrjzQQBHUhyIhwRTEXyAkC9N1KrQAWTg7UoDQG9oA4silpatbyhqHw8Qow4atJuAASI2MTAvLQ6fRGHx+OTmBCRxikDbmOAQQy1+tpXz+AL2Kk+ACs5iiAHYktlcpIgA)
originally from
vega/altair#3394 (comment). Adding
this functionality would allow us to have a constant color domain even
when filtering which is very useful (and could even be a good default
option for using the legend to filter colors). Without setting a
constant domain, it is not possible to click additional categories since
they disappear from the legend as described in
#9360

close #9360

## Checklist

- [x] This PR is atomic (i.e., it fixes one issue at a time).
- [x] The title is a concise [semantic commit
message](https://www.conventionalcommits.org/) (e.g. "fix: correctly
handle undefined properties").
- [x] `yarn test` runs successfully
- For new features:
  - [ ] Has unit tests.
  - [ ] Has documentation under `site/docs/` + examples.

---------

Co-authored-by: GitHub Actions Bot <[email protected]>
  • Loading branch information
joelostblom and GitHub Actions Bot authored Jul 28, 2024
1 parent 8cf7a63 commit 93d92ef
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 0 deletions.
4 changes: 4 additions & 0 deletions build/vega-lite-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -31631,6 +31631,10 @@
"$ref": "#/definitions/ParameterName",
"description": "A unique name for the variable parameter. Parameter names should be valid JavaScript identifiers: they should contain only alphanumeric characters (or \"$\", or \"_\") and may not start with a digit. Reserved keywords that may not be used as parameter names are \"datum\", \"event\", \"item\", and \"parent\"."
},
"react": {
"description": "A boolean flag (default `true`) indicating if the update expression should be automatically re-evaluated when any upstream signal dependencies update. If `false`, the update expression will not register any dependencies on other signals, even for initialization.\n\n __Default value:__ `true`",
"type": "boolean"
},
"value": {
"description": "The [initial value](http://vega.github.io/vega-lite/docs/value.html) of the parameter.\n\n__Default value:__ `undefined`"
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/compiled/point_constant_legend_domain.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
234 changes: 234 additions & 0 deletions examples/compiled/point_constant_legend_domain.vg.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": "white",
"padding": 5,
"width": 200,
"height": 200,
"style": "cell",
"data": [
{"name": "color_selection_store"},
{
"name": "source_0",
"url": "https://cdn.jsdelivr.net/npm/[email protected]/data/cars.json",
"format": {"type": "json"},
"transform": [
{
"type": "filter",
"expr": "!length(data(\"color_selection_store\")) || vlSelectionTest(\"color_selection_store\", datum)"
},
{
"type": "filter",
"expr": "isValid(datum[\"Horsepower\"]) && isFinite(+datum[\"Horsepower\"]) && isValid(datum[\"Miles_per_Gallon\"]) && isFinite(+datum[\"Miles_per_Gallon\"])"
}
]
}
],
"signals": [
{
"name": "unit",
"value": {},
"on": [
{"events": "pointermove", "update": "isTuple(group()) ? group() : unit"}
]
},
{
"name": "color_selection_Origin_legend",
"value": null,
"on": [
{
"events": [
{
"source": "view",
"type": "click",
"markname": "Origin_legend_symbols"
},
{
"source": "view",
"type": "click",
"markname": "Origin_legend_labels"
},
{
"source": "view",
"type": "click",
"markname": "Origin_legend_entries"
}
],
"update": "isDefined(datum.value) ? datum.value : item().items[0].items[0].datum.value",
"force": true
},
{
"events": [{"source": "view", "type": "click"}],
"update": "!event.item || !datum ? null : color_selection_Origin_legend",
"force": true
}
]
},
{
"name": "color_selection",
"update": "vlSelectionResolve(\"color_selection_store\", \"union\", true, true)"
},
{"name": "computed_domain", "update": "domain('color')"},
{"name": "color_domain", "react": false, "update": "computed_domain"},
{
"name": "color_selection_tuple",
"update": "color_selection_Origin_legend !== null ? {fields: color_selection_tuple_fields, values: [color_selection_Origin_legend]} : null"
},
{
"name": "color_selection_tuple_fields",
"value": [{"field": "Origin", "channel": "color", "type": "E"}]
},
{
"name": "color_selection_toggle",
"value": false,
"on": [
{
"events": {"merge": [{"source": "view", "type": "click"}]},
"update": "event.shiftKey"
}
]
},
{
"name": "color_selection_modify",
"on": [
{
"events": {"signal": "color_selection_tuple"},
"update": "modify(\"color_selection_store\", color_selection_toggle ? null : color_selection_tuple, color_selection_toggle ? null : true, color_selection_toggle ? color_selection_tuple : null)"
}
]
}
],
"marks": [
{
"name": "marks",
"type": "symbol",
"style": ["point"],
"interactive": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"opacity": {"value": 0.7},
"fill": {"scale": "color", "field": "Origin"},
"ariaRoleDescription": {"value": "point"},
"description": {
"signal": "\"Horsepower: \" + (format(datum[\"Horsepower\"], \"\")) + \"; Miles_per_Gallon: \" + (format(datum[\"Miles_per_Gallon\"], \"\")) + \"; Origin: \" + (isValid(datum[\"Origin\"]) ? datum[\"Origin\"] : \"\"+datum[\"Origin\"])"
},
"x": {"scale": "x", "field": "Horsepower"},
"y": {"scale": "y", "field": "Miles_per_Gallon"}
}
}
}
],
"scales": [
{
"name": "x",
"type": "linear",
"domain": {"data": "source_0", "field": "Horsepower"},
"range": [0, {"signal": "width"}],
"nice": true,
"zero": true
},
{
"name": "y",
"type": "linear",
"domain": {"data": "source_0", "field": "Miles_per_Gallon"},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
},
{
"name": "color",
"type": "ordinal",
"domain": {"signal": "color_domain"},
"range": "category"
}
],
"axes": [
{
"scale": "x",
"orient": "bottom",
"gridScale": "y",
"grid": true,
"tickCount": {"signal": "ceil(width/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"gridScale": "x",
"grid": true,
"tickCount": {"signal": "ceil(height/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 0
},
{
"scale": "x",
"orient": "bottom",
"grid": false,
"title": "Horsepower",
"labelFlush": true,
"labelOverlap": true,
"tickCount": {"signal": "ceil(width/40)"},
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"grid": false,
"title": "Miles_per_Gallon",
"labelOverlap": true,
"tickCount": {"signal": "ceil(height/40)"},
"zindex": 0
}
],
"legends": [
{
"fill": "color",
"symbolType": "circle",
"title": "Origin",
"encode": {
"labels": {
"name": "Origin_legend_labels",
"interactive": true,
"update": {
"opacity": [
{
"test": "(!length(data(\"color_selection_store\")) || (color_selection[\"Origin\"] && indexof(color_selection[\"Origin\"], datum.value) >= 0))",
"value": 1
},
{"value": 0.35}
]
}
},
"symbols": {
"name": "Origin_legend_symbols",
"interactive": true,
"update": {
"opacity": [
{
"test": "(!length(data(\"color_selection_store\")) || (color_selection[\"Origin\"] && indexof(color_selection[\"Origin\"], datum.value) >= 0))",
"value": 0.7
},
{"value": 0.35}
]
}
},
"entries": {
"name": "Origin_legend_entries",
"interactive": true,
"update": {"fill": {"value": "transparent"}}
}
}
}
]
}
26 changes: 26 additions & 0 deletions examples/specs/point_constant_legend_domain.vl.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {
"url": "https://cdn.jsdelivr.net/npm/[email protected]/data/cars.json"
},
"params": [
{
"name": "color_selection",
"select": {"type": "point", "encodings": ["color"]},
"bind": "legend"
},
{"name": "computed_domain", "expr": "domain('color')"},
{"name": "color_domain", "react": false, "expr": "computed_domain"}
],
"transform": [{"filter": {"param": "color_selection"}}],
"mark": {"type": "point", "filled": true},
"encoding": {
"color": {
"field": "Origin",
"type": "nominal",
"scale": {"domain": {"expr": "color_domain"}}
},
"x": {"field": "Horsepower", "type": "quantitative"},
"y": {"field": "Miles_per_Gallon", "type": "quantitative"}
}
}
7 changes: 7 additions & 0 deletions src/parameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export interface VariableParameter {
* Binds the parameter to an external input element such as a slider, selection list or radio button group.
*/
bind?: Binding;

/**
*A boolean flag (default `true`) indicating if the update expression should be automatically re-evaluated when any upstream signal dependencies update. If `false`, the update expression will not register any dependencies on other signals, even for initialization.
*
* __Default value:__ `true`
*/
react?: boolean;
}

export function assembleParameterSignals(params: (VariableParameter | TopLevelSelectionParameter)[]) {
Expand Down

0 comments on commit 93d92ef

Please sign in to comment.