I'd like to adjust the amount of data shown on a chart based on the width of the chart. On mobile devices I'd like to show less data rather than showing a large amount of data in a compressed space.
Below is a spec that reproduces the problem I am encountering. It is a modified version of the "stocks" example. I added a "filteredStocks" dataset that filters the data based on the "minYear" signal which uses the width signal, and moved some of the mark properties inside of an "update". When the chart width is <= 250 then it will only show data from 2005 and greater. Otherwise it will show everything since 2000.
This works when I resize the chart after it has been rendered using view.width(<new width>).update().
But my problem is that when the chart is first rendered the "minYear" signal is not being evaluated. Instead the signal's "init" value is being used.
If you copy and paste the spec below into the Vega editor it will render with data starting from 2000 and the chart will be 500px wide. In your console window, type "ved.view.width(250).update()" and it will correctly resize and filter the data to show only 2005 and greater.
However, if you change the spec to have "width: 250" and parse the spec, the "minYear" signal isn't evaluated to have the value "2005". This causes the chart to show data starting from 2000. If you resize the chart to 500 and back to 250 using the view API, then it updates the "minYear" signal and renders it correctly.
Is this just a bug? Is there a way to force a signal to be evaluated when the chart is first being rendered? Or is there a better way to approach this?
Thanks.
{
"width": 500,
"height": 200,
"signals": [{
"name": "minYear",
"init": 2000,
"expr": "if(width <= 250, 2005, 2000)"
}],
"data": [
{
"name": "stocks",
"url": "data/stocks.csv",
"format": {"type": "csv", "parse": {"price":"number", "date":"date"}}
}, {
"name": "filteredStocks",
"source": "stocks",
"transform": [{
"type": "filter",
"test": "year(datum.date) >= minYear"
}]
}
],
"scales": [
{
"name": "x",
"type": "time",
"range": "width",
"domain": {"data": "filteredStocks", "field": "date"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"domain": {"data": "filteredStocks", "field": "price"}
},
{
"name": "color",
"type": "ordinal",
"domain": {"data": "filteredStocks", "field": "symbol"},
"range": "category10"
}
],
"axes": [
{"type": "x", "scale": "x", "tickSizeEnd": 0},
{"type": "y", "scale": "y"}
],
"marks": [
{
"type": "group",
"from": {
"data": "filteredStocks",
"transform": [{
"type": "facet", "groupby": ["symbol"]
}]
},
"marks": [
{
"type": "line",
"properties": {
"enter": {
"stroke": {"scale": "color", "field": "symbol"},
"strokeWidth": {"value": 2}
}, "update": {
"x": {"scale": "x", "field": "date"},
"y": {"scale": "y", "field": "price"}
}
}
},
{
"type": "text",
"from": {
"transform": [{"type": "filter", "test": "datum.date == 1267430400000"}]
},
"properties": {
"enter": {
"fill": {"scale": "color", "field": "symbol"},
"text": {"field": "symbol"},
"baseline": {"value": "middle"}
}, "update": {
"x": {"scale": "x", "field": "date", "offset": 2},
"y": {"scale": "y", "field": "price"}
}
}
}
]
}
]
}