I have a Vega visualization that displays data in a table built using rect and text marks:
I can define the x_step
signal to define the width in pixel of each column (but with the same value for all columns). Now, since my first and third column have much smaller text content than the second, I'd like to use one column width for the second column and another for the first and third. I cannot find a way to do it since it seems I cannot use datum
in signals.
Please note that I want to change the axis width, not only the rect width.
Also, I need to use Vega v5.
Here's my JSON spec:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"autosize": "none",
"background": "white",
"padding": {"top": 60},
"style": "cell",
"data": [
{
"name": "source_0",
"values": [
{
"date": "2025-03-24T12:00:00+0100",
"key": "2210"
},
{
"date": "2025-03-24T13:00:00+0100",
"key": "2211"
},
{
"date": "2025-03-24T12:30:00+0100",
"key": "2212"
},
{
"date": "2025-03-24T12:50:00+0100",
"key": "2213"
}
],
"transform": [
{
"type": "formula",
"expr": "(now() - time(datum.date)) / 1000",
"as": "delta_sec"
},
{
"type": "formula",
"expr": "if(datum.delta_sec >= 31536000, floor(datum.delta_sec / 31536000) + \" year\", if(datum.delta_sec >= 2592000, floor(datum.delta_sec / 2592000) + \" month\", if(datum.delta_sec >= 86400, floor(datum.delta_sec / 86400) + \" day\", if(datum.delta_sec >= 3600, floor(datum.delta_sec / 3600) + \" hour\", if(datum.delta_sec >= 60, floor(datum.delta_sec / 60) + \" minute\", floor(datum.delta_sec) + \" second\")))))",
"as": "delta_str"
},
{
"type": "formula",
"expr": "if(parseInt(split(datum.delta_str, \" \", 1)[0]) > 1, datum.delta_str + \"s\", datum.delta_str)",
"as": "Ago"
},
{"type": "formula", "expr": "datum.delta_sec < 3600", "as": "color"},
{
"type": "window",
"params": [null],
"as": ["row_num"],
"ops": ["row_number"],
"fields": [null],
"sort": {"field": [], "order": []}
},
{"type": "formula", "expr": "datum.key", "as": "Key"},
{
"type": "formula",
"expr": "datum.date",
"as": "Date"
},
{
"type": "fold",
"fields": ["Key", "Date", "Ago"],
"as": ["key", "value"]
},
{
"type": "formula",
"expr": "datum[\"key\"]===\"Key\" ? 0 : datum[\"key\"]===\"Date\" ? 1 : datum[\"key\"]===\"Ago\" ? 2 : 3",
"as": "x_key_sort_index"
}
]
}
],
"signals": [
{"name": "x_step", "value": 250},
{"name": "width", "update": "containerSize()[0]"},
{"name": "y_step", "value": 20},
{"name": "height", "update": "containerSize()[1]"}
],
"marks": [
{
"name": "layer_0_marks",
"type": "rect",
"style": ["rect"],
"from": {"data": "source_0"},
"encode": {
"update": {
"fill": {"scale": "color", "field": "color"},
"description": {
"signal": "\"row_num: \" + (isValid(datum[\"row_num\"]) ? datum[\"row_num\"] : \"\"+datum[\"row_num\"]) + \"; key: \" + (isValid(datum[\"key\"]) ? datum[\"key\"] : \"\"+datum[\"key\"]) + \"; color: \" + (isValid(datum[\"color\"]) ? datum[\"color\"] : \"\"+datum[\"color\"])"
},
"x": {"scale": "x", "field": "key"},
"width": {"scale": "x", "band": 1},
"y": {"scale": "y", "field": "row_num"},
"height": {"scale": "y", "band": 1}
}
}
},
{
"name": "layer_1_marks",
"type": "text",
"style": ["text"],
"from": {"data": "source_0"},
"encode": {
"update": {
"fontSize": {"value": 12},
"fill": {"value": "#eeeeee"},
"description": {
"signal": "\"row_num: \" + (isValid(datum[\"row_num\"]) ? datum[\"row_num\"] : \"\"+datum[\"row_num\"]) + \"; key: \" + (isValid(datum[\"key\"]) ? datum[\"key\"] : \"\"+datum[\"key\"]) + \"; value: \" + (isValid(datum[\"value\"]) ? datum[\"value\"] : \"\"+datum[\"value\"])"
},
"x": {"scale": "x", "field": "key", "band": 0.5},
"y": {"scale": "y", "field": "row_num", "band": 0.5},
"text": {
"signal": "isValid(datum[\"value\"]) ? datum[\"value\"] : \"\"+datum[\"value\"]"
},
"align": {"value": "center"},
"baseline": {"value": "middle"}
}
}
}
],
"scales": [
{
"name": "x",
"type": "band",
"domain": {
"data": "source_0",
"field": "key",
"sort": {"op": "min", "field": "x_key_sort_index"}
},
"range": {"step": {"signal": "x_step"}},
"paddingInner": 0,
"paddingOuter": 0
},
{
"name": "y",
"type": "band",
"domain": {"data": "source_0", "field": "row_num", "sort": true},
"range": {"step": {"signal": "y_step"}},
"paddingInner": 0,
"paddingOuter": 0
},
{
"name": "color",
"type": "ordinal",
"domain": ["true", "false"],
"range": ["#19aa6e", "#788291"]
}
],
"axes": [
{
"scale": "x",
"orient": "top",
"gridScale": "y",
"grid": true,
"domain": false,
"labels": false,
"aria": false,
"maxExtent": 0,
"minExtent": 0,
"ticks": false,
"zindex": 1
},
{
"scale": "x",
"orient": "top",
"grid": false,
"labelAngle": 0,
"labelFontSize": 15,
"ticks": false,
"labelBaseline": "bottom",
"zindex": 1
}
],
"legends": [
{
"labelFontSize": 12,
"labelLimit": 300,
"orient": "top",
"fill": "color",
"direction": "horizontal",
"symbolType": "square",
"encode": {
"labels": {
"update": {
"text": {
"signal": "if(datum.value == 'true', 'Less than 60 min ago', 'More than 60 min ago')"
}
}
}
}
}
],
"config": {"axis": {"grid": true, "tickBand": "extent"}}
}
Here you go
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"autosize": "none",
"background": "white",
"width": 300,
"height": 100,
"padding": {"top": 60},
"data": [
{
"name": "source_0",
"values": [
{"date": "2025-03-24T12:00:00+0100", "key": "2210"},
{"date": "2025-03-24T13:00:00+0100", "key": "2211"},
{"date": "2025-03-24T12:30:00+0100", "key": "2212"},
{"date": "2025-03-24T12:50:00+0100", "key": "2213"}
],
"transform": [
{
"type": "formula",
"expr": "(now() - time(datum.date)) / 1000",
"as": "delta_sec"
},
{
"type": "formula",
"expr": "if(datum.delta_sec >= 31536000, floor(datum.delta_sec / 31536000) + \" year\", if(datum.delta_sec >= 2592000, floor(datum.delta_sec / 2592000) + \" month\", if(datum.delta_sec >= 86400, floor(datum.delta_sec / 86400) + \" day\", if(datum.delta_sec >= 3600, floor(datum.delta_sec / 3600) + \" hour\", if(datum.delta_sec >= 60, floor(datum.delta_sec / 60) + \" minute\", floor(datum.delta_sec) + \" second\")))))",
"as": "delta_str"
},
{
"type": "formula",
"expr": "if(parseInt(split(datum.delta_str, \" \", 1)[0]) > 1, datum.delta_str + \"s\", datum.delta_str)",
"as": "Ago"
},
{
"type": "formula",
"expr": "datum.delta_sec < 3600?'yes':'no'",
"as": "color"
}
]
}
],
"signals": [
{"name": "x_step", "value": 250},
{"name": "width", "update": "containerSize()[0]"},
{"name": "y_step", "value": 20},
{"name": "height", "update": "containerSize()[1]"}
],
"marks": [
{
"type": "group",
"name": "columnHolder",
"style": "cell",
"layout": {"padding": 0, "bounds": "flush", "align": "each"},
"encode": {
"enter": {
"x": {"signal": "0"},
"stroke": {"value": "transparent"},
"width": {"signal": "width"},
"height": {"signal": "height"}
}
},
"marks": [
{
"type": "group",
"name": "firstColumn",
"style": "cell",
"title": {
"text": "Key",
"anchor": "start",
"frame": "group",
"align": "left"
},
"encode": {
"enter": {
"stroke": {"value": "transparent"},
"width": {"value": 40},
"height": {"signal": "height"}
}
},
"marks": [
{
"type": "rect",
"clip": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"fill": {"scale": "color", "field": "color"},
"y": {"scale": "y", "field": "key", "band": 0},
"height": {"scale": "y", "band": 1},
"x": {"value": 0},
"width": {"value": 40}
}
}
},
{
"type": "text",
"style": "col",
"clip": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"fontSize": {"value": 12},
"fill": {"value": "#eeeeee"},
"y": {"scale": "y", "field": "key", "band": 0.5},
"text": {"field": "key"}
}
}
}
]
},
{
"type": "group",
"name": "secondColumn",
"style": "cell",
"title": {
"text": "Date",
"anchor": "start",
"frame": "group",
"align": "left"
},
"encode": {
"enter": {
"stroke": {"value": "transparent"},
"width": {"value": 180},
"height": {"signal": "height"}
}
},
"marks": [
{
"type": "rect",
"clip": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"fill": {"scale": "color", "field": "color"},
"y": {"scale": "y", "field": "key", "band": 0},
"height": {"scale": "y", "band": 1},
"x": {"value": 0},
"width": {"value": 180}
}
}
},
{
"type": "text",
"style": "col",
"clip": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"fontSize": {"value": 12},
"fill": {"value": "#eeeeee"},
"y": {"scale": "y", "field": "key", "band": 0.5},
"text": {"field": "date"}
}
}
}
]
},
{
"type": "group",
"name": "thirdColumn",
"style": "cell",
"title": {
"text": "Ago",
"anchor": "start",
"frame": "group",
"align": "left"
},
"encode": {
"enter": {
"stroke": {"value": "transparent"},
"width": {"value": 60},
"height": {"signal": "height"}
}
},
"marks": [
{
"type": "rect",
"clip": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"fill": {"scale": "color", "field": "color"},
"y": {"scale": "y", "field": "key", "band": 0},
"height": {"scale": "y", "band": 1},
"x": {"value": 0},
"width": {"value": 60}
}
}
},
{
"type": "text",
"style": "col",
"clip": true,
"from": {"data": "source_0"},
"encode": {
"update": {
"fontSize": {"value": 12},
"fill": {"value": "#eeeeee"},
"y": {"scale": "y", "field": "key", "band": 0.5},
"text": {"field": "Ago"}
}
}
}
]
}
]
}
],
"scales": [
{
"name": "y",
"type": "band",
"domain": {"data": "source_0", "field": "key", "sort": true},
"range": {"step": {"signal": "y_step"}},
"paddingInner": 0,
"paddingOuter": 0
},
{
"name": "color",
"type": "ordinal",
"domain": ["yes", "no"],
"range": ["#19aa6e", "#788291"]
}
],
"legends": [
{
"labelFontSize": 12,
"labelLimit": 300,
"orient": "top",
"fill": "color",
"direction": "horizontal",
"symbolType": "square",
"encode": {
"labels": {
"update": {
"text": {
"signal": "if(datum.value == 'true', 'Less than 60 min ago', 'More than 60 min ago')"
}
}
}
}
}
],
"config": {"axis": {"grid": true, "tickBand": "extent"}}
}