From 055e32f2ce109c6a663c3950e6ad9f80b321f65b Mon Sep 17 00:00:00 2001 From: Kanit Wongsuphasawat Date: Thu, 18 May 2023 08:52:37 -0700 Subject: [PATCH] fix: support stack bar with reverse order (#8910) Co-authored-by: GitHub Actions Bot --- build/vega-lite-schema.json | 19 +++ examples/compiled/stacked_bar_v_ascending.png | Bin 0 -> 21025 bytes examples/compiled/stacked_bar_v_ascending.svg | 1 + .../compiled/stacked_bar_v_ascending.vg.json | 126 ++++++++++++++++++ .../specs/stacked_bar_v_ascending.vl.json | 11 ++ src/channeldef.ts | 10 +- src/compile/data/stack.ts | 5 +- src/encoding.ts | 11 +- 8 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 examples/compiled/stacked_bar_v_ascending.png create mode 100644 examples/compiled/stacked_bar_v_ascending.svg create mode 100644 examples/compiled/stacked_bar_v_ascending.vg.json create mode 100644 examples/specs/stacked_bar_v_ascending.vl.json diff --git a/build/vega-lite-schema.json b/build/vega-lite-schema.json index 152f30f779..caa0691e63 100644 --- a/build/vega-lite-schema.json +++ b/build/vega-lite-schema.json @@ -4990,6 +4990,9 @@ }, { "$ref": "#/definitions/OrderValueDef" + }, + { + "$ref": "#/definitions/OrderOnlyDef" } ], "description": "Order of the marks.\n- For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n- For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n- Otherwise, this `order` channel encodes layer order of the marks.\n\n__Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping." @@ -9076,6 +9079,9 @@ }, { "$ref": "#/definitions/OrderValueDef" + }, + { + "$ref": "#/definitions/OrderOnlyDef" } ], "description": "Order of the marks.\n- For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n- For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n- Otherwise, this `order` channel encodes layer order of the marks.\n\n__Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping." @@ -17972,6 +17978,16 @@ }, "type": "object" }, + "OrderOnlyDef": { + "additionalProperties": false, + "properties": { + "sort": { + "$ref": "#/definitions/SortOrder", + "description": "The sort order. One of `\"ascending\"` (default) or `\"descending\"`." + } + }, + "type": "object" + }, "OrderValueDef": { "additionalProperties": false, "properties": { @@ -24211,6 +24227,9 @@ }, { "$ref": "#/definitions/OrderValueDef" + }, + { + "$ref": "#/definitions/OrderOnlyDef" } ], "description": "Order of the marks.\n- For stacked marks, this `order` channel encodes [stack order](https://vega.github.io/vega-lite/docs/stack.html#order).\n- For line and trail marks, this `order` channel encodes order of data points in the lines. This can be useful for creating [a connected scatterplot](https://vega.github.io/vega-lite/examples/connected_scatterplot.html). Setting `order` to `{\"value\": null}` makes the line marks use the original order in the data sources.\n- Otherwise, this `order` channel encodes layer order of the marks.\n\n__Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping." diff --git a/examples/compiled/stacked_bar_v_ascending.png b/examples/compiled/stacked_bar_v_ascending.png new file mode 100644 index 0000000000000000000000000000000000000000..21306279166f6ca6c2ae046bafa43e1f5c44cd73 GIT binary patch literal 21025 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 z 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%0A=Q*%SkqF6%Vvjjb1NC|gjM`)P?}WZSfCd#{ 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 literal 0 HcmV?d00001 diff --git a/examples/compiled/stacked_bar_v_ascending.svg b/examples/compiled/stacked_bar_v_ascending.svg new file mode 100644 index 0000000000..3ac74c02a1 --- /dev/null +++ b/examples/compiled/stacked_bar_v_ascending.svg @@ -0,0 +1 @@ +GlabronManchuriaNo. 457No. 462No. 475PeatlandSvansotaTrebiVelvetWisconsin No. 38variety0100200300400500Sum of yieldCrookstonDuluthGrand RapidsMorrisUniversity FarmWasecasite \ No newline at end of file diff --git a/examples/compiled/stacked_bar_v_ascending.vg.json b/examples/compiled/stacked_bar_v_ascending.vg.json new file mode 100644 index 0000000000..9581042ae0 --- /dev/null +++ b/examples/compiled/stacked_bar_v_ascending.vg.json @@ -0,0 +1,126 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "background": "white", + "padding": 5, + "height": 200, + "style": "cell", + "data": [ + { + "name": "source_0", + "url": "data/barley.json", + "format": {"type": "json"}, + "transform": [ + { + "type": "aggregate", + "groupby": ["variety", "site"], + "ops": ["sum"], + "fields": ["yield"], + "as": ["sum_yield"] + }, + { + "type": "stack", + "groupby": ["variety"], + "field": "sum_yield", + "sort": {"field": ["site"], "order": ["ascending"]}, + "as": ["sum_yield_start", "sum_yield_end"], + "offset": "zero" + }, + { + "type": "filter", + "expr": "isValid(datum[\"sum_yield\"]) && isFinite(+datum[\"sum_yield\"])" + } + ] + } + ], + "signals": [ + {"name": "x_step", "value": 20}, + { + "name": "width", + "update": "bandspace(domain('x').length, 0.1, 0.05) * x_step" + } + ], + "marks": [ + { + "name": "marks", + "type": "rect", + "style": ["bar"], + "from": {"data": "source_0"}, + "encode": { + "update": { + "fill": {"scale": "color", "field": "site"}, + "ariaRoleDescription": {"value": "bar"}, + "description": { + "signal": "\"variety: \" + (isValid(datum[\"variety\"]) ? datum[\"variety\"] : \"\"+datum[\"variety\"]) + \"; Sum of yield: \" + (format(datum[\"sum_yield\"], \"\")) + \"; site: \" + (isValid(datum[\"site\"]) ? datum[\"site\"] : \"\"+datum[\"site\"])" + }, + "x": {"scale": "x", "field": "variety"}, + "width": {"signal": "max(0.25, bandwidth('x'))"}, + "y": {"scale": "y", "field": "sum_yield_end"}, + "y2": {"scale": "y", "field": "sum_yield_start"} + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "band", + "domain": {"data": "source_0", "field": "variety", "sort": true}, + "range": {"step": {"signal": "x_step"}}, + "paddingInner": 0.1, + "paddingOuter": 0.05 + }, + { + "name": "y", + "type": "linear", + "domain": { + "data": "source_0", + "fields": ["sum_yield_start", "sum_yield_end"] + }, + "range": [{"signal": "height"}, 0], + "nice": true, + "zero": true + }, + { + "name": "color", + "type": "ordinal", + "domain": {"data": "source_0", "field": "site", "sort": true}, + "range": "category" + } + ], + "axes": [ + { + "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": "variety", + "labelAlign": "right", + "labelAngle": 270, + "labelBaseline": "middle", + "zindex": 0 + }, + { + "scale": "y", + "orient": "left", + "grid": false, + "title": "Sum of yield", + "labelOverlap": true, + "tickCount": {"signal": "ceil(height/40)"}, + "zindex": 0 + } + ], + "legends": [{"fill": "color", "symbolType": "square", "title": "site"}] +} diff --git a/examples/specs/stacked_bar_v_ascending.vl.json b/examples/specs/stacked_bar_v_ascending.vl.json new file mode 100644 index 0000000000..257cc0f41c --- /dev/null +++ b/examples/specs/stacked_bar_v_ascending.vl.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "data": {"url": "data/barley.json"}, + "mark": "bar", + "encoding": { + "x": {"field": "variety"}, + "y": {"aggregate": "sum", "field": "yield"}, + "color": {"field": "site"}, + "order": {"sort": "ascending"} + } +} diff --git a/src/channeldef.ts b/src/channeldef.ts index 7354aef166..31f6a5dd57 100644 --- a/src/channeldef.ts +++ b/src/channeldef.ts @@ -633,13 +633,21 @@ export interface LegendMixins { // Order Path have no scale -export interface OrderFieldDef extends FieldDefWithoutScale { +export type OrderFieldDef = FieldDefWithoutScale & OrderOnlyDef; + +export interface OrderOnlyDef { /** * The sort order. One of `"ascending"` (default) or `"descending"`. */ sort?: SortOrder; } +export function isOrderOnlyDef( + orderDef: OrderFieldDef | OrderFieldDef[] | OrderValueDef | OrderOnlyDef +): orderDef is OrderOnlyDef { + return orderDef && !!(orderDef as OrderOnlyDef).sort && !orderDef['field']; +} + export type OrderValueDef = ConditionValueDefMixins & NumericValueDef; export interface StringFieldDef extends FieldDefWithoutScale, FormatMixins {} diff --git a/src/compile/data/stack.ts b/src/compile/data/stack.ts index 2ebc1a121c..184f85957e 100644 --- a/src/compile/data/stack.ts +++ b/src/compile/data/stack.ts @@ -1,6 +1,6 @@ import {Transforms as VgTransform} from 'vega'; import {isArray, isString} from 'vega-util'; -import {FieldDef, FieldName, getFieldDef, isFieldDef, vgField} from '../../channeldef'; +import {FieldDef, FieldName, getFieldDef, isFieldDef, isOrderOnlyDef, vgField} from '../../channeldef'; import {SortFields, SortOrder} from '../../sort'; import {StackOffset} from '../../stack'; import {StackTransform} from '../../transform'; @@ -141,12 +141,13 @@ export class StackNode extends DataFlowNode { if (isArray(orderDef) || isFieldDef(orderDef)) { sort = sortParams(orderDef); } else { + const sortOrder = isOrderOnlyDef(orderDef) ? orderDef.sort : fieldChannel === 'y' ? 'descending' : 'ascending'; // default = descending by stackFields // FIXME is the default here correct for binned fields? sort = stackby.reduce( (s, field) => { s.field.push(field); - s.order.push(fieldChannel === 'y' ? 'descending' : 'ascending'); + s.order.push(sortOrder); return s; }, {field: [], order: []} diff --git a/src/encoding.ts b/src/encoding.ts index 0fcf739731..bc6534c07b 100644 --- a/src/encoding.ts +++ b/src/encoding.ts @@ -64,6 +64,7 @@ import { isConditionalDef, isDatumDef, isFieldDef, + isOrderOnlyDef, isTypedFieldDef, isValueDef, LatLongDef, @@ -71,6 +72,7 @@ import { NumericMarkPropDef, OffsetDef, OrderFieldDef, + OrderOnlyDef, OrderValueDef, PolarDef, Position2Def, @@ -321,7 +323,7 @@ export interface Encoding { * * __Note__: In aggregate plots, `order` field should be `aggregate`d to avoid creating additional aggregation grouping. */ - order?: OrderFieldDef | OrderFieldDef[] | OrderValueDef; + order?: OrderFieldDef | OrderFieldDef[] | OrderValueDef | OrderOnlyDef; } export interface EncodingWithFacet extends Encoding, EncodingFacetMapping {} @@ -594,6 +596,13 @@ export function initEncoding( (channel === TOOLTIP && isArray(channelDef)) ) { if (channelDef) { + if (channel === ORDER) { + const def = encoding[channel]; + if (isOrderOnlyDef(def)) { + normalizedEncoding[channel] = def; + continue; + } + } // Array of fieldDefs for detail channel (or production rule) (normalizedEncoding[channel] as any) = array(channelDef).reduce( (defs: FieldDef[], fieldDef: FieldDef) => {