-
Notifications
You must be signed in to change notification settings - Fork 630
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Interactive Legend * Correct tests * Enable interactive legends for multi-field selection * Support single type selections * Add tests for interactive legends * Simplify flagging a legend to be interactive if selection present. * Simplify signal assembly for interactive legends. * Simplify conditional encoding for legend items. * Scope legend events to "view" as signals may be nested within subscopes. * Move opacity of unselected legend entries to config. * Use more relaxed predicate to correctly select legend items. This is necessary when a selection is projected over several fields. Using vlSelectionTest will cause all legend items to appear unselected, even if one of the values is within in the selection. Instead, we now test only for the legend item itself, via the top-level resolved signal. * Encapsulate interactive legends in a selection transform. Augmenting existing signal logic with legend events yields buggy behavior when toggling values from the store based on unit name. It is also less efficient in multi-view cases, as each individual view would modify the store based on legend events. Instead, the legend selection transform adds a top-level signal to coordinate all legends for a given selection. Moreover, it allows users to selectively disable interactive legend processing (i.e., "legends": false in a selection definition). * Input widgets should reflect selection status from interactive legends. * Update existing compile-time unit tests. * Snapshot. * Fix build. * Simplify interactive legends by treating it as an alternate binding. * Add interactive legend example. * Update unit tests. * Fix bug with legend symbol opacity. * Add docs for interactive legends. * refactor: simplify logic * chore: update schema * docs: add missing docs for unselectedOpacity * chore: build stuff * chore: rebuild toc * fix: don't output unselectedOpacity in config * refactor: don't interpret numbers as truth values * chore: update examples [CI] * Only name and flag parts as interactive if selections exist on component * React to legend entries (whitespace between symbol, label). * Warn + skip if projecting over an aggregate field (or no field). * chore: update examples [CI] * chore: rebuild runtime examples * fix: resolve issue with symbol and color legend by using deep equal * fix: store selection names (not components) on legend component * refactor: use null coalescing Co-Authored-By: Dominik Moritz <[email protected]>
- Loading branch information
Showing
44 changed files
with
1,412 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,259 @@ | ||
{ | ||
"$schema": "https://vega.github.io/schema/vega/v5.json", | ||
"background": "white", | ||
"padding": 5, | ||
"width": 300, | ||
"height": 200, | ||
"style": "cell", | ||
"data": [ | ||
{"name": "industry_store"}, | ||
{ | ||
"name": "source_0", | ||
"url": "data/unemployment-across-industries.json", | ||
"format": {"type": "json", "parse": {"date": "date"}}, | ||
"transform": [ | ||
{ | ||
"type": "formula", | ||
"as": "yearmonth_date", | ||
"expr": "datetime(year(datum[\"date\"]), month(datum[\"date\"]), 1, 0, 0, 0, 0)" | ||
}, | ||
{ | ||
"type": "aggregate", | ||
"groupby": ["yearmonth_date", "series"], | ||
"ops": ["sum"], | ||
"fields": ["count"], | ||
"as": ["sum_count"] | ||
}, | ||
{ | ||
"type": "impute", | ||
"field": "sum_count", | ||
"groupby": ["series"], | ||
"key": "yearmonth_date", | ||
"method": "value", | ||
"value": 0 | ||
}, | ||
{ | ||
"type": "stack", | ||
"groupby": ["yearmonth_date"], | ||
"field": "sum_count", | ||
"sort": {"field": ["series"], "order": ["descending"]}, | ||
"as": ["sum_count_start", "sum_count_end"], | ||
"offset": "center" | ||
} | ||
] | ||
} | ||
], | ||
"signals": [ | ||
{ | ||
"name": "unit", | ||
"value": {}, | ||
"on": [ | ||
{"events": "mousemove", "update": "isTuple(group()) ? group() : unit"} | ||
] | ||
}, | ||
{ | ||
"name": "industry_series_legend", | ||
"value": null, | ||
"on": [ | ||
{ | ||
"events": [ | ||
{ | ||
"source": "view", | ||
"type": "click", | ||
"markname": "series_legend_symbols" | ||
}, | ||
{ | ||
"source": "view", | ||
"type": "click", | ||
"markname": "series_legend_labels" | ||
}, | ||
{ | ||
"source": "view", | ||
"type": "click", | ||
"markname": "series_legend_entries" | ||
} | ||
], | ||
"update": "datum.value || item().items[0].items[0].datum.value", | ||
"force": true | ||
}, | ||
{ | ||
"events": [{"source": "view", "type": "click"}], | ||
"update": "!event.item || !datum ? null : industry_series_legend", | ||
"force": true | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "industry", | ||
"update": "vlSelectionResolve(\"industry_store\", \"union\", true)" | ||
}, | ||
{ | ||
"name": "industry_tuple", | ||
"update": "industry_series_legend !== null ? {fields: industry_tuple_fields, values: [industry_series_legend]} : null" | ||
}, | ||
{ | ||
"name": "industry_tuple_fields", | ||
"value": [{"type": "E", "field": "series"}] | ||
}, | ||
{ | ||
"name": "industry_toggle", | ||
"value": false, | ||
"on": [ | ||
{ | ||
"events": {"merge": [{"source": "view", "type": "click"}]}, | ||
"update": "event.shiftKey" | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "industry_modify", | ||
"update": "modify(\"industry_store\", industry_toggle ? null : industry_tuple, industry_toggle ? null : true, industry_toggle ? industry_tuple : null)" | ||
} | ||
], | ||
"marks": [ | ||
{ | ||
"name": "pathgroup", | ||
"type": "group", | ||
"from": { | ||
"facet": { | ||
"name": "faceted_path_main", | ||
"data": "source_0", | ||
"groupby": ["series"] | ||
} | ||
}, | ||
"encode": { | ||
"update": { | ||
"width": {"field": {"group": "width"}}, | ||
"height": {"field": {"group": "height"}} | ||
} | ||
}, | ||
"marks": [ | ||
{ | ||
"name": "marks", | ||
"type": "area", | ||
"style": ["area"], | ||
"sort": {"field": "datum[\"yearmonth_date\"]"}, | ||
"interactive": true, | ||
"from": {"data": "faceted_path_main"}, | ||
"encode": { | ||
"update": { | ||
"orient": {"value": "vertical"}, | ||
"fill": {"scale": "color", "field": "series"}, | ||
"opacity": [ | ||
{ | ||
"test": "!(length(data(\"industry_store\"))) || (vlSelectionTest(\"industry_store\", datum))", | ||
"value": 1 | ||
}, | ||
{"value": 0.2} | ||
], | ||
"x": {"scale": "x", "field": "yearmonth_date"}, | ||
"y": {"scale": "y", "field": "sum_count_end"}, | ||
"y2": {"scale": "y", "field": "sum_count_start"}, | ||
"defined": { | ||
"signal": "isValid(datum[\"yearmonth_date\"]) && isFinite(+datum[\"yearmonth_date\"]) && isValid(datum[\"sum_count\"]) && isFinite(+datum[\"sum_count\"])" | ||
} | ||
} | ||
} | ||
} | ||
] | ||
} | ||
], | ||
"scales": [ | ||
{ | ||
"name": "x", | ||
"type": "time", | ||
"domain": {"data": "source_0", "field": "yearmonth_date"}, | ||
"range": [0, {"signal": "width"}] | ||
}, | ||
{ | ||
"name": "y", | ||
"type": "linear", | ||
"domain": { | ||
"data": "source_0", | ||
"fields": ["sum_count_start", "sum_count_end"] | ||
}, | ||
"range": [{"signal": "height"}, 0], | ||
"nice": true, | ||
"zero": true | ||
}, | ||
{ | ||
"name": "color", | ||
"type": "ordinal", | ||
"domain": {"data": "source_0", "field": "series", "sort": true}, | ||
"range": {"scheme": "category20b"} | ||
} | ||
], | ||
"axes": [ | ||
{ | ||
"scale": "x", | ||
"orient": "bottom", | ||
"gridScale": "y", | ||
"grid": true, | ||
"tickCount": {"signal": "ceil(width/40)"}, | ||
"domain": false, | ||
"labels": false, | ||
"maxExtent": 0, | ||
"minExtent": 0, | ||
"ticks": false, | ||
"zindex": 0 | ||
}, | ||
{ | ||
"scale": "x", | ||
"orient": "bottom", | ||
"grid": false, | ||
"title": "date (year-month)", | ||
"domain": false, | ||
"tickSize": 0, | ||
"labelFlush": true, | ||
"labelOverlap": true, | ||
"tickCount": {"signal": "ceil(width/40)"}, | ||
"encode": { | ||
"labels": { | ||
"update": {"text": {"signal": "timeFormat(datum.value, '%Y')"}} | ||
} | ||
}, | ||
"zindex": 0 | ||
} | ||
], | ||
"legends": [ | ||
{ | ||
"fill": "color", | ||
"gradientLength": {"signal": "clamp(height, 64, 200)"}, | ||
"symbolType": "circle", | ||
"title": "series", | ||
"encode": { | ||
"labels": { | ||
"name": "series_legend_labels", | ||
"interactive": true, | ||
"update": { | ||
"opacity": [ | ||
{ | ||
"test": "(!length(data(\"industry_store\")) || (industry[\"series\"] && indexof(industry[\"series\"], datum.value) >= 0))", | ||
"value": 1 | ||
}, | ||
{"value": 0.35} | ||
] | ||
} | ||
}, | ||
"symbols": { | ||
"name": "series_legend_symbols", | ||
"interactive": true, | ||
"update": { | ||
"opacity": [ | ||
{ | ||
"test": "(!length(data(\"industry_store\")) || (industry[\"series\"] && indexof(industry[\"series\"], datum.value) >= 0))", | ||
"value": 1 | ||
}, | ||
{"value": 0.35} | ||
] | ||
} | ||
}, | ||
"entries": { | ||
"name": "series_legend_entries", | ||
"interactive": true, | ||
"update": {"fill": {"value": "transparent"}} | ||
} | ||
} | ||
} | ||
] | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.