Is it possible in vega or vega lite to create bar chart that has a fixed gradient across the entire chart, rather than a seperate gradient for each bar?
I have tried to use a gradient color/fill on the mark but it creates a new gradient for each bar:
Here’s the code i’ve tried in the Vega Editor
I think this is quite difficult given how gradients are created. Here is a hacky way of drawing full bars and then white bars on top to achieve the desired outcome. Grid lines won’t be the same due to zindex issue but it might be a good enough solution for you.
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"background": "white",
"padding": 5,
"height": 200,
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{"date": "2024-08-25", "views": 30},
{"date": "2024-08-26", "views": 7},
{"date": "2024-08-27", "views": 12},
{"date": "2024-08-28", "views": 15},
{"date": "2024-08-29", "views": 8},
{"date": "2024-08-30", "views": 2},
{"date": "2024-08-31", "views": 28},
{"date": "2024-09-01", "views": 6},
{"date": "2024-09-02", "views": 16}
]
},
{
"name": "data_0",
"source": "source_0",
"transform": [
{"type": "formula", "expr": "toDate(datum["date"])", "as": "date"},
{
"field": "date",
"type": "timeunit",
"units": ["year", "month", "date"],
"as": ["yearmonthdate_date", "yearmonthdate_date_end"]
},
{
"type": "stack",
"groupby": ["yearmonthdate_date"],
"field": "views",
"sort": {"field": [], "order": []},
"as": ["views_start", "views_end"],
"offset": "zero"
},
{
"type": "filter",
"expr": "isValid(datum["views"]) && isFinite(+datum["views"])"
},
{"type": "extent", "field": "views", "signal": "extent"}
]
}
],
"signals": [
{"name": "x_step", "value": 20},
{
"name": "width",
"update": "bandspace(domain('x').length, 0.1, 0.05) * x_step"
}
],
"marks": [
{
"name": "marks", "zindex":0,
"type": "rect",
"style": ["bar"],
"from": {"data": "data_0"},
"encode": {
"update": {
"fill": {"signal": "gradient('color', [0,0], [0,1])"},
"x": {"scale": "x", "field": "yearmonthdate_date"},
"width": {"signal": "max(0.25, bandwidth('x'))"},
"y": {"signal": "scale('y', extent[1])"},
"y2": {"scale": "y", "field": "views_start"},
}
}
},
{
"name": "marks2","zindex":1,
"type": "rect",
"style": ["bar"],
"from": {"data": "data_0"},
"encode": {
"update": {
"fill": {"signal": "'white'"},
"x": {"scale": "x", "field": "yearmonthdate_date"},
"width": {"signal": "max(0.25, bandwidth('x'))"},
"y": {"signal": "scale('y', datum.views)"},
"y2": {"signal": "scale('y', extent[1])"},
}
}
}
],
"scales": [
{
"name": "x",
"type": "band",
"domain": {"data": "data_0", "field": "yearmonthdate_date", "sort": true},
"range": {"step": {"signal": "x_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
},
{
"name": "y",
"type": "linear",
"domain": {"data": "data_0", "fields": ["views_start", "views_end"]},
"range": [{"signal": "height"}, 0],
"nice": true,
"zero": true
},
{
"name": "color",
"type": "sequential",
"range": [
"#002C41",
"#35406F",
"#834886",
"#CE4D7C",
"#FC6B55",
"#FFA516"
]
}
],
"axes": [
{
"scale": "y",
"orient": "left",
"gridScale": "x",
"grid": false,
"tickCount": {"signal": "ceil(height/40)"},
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false
},
{
"scale": "x",
"orient": "bottom",
"grid": false,
"format": "%m/%d",
"labelBound": true,
"formatType": "time",
"labelOverlap": true,
"tickMinStep": {
"signal": "datetime(2001, 0, 2, 0, 0, 0, 0) - datetime(2001, 0, 1, 0, 0, 0, 0)"
},
"zindex": 0
},
{
"scale": "y",
"orient": "left",
"grid": false,
"labelOverlap": true,
"tickCount": {"signal": "ceil(height/40)"},
"zindex": 0
}
]
}