I want to represent two rows in the axis of a graph. The two rows represent month and year respectively.
For the above plot , we use a conditional statement to display year only if the current month is jan, but this logic works well in this plot. But this fails if the plot is rendering only say, Feb, Apr, Jun etc, then the year will not be displayed at all. I wanted a generic solution to display year only on the first valid occurance be it Jan or Feb etc.
The above can be found in vegalite editor
I had no luck with Temporal labelExpr using H (hour), M (minutes) etc In this example I set the date to either 1 or 2 and use that logic in the labelExpr.
Let me know if this could be a possible solution for you. I have added lots of dynamic features to show that in action too.
Also added a trick I like to use so tooltip works everywhere. I set the chart to Area instead of line..
{
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": "Line chart with conditional axis ticks, labels, and grid.",
"data": {"url": "data/stocks.csv"},
"transform": [
{"filter": "datum.symbol==='GOOG'"},
{"filter": {"field": "date", "timeUnit": "year", "range": [2006, 2007]}},
{
"filter": {
"field": "date",
"timeUnit": "yearmonthdate",
"gte": "2006-03-01"
}
},
{"calculate": "timeFormat(datum.date, '%y%m')", "as": "YM"},
{"calculate": "timeFormat(datum.date, '%m')", "as": "M"},
{
"joinaggregate": [{"op": "min", "field": "date", "as": "firstDate"}],
"groupby": ["symbol"]
},
{
"calculate": "datetime(timeFormat(datum.firstDate, '%y%m') == datum.YM || datum.M == '01' ? timeFormat(datum.date, '%Y-%m-' + '01') : timeFormat(datum.date, '%Y-%m-' + '02'))",
"as": "formattedDate"
}
],
"width": 700,
"mark": {
"type": "area",
"color": "transparent",
"line": {"color": "#0564C8"}
},
"encoding": {
"tooltip": {
"field": "formattedDate",
"type": "temporal",
"timeUnit": "utcyearmonth"
},
"x": {
"field": "formattedDate",
"type": "ordinal",
"timeUnit": "utcyearmonthdate",
"bandPosition": 0,
"axis": {
"title": "",
"tickCount": 12,
"format": "%Y-%m-%d",
"labelAlign": "left",
"labelExpr": "[timeFormat(datum.value, '%b'), timeFormat(datum.value, '%d') == '01' ? timeFormat(datum.value, '%Y') : '']",
"labelOffset": 4,
"grid": true,
"labelPadding": {
"expr": "timeFormat(datum.value, '%d') == '01' ? -26:-11"
},
"tickSize": {"expr": "timeFormat(datum.value, '%d') == '01' ? 30:15"},
"gridDash": {
"expr": "timeFormat(datum.value, '%d') == '01' ? []:[2,2]"
},
"tickDash": {
"expr": "timeFormat(datum.value, '%d') == '01' ? []:[2,2]"
},
"tickColor": {
"expr": "timeFormat(datum.value, '%d') == '01' ? '#0564C8':'silver'"
},
"gridColor": {
"expr": "timeFormat(datum.value, '%d') == '01' ? '#0564C8':'silver'"
}
}
},
"y": {"field": "price", "type": "quantitative", "axis": {"grid": false}}
},
"config": {"axis": {"domainColor": "#ddd", "tickColor": "#ddd"}}
}