diff --git a/examples/compiled/arc_ordinal_theta.vg.json b/examples/compiled/arc_ordinal_theta.vg.json
index eda82aec99..b1e44cd834 100644
--- a/examples/compiled/arc_ordinal_theta.vg.json
+++ b/examples/compiled/arc_ordinal_theta.vg.json
@@ -23,6 +23,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["dir"],
+ "field": "strength",
+ "sort": {"field": [], "order": []},
+ "as": ["strength_start", "strength_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"strength\"]) && isFinite(+datum[\"strength\"])"
@@ -44,8 +52,8 @@
},
"x": {"signal": "width", "mult": 0.5},
"y": {"signal": "height", "mult": 0.5},
- "outerRadius": {"scale": "radius", "field": "strength"},
- "innerRadius": {"scale": "radius", "value": 0},
+ "outerRadius": {"scale": "radius", "field": "strength_end"},
+ "innerRadius": {"scale": "radius", "field": "strength_start"},
"startAngle": {"scale": "theta", "field": "dir"},
"endAngle": {
"scale": "theta",
@@ -66,7 +74,10 @@
{
"name": "radius",
"type": "linear",
- "domain": {"data": "data_0", "field": "strength"},
+ "domain": {
+ "data": "data_0",
+ "fields": ["strength_start", "strength_end"]
+ },
"range": [0, {"signal": "min(width,height)/2"}],
"zero": true
},
diff --git a/examples/compiled/area_gradient.vg.json b/examples/compiled/area_gradient.vg.json
index 6c9e22dc1d..ad480764d8 100644
--- a/examples/compiled/area_gradient.vg.json
+++ b/examples/compiled/area_gradient.vg.json
@@ -11,7 +11,25 @@
"name": "source_0",
"url": "data/stocks.csv",
"format": {"type": "csv", "parse": {"date": "date"}},
- "transform": [{"type": "filter", "expr": "datum.symbol==='GOOG'"}]
+ "transform": [
+ {"type": "filter", "expr": "datum.symbol==='GOOG'"},
+ {
+ "type": "impute",
+ "field": "price",
+ "groupby": [],
+ "key": "date",
+ "method": "value",
+ "value": 0
+ },
+ {
+ "type": "stack",
+ "groupby": ["date"],
+ "field": "price",
+ "sort": {"field": [], "order": []},
+ "as": ["price_start", "price_end"],
+ "offset": "zero"
+ }
+ ]
}
],
"marks": [
@@ -42,8 +60,8 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "x", "field": "date"},
- "y": {"scale": "y", "field": "price"},
- "y2": {"scale": "y", "value": 0},
+ "y": {"scale": "y", "field": "price_end"},
+ "y2": {"scale": "y", "field": "price_start"},
"defined": {
"signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
}
@@ -63,7 +81,7 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "x", "field": "date"},
- "y": {"scale": "y", "field": "price"},
+ "y": {"scale": "y", "field": "price_end"},
"defined": {
"signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
}
@@ -81,7 +99,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "source_0", "field": "price"},
+ "domain": {"data": "source_0", "fields": ["price_start", "price_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/area_overlay.vg.json b/examples/compiled/area_overlay.vg.json
index 77f5607300..aec203dc4b 100644
--- a/examples/compiled/area_overlay.vg.json
+++ b/examples/compiled/area_overlay.vg.json
@@ -17,6 +17,36 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "impute",
+ "field": "price",
+ "groupby": [],
+ "key": "date",
+ "method": "value",
+ "value": 0
+ },
+ {
+ "type": "stack",
+ "groupby": ["date"],
+ "field": "price",
+ "sort": {"field": [], "order": []},
+ "as": ["price_start", "price_end"],
+ "offset": "zero"
+ }
+ ]
+ },
+ {
+ "name": "data_1",
+ "source": "source_0",
+ "transform": [
+ {
+ "type": "stack",
+ "groupby": ["date"],
+ "field": "price",
+ "sort": {"field": [], "order": []},
+ "as": ["price_start", "price_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "(isDate(datum[\"date\"]) || (isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]))) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
@@ -30,7 +60,7 @@
"type": "area",
"style": ["area"],
"sort": {"field": "datum[\"date\"]"},
- "from": {"data": "source_0"},
+ "from": {"data": "data_0"},
"encode": {
"update": {
"opacity": {"value": 0.7},
@@ -40,8 +70,8 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "x", "field": "date"},
- "y": {"scale": "y", "field": "price"},
- "y2": {"scale": "y", "value": 0},
+ "y": {"scale": "y", "field": "price_end"},
+ "y2": {"scale": "y", "field": "price_start"},
"defined": {
"signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
}
@@ -53,7 +83,7 @@
"type": "line",
"style": ["line"],
"sort": {"field": "datum[\"date\"]"},
- "from": {"data": "source_0"},
+ "from": {"data": "data_0"},
"encode": {
"update": {
"stroke": {"value": "#4c78a8"},
@@ -61,7 +91,7 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "x", "field": "date"},
- "y": {"scale": "y", "field": "price"},
+ "y": {"scale": "y", "field": "price_end"},
"defined": {
"signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
}
@@ -72,7 +102,7 @@
"name": "layer_2_marks",
"type": "symbol",
"style": ["point"],
- "from": {"data": "data_0"},
+ "from": {"data": "data_1"},
"encode": {
"update": {
"opacity": {"value": 1},
@@ -82,7 +112,7 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "x", "field": "date"},
- "y": {"scale": "y", "field": "price"}
+ "y": {"scale": "y", "field": "price_end"}
}
}
}
@@ -93,8 +123,8 @@
"type": "time",
"domain": {
"fields": [
- {"data": "source_0", "field": "date"},
- {"data": "data_0", "field": "date"}
+ {"data": "data_0", "field": "date"},
+ {"data": "data_1", "field": "date"}
]
},
"range": [0, {"signal": "width"}]
@@ -104,8 +134,10 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "source_0", "field": "price"},
- {"data": "data_0", "field": "price"}
+ {"data": "data_0", "field": "price_start"},
+ {"data": "data_0", "field": "price_end"},
+ {"data": "data_1", "field": "price_start"},
+ {"data": "data_1", "field": "price_end"}
]
},
"range": [{"signal": "height"}, 0],
diff --git a/examples/compiled/bar.vg.json b/examples/compiled/bar.vg.json
index 2840f2d51e..cf7d1e2bbc 100644
--- a/examples/compiled/bar.vg.json
+++ b/examples/compiled/bar.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -53,8 +61,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -71,7 +79,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_aggregate_transform.vg.json b/examples/compiled/bar_aggregate_transform.vg.json
index 22f7da095b..47ed9786bf 100644
--- a/examples/compiled/bar_aggregate_transform.vg.json
+++ b/examples/compiled/bar_aggregate_transform.vg.json
@@ -17,6 +17,14 @@
"fields": ["Acceleration"],
"as": ["mean_acc"]
},
+ {
+ "type": "stack",
+ "groupby": ["Cylinders"],
+ "field": "mean_acc",
+ "sort": {"field": [], "order": []},
+ "as": ["mean_acc_start", "mean_acc_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"mean_acc\"]) && isFinite(+datum[\"mean_acc\"])"
@@ -46,8 +54,8 @@
},
"x": {"scale": "x", "field": "Cylinders"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "mean_acc"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "mean_acc_end"},
+ "y2": {"scale": "y", "field": "mean_acc_start"}
}
}
}
@@ -64,7 +72,10 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "source_0", "field": "mean_acc"},
+ "domain": {
+ "data": "source_0",
+ "fields": ["mean_acc_start", "mean_acc_end"]
+ },
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_argmax_transform.vg.json b/examples/compiled/bar_argmax_transform.vg.json
index d985a8d0a1..87a4afbed9 100644
--- a/examples/compiled/bar_argmax_transform.vg.json
+++ b/examples/compiled/bar_argmax_transform.vg.json
@@ -23,6 +23,17 @@
"expr": "datum[\"argmax_US_Gross\"] && datum[\"argmax_US_Gross\"][\"Production Budget\"]",
"as": "argmax_US_Gross.Production Budget"
},
+ {
+ "type": "stack",
+ "groupby": ["Major Genre"],
+ "field": "argmax_US_Gross\\.Production Budget",
+ "sort": {"field": [], "order": []},
+ "as": [
+ "argmax_US_Gross.Production Budget._start",
+ "argmax_US_Gross.Production Budget._end"
+ ],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"argmax_US_Gross.Production Budget\"]) && isFinite(+datum[\"argmax_US_Gross.Production Budget\"])"
@@ -50,8 +61,14 @@
"description": {
"signal": "\"argmax_US_Gross['Production Budget']: \" + (format(datum[\"argmax_US_Gross.Production Budget\"], \"\")) + \"; Major Genre: \" + (isValid(datum[\"Major Genre\"]) ? datum[\"Major Genre\"] : \"\"+datum[\"Major Genre\"])"
},
- "x": {"scale": "x", "field": "argmax_US_Gross\\.Production Budget"},
- "x2": {"scale": "x", "value": 0},
+ "x": {
+ "scale": "x",
+ "field": "argmax_US_Gross\\.Production Budget\\._end"
+ },
+ "x2": {
+ "scale": "x",
+ "field": "argmax_US_Gross\\.Production Budget\\._start"
+ },
"y": {"scale": "y", "field": "Major Genre"},
"height": {"scale": "y", "band": 1}
}
@@ -64,7 +81,10 @@
"type": "linear",
"domain": {
"data": "source_0",
- "field": "argmax_US_Gross\\.Production Budget"
+ "fields": [
+ "argmax_US_Gross\\.Production Budget\\._start",
+ "argmax_US_Gross\\.Production Budget\\._end"
+ ]
},
"range": [0, {"signal": "width"}],
"nice": true,
diff --git a/examples/compiled/bar_axis_orient_signal_future.vg.json b/examples/compiled/bar_axis_orient_signal_future.vg.json
index 5631559ac5..552dcbeb94 100644
--- a/examples/compiled/bar_axis_orient_signal_future.vg.json
+++ b/examples/compiled/bar_axis_orient_signal_future.vg.json
@@ -25,6 +25,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -54,8 +62,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -72,7 +80,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_color_disabled_scale.vg.json b/examples/compiled/bar_color_disabled_scale.vg.json
index c63876568c..68c3a29ad3 100644
--- a/examples/compiled/bar_color_disabled_scale.vg.json
+++ b/examples/compiled/bar_color_disabled_scale.vg.json
@@ -18,6 +18,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["color"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -47,8 +55,8 @@
},
"x": {"scale": "x", "field": "color"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -65,7 +73,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_column_fold.vg.json b/examples/compiled/bar_column_fold.vg.json
index 2eec0646da..f197b99d3d 100644
--- a/examples/compiled/bar_column_fold.vg.json
+++ b/examples/compiled/bar_column_fold.vg.json
@@ -15,6 +15,14 @@
"source": "source_0",
"transform": [
{"type": "fold", "fields": ["gold", "silver"], "as": ["key", "value"]},
+ {
+ "type": "stack",
+ "groupby": ["country", "key"],
+ "field": "value",
+ "sort": {"field": [], "order": []},
+ "as": ["value_start", "value_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"value\"]) && isFinite(+datum[\"value\"])"
@@ -131,8 +139,8 @@
},
"x": {"scale": "x", "field": "country"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "value"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "value_end"},
+ "y2": {"scale": "y", "field": "value_start"}
}
}
}
@@ -167,7 +175,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "value"},
+ "domain": {"data": "data_0", "fields": ["value_start", "value_end"]},
"range": [{"signal": "child_height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_column_pivot.vg.json b/examples/compiled/bar_column_pivot.vg.json
index ad450b0681..3e69682af4 100644
--- a/examples/compiled/bar_column_pivot.vg.json
+++ b/examples/compiled/bar_column_pivot.vg.json
@@ -29,6 +29,14 @@
"value": "count",
"groupby": ["country"]
},
+ {
+ "type": "stack",
+ "groupby": ["country"],
+ "field": "gold",
+ "sort": {"field": [], "order": []},
+ "as": ["gold_start", "gold_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"gold\"]) && isFinite(+datum[\"gold\"])"
@@ -58,8 +66,8 @@
},
"x": {"scale": "x", "field": "country"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "gold"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "gold_end"},
+ "y2": {"scale": "y", "field": "gold_start"}
}
}
}
@@ -76,7 +84,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "gold"},
+ "domain": {"data": "data_0", "fields": ["gold_start", "gold_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_corner_radius_end.svg b/examples/compiled/bar_corner_radius_end.svg
index 1b6fd00d71..ec6bc8107a 100644
--- a/examples/compiled/bar_corner_radius_end.svg
+++ b/examples/compiled/bar_corner_radius_end.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/examples/compiled/bar_corner_radius_end.vg.json b/examples/compiled/bar_corner_radius_end.vg.json
index 14dc2f0740..64a6015a4f 100644
--- a/examples/compiled/bar_corner_radius_end.vg.json
+++ b/examples/compiled/bar_corner_radius_end.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -40,25 +48,64 @@
],
"marks": [
{
- "name": "marks",
- "type": "rect",
- "style": ["bar"],
- "from": {"data": "data_0"},
+ "type": "group",
+ "from": {
+ "facet": {
+ "data": "data_0",
+ "name": "stack_group_main",
+ "groupby": ["a"],
+ "aggregate": {
+ "fields": ["b_start", "b_start", "b_end", "b_end"],
+ "ops": ["min", "max", "min", "max"]
+ }
+ }
+ },
"encode": {
"update": {
- "cornerRadiusTopLeft": {"value": 4},
- "cornerRadiusTopRight": {"value": 4},
- "fill": {"value": "#4c78a8"},
- "ariaRoleDescription": {"value": "bar"},
- "description": {
- "signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
- },
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {
+ "signal": "min(scale('y',datum[\"min_b_start\"]),scale('y',datum[\"max_b_start\"]),scale('y',datum[\"min_b_end\"]),scale('y',datum[\"max_b_end\"]))"
+ },
+ "y2": {
+ "signal": "max(scale('y',datum[\"min_b_start\"]),scale('y',datum[\"max_b_start\"]),scale('y',datum[\"min_b_end\"]),scale('y',datum[\"max_b_end\"]))"
+ },
+ "clip": {"value": true},
+ "cornerRadiusTopLeft": {"value": 4},
+ "cornerRadiusTopRight": {"value": 4}
}
- }
+ },
+ "marks": [
+ {
+ "type": "group",
+ "encode": {
+ "update": {
+ "y": {"field": {"group": "y"}, "mult": -1},
+ "width": {"field": {"group": "width"}}
+ }
+ },
+ "marks": [
+ {
+ "name": "marks",
+ "type": "rect",
+ "style": ["bar"],
+ "from": {"data": "stack_group_main"},
+ "encode": {
+ "update": {
+ "fill": {"value": "#4c78a8"},
+ "ariaRoleDescription": {"value": "bar"},
+ "description": {
+ "signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
+ },
+ "width": {"field": {"group": "width"}},
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
+ }
+ }
+ }
+ ]
+ }
+ ]
}
],
"scales": [
@@ -73,7 +120,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_custom_sort_full.vg.json b/examples/compiled/bar_custom_sort_full.vg.json
index be87e67c82..4cfa00cbdc 100644
--- a/examples/compiled/bar_custom_sort_full.vg.json
+++ b/examples/compiled/bar_custom_sort_full.vg.json
@@ -24,6 +24,14 @@
"name": "data_1",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -53,8 +61,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -75,7 +83,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_1", "field": "b"},
+ "domain": {"data": "data_1", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_custom_sort_partial.vg.json b/examples/compiled/bar_custom_sort_partial.vg.json
index 7a9c1c59e7..cc37703181 100644
--- a/examples/compiled/bar_custom_sort_partial.vg.json
+++ b/examples/compiled/bar_custom_sort_partial.vg.json
@@ -31,6 +31,14 @@
"name": "data_1",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -60,8 +68,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -82,7 +90,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_1", "field": "b"},
+ "domain": {"data": "data_1", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_custom_time_domain.vg.json b/examples/compiled/bar_custom_time_domain.vg.json
index 3b3a710947..fef5727456 100644
--- a/examples/compiled/bar_custom_time_domain.vg.json
+++ b/examples/compiled/bar_custom_time_domain.vg.json
@@ -26,6 +26,14 @@
"units": ["hours"],
"as": ["hours_a", "hours_a_end"]
},
+ {
+ "type": "stack",
+ "groupby": ["hours_a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "(isDate(datum[\"hours_a\"]) || (isValid(datum[\"hours_a\"]) && isFinite(+datum[\"hours_a\"]))) && isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -60,8 +68,8 @@
},
{"scale": "x", "field": "hours_a_end"}
],
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -81,7 +89,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_default_tooltip_title_null.vg.json b/examples/compiled/bar_default_tooltip_title_null.vg.json
index 2be9384556..414e5a232d 100644
--- a/examples/compiled/bar_default_tooltip_title_null.vg.json
+++ b/examples/compiled/bar_default_tooltip_title_null.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -56,8 +64,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -74,7 +82,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_filter_calc.vg.json b/examples/compiled/bar_filter_calc.vg.json
index 57fa80f133..961077ae0d 100644
--- a/examples/compiled/bar_filter_calc.vg.json
+++ b/examples/compiled/bar_filter_calc.vg.json
@@ -26,6 +26,14 @@
"transform": [
{"type": "formula", "expr": "2*datum.b", "as": "b2"},
{"type": "filter", "expr": "datum.b2 > 60"},
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b2",
+ "sort": {"field": [], "order": []},
+ "as": ["b2_start", "b2_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b2\"]) && isFinite(+datum[\"b2\"])"
@@ -55,8 +63,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b2"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b2_end"},
+ "y2": {"scale": "y", "field": "b2_start"}
}
}
}
@@ -73,7 +81,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b2"},
+ "domain": {"data": "data_0", "fields": ["b2_start", "b2_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_fit.vg.json b/examples/compiled/bar_fit.vg.json
index c72e3e8817..6abf452be9 100644
--- a/examples/compiled/bar_fit.vg.json
+++ b/examples/compiled/bar_fit.vg.json
@@ -26,6 +26,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -48,8 +56,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -66,7 +74,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_negative.vg.json b/examples/compiled/bar_negative.vg.json
index ec64412589..8f9e76b9f9 100644
--- a/examples/compiled/bar_negative.vg.json
+++ b/examples/compiled/bar_negative.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -53,8 +61,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -71,7 +79,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_params.svg b/examples/compiled/bar_params.svg
index 9e458ba525..1fbef27891 100644
--- a/examples/compiled/bar_params.svg
+++ b/examples/compiled/bar_params.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/examples/compiled/bar_params.vg.json b/examples/compiled/bar_params.vg.json
index 69deed03e2..e34db33fa3 100644
--- a/examples/compiled/bar_params.vg.json
+++ b/examples/compiled/bar_params.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -50,26 +58,65 @@
],
"marks": [
{
- "name": "marks",
- "type": "rect",
- "style": ["bar"],
- "from": {"data": "data_0"},
+ "type": "group",
+ "from": {
+ "facet": {
+ "data": "data_0",
+ "name": "stack_group_main",
+ "groupby": ["a"],
+ "aggregate": {
+ "fields": ["b_start", "b_start", "b_end", "b_end"],
+ "ops": ["min", "max", "min", "max"]
+ }
+ }
+ },
"encode": {
"update": {
+ "x": {"scale": "x", "field": "a"},
+ "width": {"scale": "x", "band": 1},
+ "y": {
+ "signal": "min(scale('y',datum[\"min_b_start\"]),scale('y',datum[\"max_b_start\"]),scale('y',datum[\"min_b_end\"]),scale('y',datum[\"max_b_end\"]))"
+ },
+ "y2": {
+ "signal": "max(scale('y',datum[\"min_b_start\"]),scale('y',datum[\"max_b_start\"]),scale('y',datum[\"min_b_end\"]),scale('y',datum[\"max_b_end\"]))"
+ },
+ "clip": {"value": true},
"cornerRadius": {"signal": "cornerRadius"},
"cornerRadiusTopLeft": {"signal": "cornerRadiusEnd"},
- "cornerRadiusTopRight": {"signal": "cornerRadiusEnd"},
- "fill": {"value": "#4c78a8"},
- "ariaRoleDescription": {"value": "bar"},
- "description": {
- "signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
+ "cornerRadiusTopRight": {"signal": "cornerRadiusEnd"}
+ }
+ },
+ "marks": [
+ {
+ "type": "group",
+ "encode": {
+ "update": {
+ "y": {"field": {"group": "y"}, "mult": -1},
+ "width": {"field": {"group": "width"}}
+ }
},
- "x": {"scale": "x", "field": "a"},
- "width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "marks": [
+ {
+ "name": "marks",
+ "type": "rect",
+ "style": ["bar"],
+ "from": {"data": "stack_group_main"},
+ "encode": {
+ "update": {
+ "fill": {"value": "#4c78a8"},
+ "ariaRoleDescription": {"value": "bar"},
+ "description": {
+ "signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
+ },
+ "width": {"field": {"group": "width"}},
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
+ }
+ }
+ }
+ ]
}
- }
+ ]
}
],
"scales": [
@@ -84,7 +131,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_title.vg.json b/examples/compiled/bar_title.vg.json
index 61abeede99..cac465ad90 100644
--- a/examples/compiled/bar_title.vg.json
+++ b/examples/compiled/bar_title.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -53,8 +61,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -71,7 +79,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_title_start.vg.json b/examples/compiled/bar_title_start.vg.json
index 37ce30bca4..060cdc9c87 100644
--- a/examples/compiled/bar_title_start.vg.json
+++ b/examples/compiled/bar_title_start.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -53,8 +61,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -71,7 +79,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_tooltip.vg.json b/examples/compiled/bar_tooltip.vg.json
index 8d8747c756..2ab3ef1e59 100644
--- a/examples/compiled/bar_tooltip.vg.json
+++ b/examples/compiled/bar_tooltip.vg.json
@@ -24,6 +24,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -54,8 +62,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -72,7 +80,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_tooltip_multi.vg.json b/examples/compiled/bar_tooltip_multi.vg.json
index 369dfaf67d..a1b3f4e40a 100644
--- a/examples/compiled/bar_tooltip_multi.vg.json
+++ b/examples/compiled/bar_tooltip_multi.vg.json
@@ -23,6 +23,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -55,8 +63,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -73,7 +81,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/bar_tooltip_title.vg.json b/examples/compiled/bar_tooltip_title.vg.json
index fc6e2d176d..78c257643f 100644
--- a/examples/compiled/bar_tooltip_title.vg.json
+++ b/examples/compiled/bar_tooltip_title.vg.json
@@ -23,6 +23,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -55,8 +63,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -73,7 +81,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/facet_bullet.vg.json b/examples/compiled/facet_bullet.vg.json
index 465fd35351..1080a96e24 100644
--- a/examples/compiled/facet_bullet.vg.json
+++ b/examples/compiled/facet_bullet.vg.json
@@ -83,6 +83,14 @@
"name": "data_1",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["title"],
+ "field": "ranges\\.2",
+ "sort": {"field": [], "order": []},
+ "as": ["ranges.2._start", "ranges.2._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"ranges.2\"]) && isFinite(+datum[\"ranges.2\"])"
@@ -93,6 +101,14 @@
"name": "data_2",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["title"],
+ "field": "ranges\\.1",
+ "sort": {"field": [], "order": []},
+ "as": ["ranges.1._start", "ranges.1._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"ranges.1\"]) && isFinite(+datum[\"ranges.1\"])"
@@ -103,6 +119,14 @@
"name": "data_3",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["title"],
+ "field": "ranges\\.0",
+ "sort": {"field": [], "order": []},
+ "as": ["ranges.0._start", "ranges.0._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"ranges.0\"]) && isFinite(+datum[\"ranges.0\"])"
@@ -113,6 +137,14 @@
"name": "data_4",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["title"],
+ "field": "measures\\.1",
+ "sort": {"field": [], "order": []},
+ "as": ["measures.1._start", "measures.1._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"measures.1\"]) && isFinite(+datum[\"measures.1\"])"
@@ -123,6 +155,14 @@
"name": "data_5",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["title"],
+ "field": "measures\\.0",
+ "sort": {"field": [], "order": []},
+ "as": ["measures.0._start", "measures.0._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"measures.0\"]) && isFinite(+datum[\"measures.0\"])"
@@ -184,6 +224,14 @@
"source": "facet",
"name": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": [],
+ "field": "ranges\\.2",
+ "sort": {"field": [], "order": []},
+ "as": ["ranges.2._start", "ranges.2._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"ranges.2\"]) && isFinite(+datum[\"ranges.2\"])"
@@ -194,6 +242,14 @@
"source": "facet",
"name": "data_1",
"transform": [
+ {
+ "type": "stack",
+ "groupby": [],
+ "field": "ranges\\.1",
+ "sort": {"field": [], "order": []},
+ "as": ["ranges.1._start", "ranges.1._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"ranges.1\"]) && isFinite(+datum[\"ranges.1\"])"
@@ -204,6 +260,14 @@
"source": "facet",
"name": "data_2",
"transform": [
+ {
+ "type": "stack",
+ "groupby": [],
+ "field": "ranges\\.0",
+ "sort": {"field": [], "order": []},
+ "as": ["ranges.0._start", "ranges.0._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"ranges.0\"]) && isFinite(+datum[\"ranges.0\"])"
@@ -214,6 +278,14 @@
"source": "facet",
"name": "data_3",
"transform": [
+ {
+ "type": "stack",
+ "groupby": [],
+ "field": "measures\\.1",
+ "sort": {"field": [], "order": []},
+ "as": ["measures.1._start", "measures.1._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"measures.1\"]) && isFinite(+datum[\"measures.1\"])"
@@ -224,6 +296,14 @@
"source": "facet",
"name": "data_4",
"transform": [
+ {
+ "type": "stack",
+ "groupby": [],
+ "field": "measures\\.0",
+ "sort": {"field": [], "order": []},
+ "as": ["measures.0._start", "measures.0._end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"measures.0\"]) && isFinite(+datum[\"measures.0\"])"
@@ -261,8 +341,8 @@
"description": {
"signal": "\"ranges[2]: \" + (format(datum[\"ranges.2\"], \"\"))"
},
- "x": {"scale": "child_x", "field": "ranges\\.2"},
- "x2": {"scale": "child_x", "value": 0},
+ "x": {"scale": "child_x", "field": "ranges\\.2\\._end"},
+ "x2": {"scale": "child_x", "field": "ranges\\.2\\._start"},
"yc": {"signal": "child_height", "mult": 0.5},
"height": {"value": 18}
}
@@ -280,8 +360,8 @@
"description": {
"signal": "\"ranges[1]: \" + (format(datum[\"ranges.1\"], \"\"))"
},
- "x": {"scale": "child_x", "field": "ranges\\.1"},
- "x2": {"scale": "child_x", "value": 0},
+ "x": {"scale": "child_x", "field": "ranges\\.1\\._end"},
+ "x2": {"scale": "child_x", "field": "ranges\\.1\\._start"},
"yc": {"signal": "child_height", "mult": 0.5},
"height": {"value": 18}
}
@@ -299,8 +379,8 @@
"description": {
"signal": "\"ranges[0]: \" + (format(datum[\"ranges.0\"], \"\"))"
},
- "x": {"scale": "child_x", "field": "ranges\\.0"},
- "x2": {"scale": "child_x", "value": 0},
+ "x": {"scale": "child_x", "field": "ranges\\.0\\._end"},
+ "x2": {"scale": "child_x", "field": "ranges\\.0\\._start"},
"yc": {"signal": "child_height", "mult": 0.5},
"height": {"value": 18}
}
@@ -318,8 +398,8 @@
"description": {
"signal": "\"measures[1]: \" + (format(datum[\"measures.1\"], \"\"))"
},
- "x": {"scale": "child_x", "field": "measures\\.1"},
- "x2": {"scale": "child_x", "value": 0},
+ "x": {"scale": "child_x", "field": "measures\\.1\\._end"},
+ "x2": {"scale": "child_x", "field": "measures\\.1\\._start"},
"yc": {"signal": "child_height", "mult": 0.5},
"height": {"value": 10}
}
@@ -337,8 +417,8 @@
"description": {
"signal": "\"measures[0]: \" + (format(datum[\"measures.0\"], \"\"))"
},
- "x": {"scale": "child_x", "field": "measures\\.0"},
- "x2": {"scale": "child_x", "value": 0},
+ "x": {"scale": "child_x", "field": "measures\\.0\\._end"},
+ "x2": {"scale": "child_x", "field": "measures\\.0\\._start"},
"yc": {"signal": "child_height", "mult": 0.5},
"height": {"value": 10}
}
@@ -371,11 +451,16 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "data_0", "field": "ranges\\.2"},
- {"data": "data_1", "field": "ranges\\.1"},
- {"data": "data_2", "field": "ranges\\.0"},
- {"data": "data_3", "field": "measures\\.1"},
- {"data": "data_4", "field": "measures\\.0"},
+ {"data": "data_0", "field": "ranges\\.2\\._start"},
+ {"data": "data_0", "field": "ranges\\.2\\._end"},
+ {"data": "data_1", "field": "ranges\\.1\\._start"},
+ {"data": "data_1", "field": "ranges\\.1\\._end"},
+ {"data": "data_2", "field": "ranges\\.0\\._start"},
+ {"data": "data_2", "field": "ranges\\.0\\._end"},
+ {"data": "data_3", "field": "measures\\.1\\._start"},
+ {"data": "data_3", "field": "measures\\.1\\._end"},
+ {"data": "data_4", "field": "measures\\.0\\._start"},
+ {"data": "data_4", "field": "measures\\.0\\._end"},
{"data": "data_5", "field": "markers\\.0"}
]
},
diff --git a/examples/compiled/facet_grid_bar.vg.json b/examples/compiled/facet_grid_bar.vg.json
index 2297ec3331..2d3696ae45 100644
--- a/examples/compiled/facet_grid_bar.vg.json
+++ b/examples/compiled/facet_grid_bar.vg.json
@@ -40,6 +40,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["c", "a", "b"],
+ "field": "p",
+ "sort": {"field": [], "order": []},
+ "as": ["p_start", "p_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"p\"]) && isFinite(+datum[\"p\"])"
@@ -181,8 +189,8 @@
"description": {
"signal": "\"c: \" + (isValid(datum[\"c\"]) ? datum[\"c\"] : \"\"+datum[\"c\"]) + \"; p: \" + (format(datum[\"p\"], \"%\")) + \"; settings: \" + (isValid(datum[\"c\"]) ? datum[\"c\"] : \"\"+datum[\"c\"])"
},
- "x": {"scale": "x", "field": "p"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "p_end"},
+ "x2": {"scale": "x", "field": "p_start"},
"y": {"scale": "y", "field": "c"},
"height": {"scale": "y", "band": 1}
}
@@ -211,7 +219,7 @@
{
"name": "x",
"type": "linear",
- "domain": {"data": "data_0", "field": "p"},
+ "domain": {"data": "data_0", "fields": ["p_start", "p_end"]},
"range": [0, {"signal": "child_width"}],
"nice": true,
"zero": true
diff --git a/examples/compiled/interactive_bar_select_highlight.vg.json b/examples/compiled/interactive_bar_select_highlight.vg.json
index 3fbbfd62e1..1a588a2169 100644
--- a/examples/compiled/interactive_bar_select_highlight.vg.json
+++ b/examples/compiled/interactive_bar_select_highlight.vg.json
@@ -27,6 +27,14 @@
"source": "source_0",
"transform": [
{"type": "identifier", "as": "_vgsid_"},
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -151,8 +159,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
}
@@ -169,7 +177,7 @@
{
"name": "y",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/interactive_dashboard_europe_pop.vg.json b/examples/compiled/interactive_dashboard_europe_pop.vg.json
index 70eeaff7e0..9a9fc3c4fc 100644
--- a/examples/compiled/interactive_dashboard_europe_pop.vg.json
+++ b/examples/compiled/interactive_dashboard_europe_pop.vg.json
@@ -313,6 +313,17 @@
"name": "data_1",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["Country"],
+ "field": "Population_ages_15_64_of_total",
+ "sort": {"field": [], "order": []},
+ "as": [
+ "Population_ages_15_64_of_total_start",
+ "Population_ages_15_64_of_total_end"
+ ],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"Population_ages_15_64_of_total\"]) && isFinite(+datum[\"Population_ages_15_64_of_total\"])"
@@ -323,6 +334,17 @@
"name": "data_2",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["Country"],
+ "field": "Population_ages_65_and_above_of_total",
+ "sort": {"field": [], "order": []},
+ "as": [
+ "Population_ages_65_and_above_of_total_start",
+ "Population_ages_65_and_above_of_total_end"
+ ],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"Population_ages_65_and_above_of_total\"]) && isFinite(+datum[\"Population_ages_65_and_above_of_total\"])"
@@ -597,9 +619,12 @@
},
"x": {
"scale": "concat_0_x",
- "field": "Population_ages_15_64_of_total"
+ "field": "Population_ages_15_64_of_total_end"
+ },
+ "x2": {
+ "scale": "concat_0_x",
+ "field": "Population_ages_15_64_of_total_start"
},
- "x2": {"scale": "concat_0_x", "value": 0},
"y": {"scale": "concat_0_y", "field": "Country"},
"height": {"scale": "concat_0_y", "band": 1}
}
@@ -918,9 +943,12 @@
},
"x": {
"scale": "concat_1_x",
- "field": "Population_ages_65_and_above_of_total"
+ "field": "Population_ages_65_and_above_of_total_end"
+ },
+ "x2": {
+ "scale": "concat_1_x",
+ "field": "Population_ages_65_and_above_of_total_start"
},
- "x2": {"scale": "concat_1_x", "value": 0},
"y": {"scale": "concat_1_y", "field": "Country"},
"height": {"scale": "concat_1_y", "band": 1}
}
@@ -1440,7 +1468,13 @@
{
"name": "concat_0_x",
"type": "linear",
- "domain": {"data": "data_1", "field": "Population_ages_15_64_of_total"},
+ "domain": {
+ "data": "data_1",
+ "fields": [
+ "Population_ages_15_64_of_total_start",
+ "Population_ages_15_64_of_total_end"
+ ]
+ },
"range": [0, {"signal": "concat_0_width"}],
"nice": true,
"zero": true
@@ -1452,7 +1486,7 @@
"data": "source_0",
"field": "Country",
"sort": {
- "op": "min",
+ "op": "sum",
"field": "Population_ages_15_64_of_total",
"order": "descending"
}
@@ -1466,7 +1500,10 @@
"type": "linear",
"domain": {
"data": "data_2",
- "field": "Population_ages_65_and_above_of_total"
+ "fields": [
+ "Population_ages_65_and_above_of_total_start",
+ "Population_ages_65_and_above_of_total_end"
+ ]
},
"range": [0, {"signal": "concat_1_width"}],
"nice": true,
@@ -1479,7 +1516,7 @@
"data": "source_0",
"field": "Country",
"sort": {
- "op": "min",
+ "op": "sum",
"field": "Population_ages_65_and_above_of_total",
"order": "descending"
}
diff --git a/examples/compiled/interactive_overview_detail.vg.json b/examples/compiled/interactive_overview_detail.vg.json
index 540c13e867..b0aea67264 100644
--- a/examples/compiled/interactive_overview_detail.vg.json
+++ b/examples/compiled/interactive_overview_detail.vg.json
@@ -9,6 +9,50 @@
"name": "source_0",
"url": "data/sp500.csv",
"format": {"type": "csv", "parse": {"date": "date"}}
+ },
+ {
+ "name": "data_0",
+ "source": "source_0",
+ "transform": [
+ {
+ "type": "impute",
+ "field": "price",
+ "groupby": [],
+ "key": "date",
+ "method": "value",
+ "value": 0
+ },
+ {
+ "type": "stack",
+ "groupby": ["date"],
+ "field": "price",
+ "sort": {"field": [], "order": []},
+ "as": ["price_start", "price_end"],
+ "offset": "zero"
+ }
+ ]
+ },
+ {
+ "name": "data_1",
+ "source": "source_0",
+ "transform": [
+ {
+ "type": "impute",
+ "field": "price",
+ "groupby": [],
+ "key": "date",
+ "method": "value",
+ "value": 0
+ },
+ {
+ "type": "stack",
+ "groupby": ["date"],
+ "field": "price",
+ "sort": {"field": [], "order": []},
+ "as": ["price_start", "price_end"],
+ "offset": "zero"
+ }
+ ]
}
],
"signals": [
@@ -46,7 +90,7 @@
"style": ["area"],
"sort": {"field": "datum[\"date\"]"},
"interactive": false,
- "from": {"data": "source_0"},
+ "from": {"data": "data_0"},
"encode": {
"update": {
"orient": {"value": "vertical"},
@@ -55,8 +99,8 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "concat_0_x", "field": "date"},
- "y": {"scale": "concat_0_y", "field": "price"},
- "y2": {"scale": "concat_0_y", "value": 0},
+ "y": {"scale": "concat_0_y", "field": "price_end"},
+ "y2": {"scale": "concat_0_y", "field": "price_start"},
"defined": {
"signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
}
@@ -337,7 +381,7 @@
"style": ["area"],
"sort": {"field": "datum[\"date\"]"},
"interactive": true,
- "from": {"data": "source_0"},
+ "from": {"data": "data_1"},
"encode": {
"update": {
"orient": {"value": "vertical"},
@@ -346,8 +390,8 @@
"signal": "\"date: \" + (timeFormat(datum[\"date\"], '%b %d, %Y')) + \"; price: \" + (format(datum[\"price\"], \"\"))"
},
"x": {"scale": "concat_1_x", "field": "date"},
- "y": {"scale": "concat_1_y", "field": "price"},
- "y2": {"scale": "concat_1_y", "value": 0},
+ "y": {"scale": "concat_1_y", "field": "price_end"},
+ "y2": {"scale": "concat_1_y", "field": "price_start"},
"defined": {
"signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"price\"]) && isFinite(+datum[\"price\"])"
}
@@ -438,14 +482,14 @@
{
"name": "concat_0_x",
"type": "time",
- "domain": {"data": "source_0", "field": "date"},
+ "domain": {"data": "data_0", "field": "date"},
"domainRaw": {"signal": "brush[\"date\"]"},
"range": [0, {"signal": "width"}]
},
{
"name": "concat_0_y",
"type": "linear",
- "domain": {"data": "source_0", "field": "price"},
+ "domain": {"data": "data_0", "fields": ["price_start", "price_end"]},
"range": [{"signal": "concat_0_height"}, 0],
"nice": true,
"zero": true
@@ -453,13 +497,13 @@
{
"name": "concat_1_x",
"type": "time",
- "domain": {"data": "source_0", "field": "date"},
+ "domain": {"data": "data_1", "field": "date"},
"range": [0, {"signal": "width"}]
},
{
"name": "concat_1_y",
"type": "linear",
- "domain": {"data": "source_0", "field": "price"},
+ "domain": {"data": "data_1", "fields": ["price_start", "price_end"]},
"range": [{"signal": "concat_1_height"}, 0],
"nice": true,
"zero": true
diff --git a/examples/compiled/joinaggregate_mean_difference.vg.json b/examples/compiled/joinaggregate_mean_difference.vg.json
index c04717e4c8..ae63ba42e2 100644
--- a/examples/compiled/joinaggregate_mean_difference.vg.json
+++ b/examples/compiled/joinaggregate_mean_difference.vg.json
@@ -27,6 +27,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["Title"],
+ "field": "IMDB Rating",
+ "sort": {"field": [], "order": []},
+ "as": ["IMDB Rating_start", "IMDB Rating_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"IMDB Rating\"]) && isFinite(+datum[\"IMDB Rating\"])"
@@ -71,8 +79,8 @@
"description": {
"signal": "\"IMDB Rating: \" + (format(datum[\"IMDB Rating\"], \"\")) + \"; Title: \" + (isValid(datum[\"Title\"]) ? datum[\"Title\"] : \"\"+datum[\"Title\"])"
},
- "x": {"scale": "x", "field": "IMDB Rating"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "IMDB Rating_end"},
+ "x2": {"scale": "x", "field": "IMDB Rating_start"},
"y": {"scale": "y", "field": "Title"},
"height": {"scale": "y", "band": 1}
}
@@ -102,7 +110,8 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "data_0", "field": "IMDB Rating"},
+ {"data": "data_0", "field": "IMDB Rating_start"},
+ {"data": "data_0", "field": "IMDB Rating_end"},
{"data": "data_1", "field": "average_AverageRating"}
]
},
diff --git a/examples/compiled/joinaggregate_mean_difference_by_year.vg.json b/examples/compiled/joinaggregate_mean_difference_by_year.vg.json
index 6febd7fb52..476b0af3f3 100644
--- a/examples/compiled/joinaggregate_mean_difference_by_year.vg.json
+++ b/examples/compiled/joinaggregate_mean_difference_by_year.vg.json
@@ -35,6 +35,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["Title"],
+ "field": "IMDB Rating",
+ "sort": {"field": [], "order": []},
+ "as": ["IMDB Rating_start", "IMDB Rating_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"IMDB Rating\"]) && isFinite(+datum[\"IMDB Rating\"])"
@@ -73,8 +81,8 @@
"description": {
"signal": "\"IMDB Rating: \" + (format(datum[\"IMDB Rating\"], \"\")) + \"; Title: \" + (isValid(datum[\"Title\"]) ? datum[\"Title\"] : \"\"+datum[\"Title\"])"
},
- "x": {"scale": "x", "field": "IMDB Rating"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "IMDB Rating_end"},
+ "x2": {"scale": "x", "field": "IMDB Rating_start"},
"y": {"scale": "y", "field": "Title"},
"height": {"scale": "y", "band": 1}
}
@@ -107,7 +115,8 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "data_0", "field": "IMDB Rating"},
+ {"data": "data_0", "field": "IMDB Rating_start"},
+ {"data": "data_0", "field": "IMDB Rating_end"},
{"data": "data_1", "field": "AverageYearRating"}
]
},
diff --git a/examples/compiled/joinaggregate_percent_of_total.vg.json b/examples/compiled/joinaggregate_percent_of_total.vg.json
index f5e9c1b4ce..ed7365cc58 100644
--- a/examples/compiled/joinaggregate_percent_of_total.vg.json
+++ b/examples/compiled/joinaggregate_percent_of_total.vg.json
@@ -31,6 +31,14 @@
"expr": "datum.Time/datum.TotalTime * 100",
"as": "PercentOfTotal"
},
+ {
+ "type": "stack",
+ "groupby": ["Activity"],
+ "field": "PercentOfTotal",
+ "sort": {"field": [], "order": []},
+ "as": ["PercentOfTotal_start", "PercentOfTotal_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"PercentOfTotal\"]) && isFinite(+datum[\"PercentOfTotal\"])"
@@ -58,8 +66,8 @@
"description": {
"signal": "\"% of total Time: \" + (format(datum[\"PercentOfTotal\"], \"\")) + \"; Activity: \" + (isValid(datum[\"Activity\"]) ? datum[\"Activity\"] : \"\"+datum[\"Activity\"])"
},
- "x": {"scale": "x", "field": "PercentOfTotal"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "PercentOfTotal_end"},
+ "x2": {"scale": "x", "field": "PercentOfTotal_start"},
"y": {"scale": "y", "field": "Activity"},
"height": {"scale": "y", "band": 1}
}
@@ -70,7 +78,10 @@
{
"name": "x",
"type": "linear",
- "domain": {"data": "data_0", "field": "PercentOfTotal"},
+ "domain": {
+ "data": "data_0",
+ "fields": ["PercentOfTotal_start", "PercentOfTotal_end"]
+ },
"range": [0, {"signal": "width"}],
"nice": true,
"zero": true
diff --git a/examples/compiled/layer_bar_annotations.vg.json b/examples/compiled/layer_bar_annotations.vg.json
index 588bd49c3d..481e8c5c7b 100644
--- a/examples/compiled/layer_bar_annotations.vg.json
+++ b/examples/compiled/layer_bar_annotations.vg.json
@@ -31,6 +31,14 @@
"name": "data_1",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["Day"],
+ "field": "Value",
+ "sort": {"field": [], "order": []},
+ "as": ["Value_start", "Value_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"Value\"]) && isFinite(+datum[\"Value\"])"
@@ -72,8 +80,8 @@
},
"x": {"scale": "x", "field": "Day"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "Value"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "Value_end"},
+ "y2": {"scale": "y", "field": "Value_start"}
}
}
},
@@ -149,7 +157,8 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "data_1", "field": "Value"},
+ {"data": "data_1", "field": "Value_start"},
+ {"data": "data_1", "field": "Value_end"},
{"data": "data_2", "field": "baseline"},
{"data": "data_2", "field": "Value"},
[300]
diff --git a/examples/compiled/layer_bar_labels.vg.json b/examples/compiled/layer_bar_labels.vg.json
index e8ba556f8e..a1213323b3 100644
--- a/examples/compiled/layer_bar_labels.vg.json
+++ b/examples/compiled/layer_bar_labels.vg.json
@@ -1,6 +1,6 @@
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
- "description": "Bar chart with text labels. Apply scale padding to make the frame cover the labels.",
+ "description": "Bar chart with text labels. Set domain to make the frame cover the labels.",
"background": "white",
"padding": 5,
"width": 200,
@@ -11,7 +11,25 @@
"values": [{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43}]
},
{
- "name": "data_0",
+ "name": "data_1",
+ "source": "source_0",
+ "transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
+ {
+ "type": "filter",
+ "expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
+ }
+ ]
+ },
+ {
+ "name": "data_2",
"source": "source_0",
"transform": [
{
@@ -33,7 +51,7 @@
"name": "layer_0_marks",
"type": "rect",
"style": ["bar"],
- "from": {"data": "data_0"},
+ "from": {"data": "data_1"},
"encode": {
"update": {
"fill": {"value": "#4c78a8"},
@@ -41,8 +59,8 @@
"description": {
"signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
},
- "x": {"scale": "x", "field": "b"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "b_end"},
+ "x2": {"scale": "x", "field": "b_start"},
"y": {"scale": "y", "field": "a"},
"height": {"scale": "y", "band": 1}
}
@@ -52,7 +70,7 @@
"name": "layer_1_marks",
"type": "text",
"style": ["text"],
- "from": {"data": "data_0"},
+ "from": {"data": "data_2"},
"encode": {
"update": {
"align": {"value": "left"},
@@ -73,16 +91,21 @@
{
"name": "x",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": [0, 60],
"range": [0, {"signal": "width"}],
- "padding": 10,
"nice": true,
"zero": true
},
{
"name": "y",
"type": "band",
- "domain": {"data": "data_0", "field": "a", "sort": true},
+ "domain": {
+ "fields": [
+ {"data": "data_1", "field": "a"},
+ {"data": "data_2", "field": "a"}
+ ],
+ "sort": true
+ },
"range": {"step": {"signal": "y_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
diff --git a/examples/compiled/layer_bar_labels_style.vg.json b/examples/compiled/layer_bar_labels_style.vg.json
index da34ff423a..96e3a868b5 100644
--- a/examples/compiled/layer_bar_labels_style.vg.json
+++ b/examples/compiled/layer_bar_labels_style.vg.json
@@ -10,7 +10,25 @@
"values": [{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43}]
},
{
- "name": "data_0",
+ "name": "data_1",
+ "source": "source_0",
+ "transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
+ {
+ "type": "filter",
+ "expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
+ }
+ ]
+ },
+ {
+ "name": "data_2",
"source": "source_0",
"transform": [
{
@@ -32,7 +50,7 @@
"name": "layer_0_marks",
"type": "rect",
"style": ["bar"],
- "from": {"data": "data_0"},
+ "from": {"data": "data_1"},
"encode": {
"update": {
"fill": {"value": "#4c78a8"},
@@ -40,8 +58,8 @@
"description": {
"signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
},
- "x": {"scale": "x", "field": "b"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "b_end"},
+ "x2": {"scale": "x", "field": "b_start"},
"y": {"scale": "y", "field": "a"},
"height": {"scale": "y", "band": 1}
}
@@ -51,7 +69,7 @@
"name": "layer_1_marks",
"type": "text",
"style": ["text", "label"],
- "from": {"data": "data_0"},
+ "from": {"data": "data_2"},
"encode": {
"update": {
"fill": {"value": "black"},
@@ -69,7 +87,13 @@
{
"name": "x",
"type": "linear",
- "domain": {"data": "data_0", "field": "b"},
+ "domain": {
+ "fields": [
+ {"data": "data_1", "field": "b_start"},
+ {"data": "data_1", "field": "b_end"},
+ {"data": "data_2", "field": "b"}
+ ]
+ },
"range": [0, {"signal": "width"}],
"nice": true,
"zero": true
@@ -77,7 +101,13 @@
{
"name": "y",
"type": "band",
- "domain": {"data": "data_0", "field": "a", "sort": true},
+ "domain": {
+ "fields": [
+ {"data": "data_1", "field": "a"},
+ {"data": "data_2", "field": "a"}
+ ],
+ "sort": true
+ },
"range": {"step": {"signal": "y_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
diff --git a/examples/compiled/layer_bar_line.vg.json b/examples/compiled/layer_bar_line.vg.json
index 53b3391873..eec6e7a17b 100644
--- a/examples/compiled/layer_bar_line.vg.json
+++ b/examples/compiled/layer_bar_line.vg.json
@@ -23,6 +23,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "b",
+ "sort": {"field": [], "order": []},
+ "as": ["b_start", "b_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
@@ -52,8 +60,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "b"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "b_end"},
+ "y2": {"scale": "y", "field": "b_start"}
}
}
},
@@ -98,7 +106,8 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "data_0", "field": "b"},
+ {"data": "data_0", "field": "b_start"},
+ {"data": "data_0", "field": "b_end"},
{"data": "source_0", "field": "b"}
]
},
diff --git a/examples/compiled/layer_bar_line_union.vg.json b/examples/compiled/layer_bar_line_union.vg.json
index 09bdf36657..ea1feef68a 100644
--- a/examples/compiled/layer_bar_line_union.vg.json
+++ b/examples/compiled/layer_bar_line_union.vg.json
@@ -23,6 +23,14 @@
"name": "data_0",
"source": "source_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["a"],
+ "field": "c",
+ "sort": {"field": [], "order": []},
+ "as": ["c_start", "c_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"c\"]) && isFinite(+datum[\"c\"])"
@@ -52,8 +60,8 @@
},
"x": {"scale": "x", "field": "a"},
"width": {"scale": "x", "band": 1},
- "y": {"scale": "y", "field": "c"},
- "y2": {"scale": "y", "value": 0}
+ "y": {"scale": "y", "field": "c_end"},
+ "y2": {"scale": "y", "field": "c_start"}
}
}
},
@@ -98,7 +106,8 @@
"type": "linear",
"domain": {
"fields": [
- {"data": "data_0", "field": "c"},
+ {"data": "data_0", "field": "c_start"},
+ {"data": "data_0", "field": "c_end"},
{"data": "source_0", "field": "c"}
]
},
diff --git a/examples/compiled/trellis_area_seattle.png b/examples/compiled/trellis_area_seattle.png
index 01ee80d2e9..25ff23c931 100644
Binary files a/examples/compiled/trellis_area_seattle.png and b/examples/compiled/trellis_area_seattle.png differ
diff --git a/examples/compiled/trellis_area_seattle.svg b/examples/compiled/trellis_area_seattle.svg
index 2d2ec8d6d4..67f2fa26be 100644
--- a/examples/compiled/trellis_area_seattle.svg
+++ b/examples/compiled/trellis_area_seattle.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/examples/compiled/trellis_area_seattle.vg.json b/examples/compiled/trellis_area_seattle.vg.json
index 84f727bda9..95353fa85c 100644
--- a/examples/compiled/trellis_area_seattle.vg.json
+++ b/examples/compiled/trellis_area_seattle.vg.json
@@ -20,6 +20,19 @@
"type": "timeunit",
"units": ["hours"],
"as": ["hours_date", "hours_date_end"]
+ },
+ {
+ "field": "date",
+ "type": "timeunit",
+ "units": ["month", "date"],
+ "as": ["monthdate_date", "monthdate_date_end"]
+ },
+ {
+ "type": "aggregate",
+ "groupby": ["monthdate_date", "hours_date"],
+ "ops": ["mean"],
+ "fields": ["temperature"],
+ "as": ["mean_temperature"]
}
]
},
@@ -143,20 +156,20 @@
"name": "child_marks",
"type": "area",
"style": ["area"],
- "sort": {"field": "datum[\"date\"]"},
+ "sort": {"field": "datum[\"monthdate_date\"]"},
"from": {"data": "facet"},
"encode": {
"update": {
"orient": {"value": "vertical"},
"fill": {"value": "#4c78a8"},
"description": {
- "signal": "\"Month: \" + (timeFormat(datum[\"date\"], '%b')) + \"; temperature: \" + (format(datum[\"temperature\"], \"\"))"
+ "signal": "\"Month: \" + (timeFormat(datum[\"monthdate_date\"], '%b')) + \"; Mean of temperature: \" + (format(datum[\"mean_temperature\"], \"\"))"
},
- "x": {"scale": "x", "field": "date"},
- "y": {"scale": "y", "field": "temperature"},
+ "x": {"scale": "x", "field": "monthdate_date"},
+ "y": {"scale": "y", "field": "mean_temperature"},
"y2": {"field": {"group": "height"}},
"defined": {
- "signal": "isValid(datum[\"date\"]) && isFinite(+datum[\"date\"]) && isValid(datum[\"temperature\"]) && isFinite(+datum[\"temperature\"])"
+ "signal": "isValid(datum[\"monthdate_date\"]) && isFinite(+datum[\"monthdate_date\"]) && isValid(datum[\"mean_temperature\"]) && isFinite(+datum[\"mean_temperature\"])"
}
}
}
@@ -168,13 +181,13 @@
{
"name": "x",
"type": "time",
- "domain": {"data": "source_0", "field": "date"},
+ "domain": {"data": "source_0", "field": "monthdate_date"},
"range": [0, {"signal": "child_width"}]
},
{
"name": "y",
"type": "linear",
- "domain": {"data": "source_0", "field": "temperature"},
+ "domain": {"data": "source_0", "field": "mean_temperature"},
"range": [{"signal": "child_height"}, 0],
"zero": false,
"nice": true
diff --git a/examples/compiled/window_percent_of_total.vg.json b/examples/compiled/window_percent_of_total.vg.json
index f5e9c1b4ce..ed7365cc58 100644
--- a/examples/compiled/window_percent_of_total.vg.json
+++ b/examples/compiled/window_percent_of_total.vg.json
@@ -31,6 +31,14 @@
"expr": "datum.Time/datum.TotalTime * 100",
"as": "PercentOfTotal"
},
+ {
+ "type": "stack",
+ "groupby": ["Activity"],
+ "field": "PercentOfTotal",
+ "sort": {"field": [], "order": []},
+ "as": ["PercentOfTotal_start", "PercentOfTotal_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"PercentOfTotal\"]) && isFinite(+datum[\"PercentOfTotal\"])"
@@ -58,8 +66,8 @@
"description": {
"signal": "\"% of total Time: \" + (format(datum[\"PercentOfTotal\"], \"\")) + \"; Activity: \" + (isValid(datum[\"Activity\"]) ? datum[\"Activity\"] : \"\"+datum[\"Activity\"])"
},
- "x": {"scale": "x", "field": "PercentOfTotal"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "PercentOfTotal_end"},
+ "x2": {"scale": "x", "field": "PercentOfTotal_start"},
"y": {"scale": "y", "field": "Activity"},
"height": {"scale": "y", "band": 1}
}
@@ -70,7 +78,10 @@
{
"name": "x",
"type": "linear",
- "domain": {"data": "data_0", "field": "PercentOfTotal"},
+ "domain": {
+ "data": "data_0",
+ "fields": ["PercentOfTotal_start", "PercentOfTotal_end"]
+ },
"range": [0, {"signal": "width"}],
"nice": true,
"zero": true
diff --git a/examples/compiled/window_top_k.vg.json b/examples/compiled/window_top_k.vg.json
index 38e3ce1077..37d343a85f 100644
--- a/examples/compiled/window_top_k.vg.json
+++ b/examples/compiled/window_top_k.vg.json
@@ -52,6 +52,14 @@
"name": "data_1",
"source": "data_0",
"transform": [
+ {
+ "type": "stack",
+ "groupby": ["student"],
+ "field": "score",
+ "sort": {"field": [], "order": []},
+ "as": ["score_start", "score_end"],
+ "offset": "zero"
+ },
{
"type": "filter",
"expr": "isValid(datum[\"score\"]) && isFinite(+datum[\"score\"])"
@@ -79,8 +87,8 @@
"description": {
"signal": "\"score: \" + (format(datum[\"score\"], \"\")) + \"; student: \" + (isValid(datum[\"student\"]) ? datum[\"student\"] : \"\"+datum[\"student\"])"
},
- "x": {"scale": "x", "field": "score"},
- "x2": {"scale": "x", "value": 0},
+ "x": {"scale": "x", "field": "score_end"},
+ "x2": {"scale": "x", "field": "score_start"},
"y": {"scale": "y", "field": "student"},
"height": {"scale": "y", "band": 1}
}
@@ -91,7 +99,7 @@
{
"name": "x",
"type": "linear",
- "domain": {"data": "data_1", "field": "score"},
+ "domain": {"data": "data_1", "fields": ["score_start", "score_end"]},
"range": [0, {"signal": "width"}],
"nice": true,
"zero": true
diff --git a/examples/specs/layer_bar_labels.vl.json b/examples/specs/layer_bar_labels.vl.json
index 0eb5167f30..ec3fbf2df5 100644
--- a/examples/specs/layer_bar_labels.vl.json
+++ b/examples/specs/layer_bar_labels.vl.json
@@ -1,6 +1,6 @@
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
- "description": "Bar chart with text labels. Apply scale padding to make the frame cover the labels.",
+ "description": "Bar chart with text labels. Set domain to make the frame cover the labels.",
"data": {
"values": [
{"a": "A", "b": 28},
@@ -10,7 +10,7 @@
},
"encoding": {
"y": {"field": "a", "type": "nominal"},
- "x": {"field": "b", "type": "quantitative", "scale": {"padding": 10}}
+ "x": {"field": "b", "type": "quantitative", "scale": {"domain": [0, 60]}}
},
"layer": [{
"mark": "bar"
diff --git a/examples/specs/normalized/area_gradient_normalized.vl.json b/examples/specs/normalized/area_gradient_normalized.vl.json
index f5da76f809..70175e869e 100644
--- a/examples/specs/normalized/area_gradient_normalized.vl.json
+++ b/examples/specs/normalized/area_gradient_normalized.vl.json
@@ -29,7 +29,7 @@
"mark": {"type": "line", "color": "darkgreen"},
"encoding": {
"x": {"field": "date", "type": "temporal"},
- "y": {"field": "price", "type": "quantitative"}
+ "y": {"field": "price", "type": "quantitative", "stack": "zero"}
}
}
]
diff --git a/examples/specs/normalized/area_overlay_normalized.vl.json b/examples/specs/normalized/area_overlay_normalized.vl.json
index 89ebb61ff1..d1a136396f 100644
--- a/examples/specs/normalized/area_overlay_normalized.vl.json
+++ b/examples/specs/normalized/area_overlay_normalized.vl.json
@@ -15,14 +15,14 @@
"mark": {"type": "line"},
"encoding": {
"x": {"field": "date", "type": "temporal"},
- "y": {"field": "price", "type": "quantitative"}
+ "y": {"field": "price", "type": "quantitative", "stack": "zero"}
}
},
{
"mark": {"type": "point", "opacity": 1, "filled": true},
"encoding": {
"x": {"field": "date", "type": "temporal"},
- "y": {"field": "price", "type": "quantitative"}
+ "y": {"field": "price", "type": "quantitative", "stack": "zero"}
}
}
]
diff --git a/examples/specs/normalized/layer_bar_labels_normalized.vl.json b/examples/specs/normalized/layer_bar_labels_normalized.vl.json
index 7a4afb8180..5c0aeab0f4 100644
--- a/examples/specs/normalized/layer_bar_labels_normalized.vl.json
+++ b/examples/specs/normalized/layer_bar_labels_normalized.vl.json
@@ -1,6 +1,6 @@
{
"$schema": "https://vega.github.io/schema/vega-lite/v4.json",
- "description": "Bar chart with text labels. Apply scale padding to make the frame cover the labels.",
+ "description": "Bar chart with text labels. Set domain to make the frame cover the labels.",
"data": {
"values": [{"a": "A", "b": 28}, {"a": "B", "b": 55}, {"a": "C", "b": 43}]
},
@@ -9,14 +9,22 @@
"mark": "bar",
"encoding": {
"y": {"field": "a", "type": "nominal"},
- "x": {"field": "b", "type": "quantitative", "scale": {"padding": 10}}
+ "x": {
+ "field": "b",
+ "type": "quantitative",
+ "scale": {"domain": [0, 60]}
+ }
}
},
{
"mark": {"type": "text", "align": "left", "baseline": "middle", "dx": 3},
"encoding": {
"y": {"field": "a", "type": "nominal"},
- "x": {"field": "b", "type": "quantitative", "scale": {"padding": 10}},
+ "x": {
+ "field": "b",
+ "type": "quantitative",
+ "scale": {"domain": [0, 60]}
+ },
"text": {"field": "b", "type": "quantitative"}
}
}
diff --git a/examples/specs/trellis_area_seattle.vl.json b/examples/specs/trellis_area_seattle.vl.json
index 146cac4aef..d685070b85 100644
--- a/examples/specs/trellis_area_seattle.vl.json
+++ b/examples/specs/trellis_area_seattle.vl.json
@@ -32,11 +32,13 @@
"field": "date",
"type": "temporal",
"title": "Month",
+ "timeUnit": "monthdate",
"axis": {"format": "%b"}
},
"y": {
"field": "temperature",
"type": "quantitative",
+ "aggregate": "mean",
"scale": {"zero": false},
"axis": {"title": null, "labels": false, "ticks": false}
}
diff --git a/src/compile/mark/mark.ts b/src/compile/mark/mark.ts
index 957e8afe19..4e092c7942 100644
--- a/src/compile/mark/mark.ts
+++ b/src/compile/mark/mark.ts
@@ -167,12 +167,19 @@ function getGroupsForStackedBarWithCornerRadius(model: UnitModel) {
}
}
- // For bin and time unit, we have to add bin/timeunit -end channels.
- const groupByField = model.fieldDef(model.stack.groupbyChannel);
- const groupby: string[] = vgField(groupByField) ? [vgField(groupByField)] : [];
+ const groupby: string[] = [];
- if (groupByField?.bin || groupByField?.timeUnit) {
- groupby.push(vgField(groupByField, {binSuffix: 'end'}));
+ if (model.stack.groupbyChannel) {
+ // For bin and time unit, we have to add bin/timeunit -end channels.
+ const groupByField = model.fieldDef(model.stack.groupbyChannel);
+ const field = vgField(groupByField);
+ if (field) {
+ groupby.push(field);
+ }
+
+ if (groupByField?.bin || groupByField?.timeUnit) {
+ groupby.push(vgField(groupByField, {binSuffix: 'end'}));
+ }
}
const strokeProperties = [
diff --git a/src/stack.ts b/src/stack.ts
index 83128bb39e..d3d971fbcf 100644
--- a/src/stack.ts
+++ b/src/stack.ts
@@ -207,8 +207,7 @@ export function stack(
} else {
offset = stackedFieldDef.stack;
}
- } else if (stackBy.length > 0 && STACK_BY_DEFAULT_MARKS.has(mark)) {
- // Bar and Area with sum ops are automatically stacked by default
+ } else if (STACK_BY_DEFAULT_MARKS.has(mark)) {
offset = 'zero';
}
@@ -221,7 +220,7 @@ export function stack(
}
// warn when stacking non-linear
- if (stackedFieldDef.scale && stackedFieldDef.scale.type && stackedFieldDef.scale.type !== ScaleType.LINEAR) {
+ if (stackedFieldDef?.scale?.type && stackedFieldDef?.scale?.type !== ScaleType.LINEAR) {
if (opt.disallowNonLinearStack) {
return null;
} else {
diff --git a/test/compile/mark/mark.test.ts b/test/compile/mark/mark.test.ts
index 11eb1d3ba9..2d27057c7d 100644
--- a/test/compile/mark/mark.test.ts
+++ b/test/compile/mark/mark.test.ts
@@ -217,7 +217,7 @@ describe('Mark', () => {
});
const markGroup = parseMarkGroups(model);
- expect(markGroup[0].aria).toBe(false);
+ expect(markGroup[0].marks[0].marks[0].aria).toBe(false);
});
it('should set aria to false for line mark', () => {
@@ -235,6 +235,22 @@ describe('Mark', () => {
expect(markGroup[0].aria).toBe(false);
});
+ it('should group mark with corder radius by nominal field', () => {
+ const model = parseUnitModelWithScaleAndLayoutSize({
+ mark: {
+ type: 'bar',
+ cornerRadius: 2
+ },
+ encoding: {
+ x: {type: 'quantitative', field: 'foo'},
+ y: {type: 'nominal', field: 'bar'}
+ }
+ });
+
+ const markGroup = parseMarkGroups(model);
+ expect(markGroup[0].from.facet.groupby).toEqual(['bar']);
+ });
+
describe('interactiveFlag', () => {
it('should not contain flag if no selections', () => {
const model = parseUnitModelWithScaleAndSelection({
diff --git a/test/normalize/pathoverlay.test.ts b/test/normalize/pathoverlay.test.ts
index 9aee9be07a..5d84259af2 100644
--- a/test/normalize/pathoverlay.test.ts
+++ b/test/normalize/pathoverlay.test.ts
@@ -170,14 +170,14 @@ describe('PathOverlayNormalizer', () => {
mark: {type: 'line'},
encoding: {
x: {field: 'date', type: 'temporal'},
- y: {field: 'price', type: 'quantitative'}
+ y: {field: 'price', type: 'quantitative', stack: 'zero'}
}
},
{
mark: {type: 'point', opacity: 1, filled: true},
encoding: {
x: {field: 'date', type: 'temporal'},
- y: {field: 'price', type: 'quantitative'}
+ y: {field: 'price', type: 'quantitative', stack: 'zero'}
}
}
],
@@ -210,7 +210,7 @@ describe('PathOverlayNormalizer', () => {
mark: {type: 'line', interpolate: 'monotone'},
encoding: {
x: {field: 'date', type: 'temporal'},
- y: {field: 'price', type: 'quantitative'}
+ y: {field: 'price', type: 'quantitative', stack: 'zero'}
}
}
],
@@ -349,7 +349,7 @@ describe('PathOverlayNormalizer', () => {
mark: {type: 'line'},
encoding: {
x: {field: 'date', type: 'temporal'},
- y: {field: 'price', type: 'quantitative'}
+ y: {field: 'price', type: 'quantitative', stack: 'zero'}
}
}
]
diff --git a/test/stack.test.ts b/test/stack.test.ts
index 895aab7c4a..8cb0e872f3 100644
--- a/test/stack.test.ts
+++ b/test/stack.test.ts
@@ -38,7 +38,7 @@ describe('stack', () => {
}
};
const stackProps = stack(spec.mark, spec.encoding, undefined);
- expect(stackProps.fieldChannel).toBe('x');
+ expect(stackProps.fieldChannel).toBe(X);
}
});
@@ -58,6 +58,21 @@ describe('stack', () => {
}
});
+ it('should stack default stack marks', () => {
+ for (const mark of STACK_BY_DEFAULT_MARKS) {
+ const spec: TopLevel = {
+ data: {url: 'data/barley.json'},
+ mark: mark,
+ encoding: {
+ x: {field: 'yield', type: 'quantitative'},
+ y: {field: 'variety', type: 'nominal'}
+ }
+ };
+ const stackProps = stack(spec.mark, spec.encoding, undefined);
+ expect(stackProps.fieldChannel).toBe(X);
+ }
+ });
+
it('should prioritize axis with stack', () => {
for (const mark of STACKABLE_NON_POLAR_MARKS) {
const spec: TopLevel = {
@@ -70,7 +85,7 @@ describe('stack', () => {
}
};
const stackProps = stack(spec.mark, spec.encoding, undefined);
- expect(stackProps.fieldChannel).toBe('x');
+ expect(stackProps.fieldChannel).toBe(X);
}
});