Reputation: 2451
I started to think a bit about animated vega-lite charts after Davide (Vega Master) helped me out with my vega-lite clock a few days ago.
Vega-Lite Clock (Using a Timer in Vega-Lite)
Have a test of this see what you think. With this method I am rotating between 4 different charts every 15 seconds. This can open up for many possibilities for the vega-lite community I believe:)
Please make some comments how we can improve this.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "data/weather.csv"},
"usermeta": {"embedOptions": {"renderer": "svg"}},
"params": [
{
"name": "time",
"on": [{"events": {"type": "timer", "throttle": 1000}, "update": "now()"}]
}
],
"transform": [
{"filter": "datum.location === 'Seattle'"},
{"calculate": "toNumber(timeFormat(time, '%S'))", "as": "curr_sec"},
{"calculate": "datum.curr_sec >= 0 && datum.curr_sec < 15 ? datum.weather : ' '", "as": "weather_1"},
{"calculate": "datum.curr_sec >= 15 && datum.curr_sec < 30 ? datum.weather : ' '", "as": "weather_2"},
{"calculate": "datum.curr_sec >= 30 && datum.curr_sec < 45 ? datum.weather : ' '", "as": "weather_3"},
{"calculate": "datum.curr_sec >= 45 && datum.curr_sec < 60 ? datum.weather : ' '", "as": "weather_4"}
],
"title": {"text": {"expr": "'Chart updates every 15 sec: (' + parseFloat(data('source_0')[0].curr_sec) + ')'"}},
"layer": [
{
"width": {"step": 25},
"mark": {"type": "bar"},
"encoding": {
"x": {
"timeUnit": "month",
"field": "date",
"type": "ordinal",
"title": "Month of the year"
},
"y": {"aggregate": "count", "type": "quantitative"},
"color": {
"field": "weather_1",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"," "],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd","transparent"]
},
"title": "Weather type"
}
}
},
{
"width": {"step": 25},
"mark": {"type": "area"},
"encoding": {
"x": {
"timeUnit": "month",
"field": "date",
"type": "ordinal",
"title": "Month of the year"
},
"y": {"aggregate": "count", "type": "quantitative"},
"color": {
"field": "weather_2",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"," "],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd","transparent"]
},
"title": "Weather type"
}
}
},
{
"width": {"step": 25},
"mark": {"type": "line"},
"encoding": {
"x": {
"timeUnit": "month",
"field": "date",
"type": "ordinal",
"title": "Month of the year"
},
"y": {"aggregate": "count", "type": "quantitative"},
"color": {
"field": "weather_3",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"," "],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd","transparent"]
},
"title": "Weather type"
}
}
},
{
"width": {"step": 4},
"mark": {"type": "bar"},
"encoding": {
"x": {
"timeUnit": "month",
"field": "date",
"type": "ordinal",
"title": "Month of the year",
"sort": {"field": "weather_4"}
},
"y": {"aggregate": "count", "type": "quantitative"},
"color": {
"field": "weather_4",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"," "],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd","transparent"]
},
"title": "Weather type"
},
"xOffset": {"field": "weather_4"}
}
}
]
}
Here is a second example where the chart switches from a filter of year = 2012, 2013, 2014, and finally 2015 every 15 seconds.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "data/weather.csv"},
"usermeta": {"embedOptions": {"renderer": "svg"}},
"params": [
{
"name": "time",
"on": [{"events": {"type": "timer", "throttle": 1000}, "update": "now()"}]
}
],
"transform": [
{"filter": "datum.location === 'Seattle'"},
{"calculate": "toNumber(timeFormat(time, '%S'))", "as": "curr_sec"},
{
"calculate": "datum.curr_sec >= 0 && datum.curr_sec < 15 ? 2012 : 0",
"as": "year_1"
},
{
"calculate": "datum.curr_sec >= 15 && datum.curr_sec < 30 ? 2013 : 0",
"as": "year_2"
},
{
"calculate": "datum.curr_sec >= 30 && datum.curr_sec < 45 ? 2014 : 0",
"as": "year_3"
},
{
"calculate": "datum.curr_sec >= 45 && datum.curr_sec < 60 ? 2015 : 0",
"as": "year_4"
}
],
"width": {"step": 25},
"title": {
"text": {
"expr": "'Seattle weather during: ' + ((data('source_0')[0].year_1 || 0) === 2012 ? '2012' : (data('source_0')[0].year_2 || 0) === 2013 ? '2013' : (data('source_0')[0].year_3 || 0) == 2014 ? '2014' : (data('source_0')[0].year_4 || 0) == 2015 ? '2015' : '2000') + ' - (Updates in: '+ (((data('source_0')[0].year_1 || 0) === 2012 ? 15 : (data('source_0')[0].year_2 || 0) === 2013 ? 30 : (data('source_0')[0].year_3 || 0) == 2014 ? 45 : (data('source_0')[0].year_4 || 0) == 2015 ? 60 : 0)- (data('source_0')[0].curr_sec)) + ')'"
}
},
"layer": [
{
"transform": [
{"filter": "parseFloat(timeFormat(datum.date, '%Y')) === datum.year_1"}
],
"mark": {"type": "bar"},
"encoding": {
"x": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"title": null,
"axis": {
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') : '']"
}
},
"y": {"aggregate": "count", "type": "quantitative", "title": "Count"},
"color": {
"field": "weather",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd"]
},
"title": "weather"
}
}
},
{
"transform": [
{"filter": "parseFloat(timeFormat(datum.date, '%Y')) === datum.year_2"}
],
"mark": {"type": "bar"},
"encoding": {
"x": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"title": null,
"axis": {
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') : '']"
}
},
"y": {"aggregate": "count", "type": "quantitative", "title": "Count"},
"color": {
"field": "weather",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd"]
},
"title": "weather"
}
}
},
{
"transform": [
{"filter": "parseFloat(timeFormat(datum.date, '%Y')) === datum.year_3"}
],
"mark": {"type": "bar"},
"encoding": {
"x": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"title": null,
"axis": {
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') : '']"
}
},
"y": {"aggregate": "count", "type": "quantitative", "title": "Count"},
"color": {
"field": "weather",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd"]
},
"title": "weather"
}
}
},
{
"transform": [
{"filter": "parseFloat(timeFormat(datum.date, '%Y')) === datum.year_4"}
],
"mark": {"type": "bar"},
"encoding": {
"x": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"title": null,
"axis": {
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') : '']"
}
},
"y": {"aggregate": "count", "type": "quantitative", "title": "Count"},
"color": {
"field": "weather",
"type": "nominal",
"scale": {
"domain": ["sun", "fog", "drizzle", "rain", "snow"],
"range": ["#e7ba52", "#c7c7c7", "#aec7e8", "#1f77b4", "#9467bd"]
},
"title": "weather"
}
}
}
]
}
Here is another example where the line chart extends over a rolling 12 month window.
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"data": {"url": "data/weather.csv"},
"usermeta": {"embedOptions": {"renderer": "svg"}},
"width": 500,
"height": 200,
"params": [
{
"name": "time",
"on": [{"events": {"type": "timer", "throttle": 1000}, "update": "now()"}]
}
],
"transform": [
{"filter": "datum.location === 'Seattle'"},
{"filter": "datum.weather === 'rain'"},
{"calculate": "toNumber(201200)", "as": "start_date1"},
{"calculate": "toNumber(timeFormat(time, '%S')) % 24", "as": "sec"},
{"calculate": "datum.sec % 24", "as": "curr_sec_temp"},
{
"calculate": "datum.curr_sec_temp < 12 ? (datum.curr_sec_temp) : datum.curr_sec_temp < 24 ? (datum.curr_sec_temp-12) +100 : datum.curr_sec_temp < 36 ? (datum.curr_sec_temp-24) +200 : datum.curr_sec_temp < 48 ? (datum.curr_sec_temp-36) +300 : 312",
"as": "curr_sec_start"
},
{"calculate": "toNumber(datum.curr_sec_start) + 100", "as": "curr_sec_end"},
{"calculate": "toNumber(timeFormat(datum.date, '%Y%m'))", "as": "date_num"},
{
"calculate": "toNumber(datum.start_date1) + toNumber(datum.curr_sec_start)",
"as": "start_date_num"
},
{
"calculate": "toNumber(datum.start_date1)+ toNumber(datum.curr_sec_end)",
"as": "end_date_num"
},
{
"filter": "datum.date_num >= datum.start_date_num && datum.date_num <= datum.end_date_num"
},
{"calculate": "datum.curr_sec_temp <= 24 ? 1 : 0", "as": "counter"}
],
"layer": [
{
"mark": {"type": "area"},
"encoding": {
"x": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"title": null,
"axis": {
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') :'']"
}
},
"y": {
"aggregate": "sum",
"field": "counter",
"type": "quantitative",
"sort": "x",
"scale": {"domain": [0, 30]}
},
"size": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"legend": null
},
"color": {"value": "aliceblue"}
}
},
{
"mark": {"type": "trail", "size": 2},
"encoding": {
"x": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"title": null,
"axis": {
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%m') == '01' ? timeFormat(datum.value, '%Y') :'']"
}
},
"y": {
"aggregate": "sum",
"field": "counter",
"type": "quantitative",
"title": "Days",
"sort": "x",
"scale": {"domain": [0, 30]}
},
"size": {
"timeUnit": "yearmonth",
"field": "date",
"type": "ordinal",
"legend": null
},
"color": {"value": "#1f77b4"}
}
}
]
}
Happy Charting!
Adam (APB Reports)
Upvotes: 0
Views: 229