I would like to adjust the alignment of my charts so that it can look like the following image:
To be up to 220 characters, I ask another question: how to add a tendency on each bar chart just under each chart title ? It could be like : “XX%” with a triangle UP or Down with a conditional color for number & triangle ?
Thanks in advance
Here is my vega code :
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "4 graphiques identiques en grille",
"background": "white",
"padding": 5,
"data": [
{
"name": "source_0",
"values": [
{"a": "1", "b": 28},
{"a": "2", "b": 55},
{"a": "3", "b": 43},
{"a": "4", "b": 91},
{"a": "5", "b": 81},
{"a": "6", "b": 53},
{"a": "7", "b": 19},
{"a": "8", "b": 87},
{"a": "9", "b": 52}
],
"format": {}
},
{
"name": "source_1",
"values": [
{"a": "1", "b": -3},
{"a": "2", "b": -10},
{"a": "3", "b": 43},
{"a": "4", "b": 91},
{"a": "5", "b": 81},
{"a": "6", "b": 53},
{"a": "7", "b": 19},
{"a": "8", "b": -50},
{"a": "9", "b": 52}
]
},
{
"name": "source_2",
"values": [
{"a": "1", "b": -20},
{"a": "2", "b": -5},
{"a": "3", "b": -2},
{"a": "4", "b": -20},
{"a": "5", "b": -15},
{"a": "6", "b": -30},
{"a": "7", "b": -40},
{"a": "8", "b": -35},
{"a": "9", "b": -12}
]
},
{
"name": "data_0",
"source": "source_0",
"transform": [
{
"type": "stack",
"groupby": ["a"],
"field": "b",
"sort": {"field": [], "order": []},
"as": ["b_start", "b_end"],
"offset": "zero"
},
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
}
]
},
{
"name": "data_1",
"source": "source_1",
"transform": [
{
"type": "stack",
"groupby": ["a"],
"field": "b",
"sort": {"field": [], "order": []},
"as": ["b_start", "b_end"],
"offset": "zero"
},
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
}
]
},
{
"name": "data_2",
"source": "source_2",
"transform": [
{
"type": "stack",
"groupby": ["a"],
"field": "b",
"sort": {"field": [], "order": []},
"as": ["b_start", "b_end"],
"offset": "zero"
},
{
"type": "filter",
"expr": "isValid(datum[\"b\"]) && isFinite(+datum[\"b\"])"
}
]
}
],
"signals": [
{"name": "childHeight", "value": 150},
{"name": "concat_0_concat_0_x_step", "value": 20},
{
"name": "concat_0_concat_0_width",
"update": "bandspace(domain('concat_0_concat_0_x').length, 0.1, 0.05) * concat_0_concat_0_x_step"
},
{"name": "concat_0_concat_1_x_step", "value": 20},
{
"name": "concat_0_concat_1_width",
"update": "bandspace(domain('concat_0_concat_1_x').length, 0.1, 0.05) * concat_0_concat_1_x_step"
},
{"name": "concat_1_concat_0_x_step", "value": 20},
{
"name": "concat_1_concat_0_width",
"update": "bandspace(domain('concat_1_concat_0_x').length, 0.1, 0.05) * concat_1_concat_0_x_step"
},
{"name": "concat_1_concat_1_x_step", "value": 20},
{
"name": "concat_1_concat_1_width",
"update": "bandspace(domain('concat_1_concat_1_x').length, 0.1, 0.05) * concat_1_concat_1_x_step"
}
],
"layout": {"padding": 20, "columns": 1, "bounds": "full", "align": "each"},
"marks": [
{
"type": "group",
"name": "concat_0_group",
"layout": {"padding": 20, "bounds": "full", "align": "each"},
"marks": [
{
"type": "group",
"name": "concat_0_concat_0_group",
"title": {"text": "Graphe 1.1", "frame": "group"},
"style": "null",
"encode": {
"update": {
"width": {"signal": "concat_0_concat_0_width"},
"height": {"signal": "childHeight"}
}
},
"marks": [
{
"name": "concat_0_concat_0_marks",
"type": "rect",
"style": ["bar"],
"from": {"data": "data_0"},
"encode": {
"update": {
"fill": [
{"test": "datum.b < 0", "value": "red"},
{"value": "green"}
],
"ariaRoleDescription": {"value": "bar"},
"description": {
"signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
},
"x": {"scale": "concat_0_concat_0_x", "field": "a"},
"width": {
"signal": "max(0.25, bandwidth('concat_0_concat_0_x'))"
},
"y": {"scale": "concat_0_concat_0_y", "field": "b_end"},
"y2": {"scale": "concat_0_concat_0_y", "field": "b_start"}
}
}
}
],
"axes": [
{
"scale": "concat_0_concat_0_x",
"orient": "bottom",
"grid": false,
"domain": false,
"labelAngle": 0,
"ticks": false,
"labelBaseline": "top",
"zindex": 0
},
{
"scale": "concat_0_concat_0_y",
"orient": "left",
"grid": false,
"domain": false,
"labelAngle": 0,
"labels": false,
"ticks": false,
"labelAlign": "right",
"labelOverlap": true,
"tickCount": {"signal": "ceil(childHeight/40)"},
"zindex": 0
}
]
},
{
"type": "group",
"name": "concat_0_concat_1_group",
"title": {"text": "Graphe 1.2", "frame": "group"},
"style": "null",
"encode": {
"update": {
"width": {"signal": "concat_0_concat_1_width"},
"height": {"signal": "childHeight"}
}
},
"marks": [
{
"name": "concat_0_concat_1_marks",
"type": "rect",
"style": ["bar"],
"from": {"data": "data_0"},
"encode": {
"update": {
"fill": [
{"test": "datum.b < 0", "value": "red"},
{"value": "green"}
],
"ariaRoleDescription": {"value": "bar"},
"description": {
"signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
},
"x": {"scale": "concat_0_concat_1_x", "field": "a"},
"width": {
"signal": "max(0.25, bandwidth('concat_0_concat_1_x'))"
},
"y": {"scale": "concat_0_concat_1_y", "field": "b_end"},
"y2": {"scale": "concat_0_concat_1_y", "field": "b_start"}
}
}
}
],
"axes": [
{
"scale": "concat_0_concat_1_x",
"orient": "bottom",
"grid": false,
"domain": false,
"labelAngle": 0,
"ticks": false,
"labelBaseline": "top",
"zindex": 0
},
{
"scale": "concat_0_concat_1_y",
"orient": "left",
"grid": false,
"domain": false,
"labelAngle": 0,
"labels": false,
"ticks": false,
"labelAlign": "right",
"labelOverlap": true,
"tickCount": {"signal": "ceil(childHeight/40)"},
"zindex": 0
}
]
}
]
},
{
"type": "group",
"name": "concat_1_group",
"layout": {"padding": 20, "bounds": "full", "align": "each"},
"marks": [
{
"type": "group",
"name": "concat_1_concat_0_group",
"title": {"text": "Graphe 2.1", "frame": "group"},
"style": "null",
"encode": {
"update": {
"width": {"signal": "concat_1_concat_0_width"},
"height": {"signal": "childHeight"}
}
},
"marks": [
{
"name": "concat_1_concat_0_marks",
"type": "rect",
"style": ["bar"],
"from": {"data": "data_1"},
"encode": {
"update": {
"fill": [
{"test": "datum.b < 0", "value": "red"},
{"value": "green"}
],
"ariaRoleDescription": {"value": "bar"},
"description": {
"signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
},
"x": {"scale": "concat_1_concat_0_x", "field": "a"},
"width": {
"signal": "max(0.25, bandwidth('concat_1_concat_0_x'))"
},
"y": {"scale": "concat_1_concat_0_y", "field": "b_end"},
"y2": {"scale": "concat_1_concat_0_y", "field": "b_start"}
}
}
}
],
"axes": [
{
"scale": "concat_1_concat_0_x",
"orient": "bottom",
"grid": false,
"domain": false,
"labelAngle": 0,
"ticks": false,
"labelBaseline": "top",
"zindex": 0
},
{
"scale": "concat_1_concat_0_y",
"orient": "left",
"grid": false,
"domain": false,
"labelAngle": 0,
"labels": false,
"ticks": false,
"labelAlign": "right",
"labelOverlap": true,
"tickCount": {"signal": "ceil(childHeight/40)"},
"zindex": 0
}
]
},
{
"type": "group",
"name": "concat_1_concat_1_group",
"title": {"text": "Graphe 2.2", "frame": "group"},
"style": "null",
"encode": {
"update": {
"width": {"signal": "concat_1_concat_1_width"},
"height": {"signal": "childHeight"}
}
},
"marks": [
{
"name": "concat_1_concat_1_marks",
"type": "rect",
"style": ["bar"],
"from": {"data": "data_2"},
"encode": {
"update": {
"fill": [
{"test": "datum.b < 0", "value": "red"},
{"value": "green"}
],
"ariaRoleDescription": {"value": "bar"},
"description": {
"signal": "\"a: \" + (isValid(datum[\"a\"]) ? datum[\"a\"] : \"\"+datum[\"a\"]) + \"; b: \" + (format(datum[\"b\"], \"\"))"
},
"x": {"scale": "concat_1_concat_1_x", "field": "a"},
"width": {
"signal": "max(0.25, bandwidth('concat_1_concat_1_x'))"
},
"y": {"scale": "concat_1_concat_1_y", "field": "b_end"},
"y2": {"scale": "concat_1_concat_1_y", "field": "b_start"}
}
}
}
],
"axes": [
{
"scale": "concat_1_concat_1_x",
"orient": "bottom",
"grid": false,
"domain": false,
"labelAngle": 0,
"ticks": false,
"labelBaseline": "top",
"zindex": 0
},
{
"scale": "concat_1_concat_1_y",
"orient": "left",
"grid": false,
"domain": false,
"labelAngle": 0,
"labels": false,
"ticks": false,
"labelAlign": "right",
"labelOverlap": true,
"tickCount": {"signal": "ceil(childHeight/40)"},
"zindex": 0
}
]
}
]
}
],
"scales": [
{
"name": "concat_0_concat_0_x",
"type": "band",
"domain": {"data": "data_0", "field": "a", "sort": true},
"range": {"step": {"signal": "concat_0_concat_0_x_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
},
{
"name": "concat_0_concat_0_y",
"type": "linear",
"domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "childHeight"}, 0],
"nice": true,
"zero": true
},
{
"name": "concat_0_concat_1_x",
"type": "band",
"domain": {"data": "data_0", "field": "a", "sort": true},
"range": {"step": {"signal": "concat_0_concat_1_x_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
},
{
"name": "concat_0_concat_1_y",
"type": "linear",
"domain": {"data": "data_0", "fields": ["b_start", "b_end"]},
"range": [{"signal": "childHeight"}, 0],
"nice": true,
"zero": true
},
{
"name": "concat_1_concat_0_x",
"type": "band",
"domain": {"data": "data_1", "field": "a", "sort": true},
"range": {"step": {"signal": "concat_1_concat_0_x_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
},
{
"name": "concat_1_concat_0_y",
"type": "linear",
"domain": {"data": "data_1", "fields": ["b_start", "b_end"]},
"range": [{"signal": "childHeight"}, 0],
"nice": true,
"zero": true
},
{
"name": "concat_1_concat_1_x",
"type": "band",
"domain": {"data": "data_2", "field": "a", "sort": true},
"range": {"step": {"signal": "concat_1_concat_1_x_step"}},
"paddingInner": 0.1,
"paddingOuter": 0.05
},
{
"name": "concat_1_concat_1_y",
"type": "linear",
"domain": {"data": "data_2", "fields": ["b_start", "b_end"]},
"range": [{"signal": "childHeight"}, 0],
"nice": true,
"zero": true
}
]
}
It is not straight forward and would make the scale of each chart different so you could no longer compare across charts. 1.1 and 1.2 currently have the same data but if they did not and you wanted the max to finish at the same point, they would be using different scales which means they could not be compared to one another. Perhaps a percentage based scale would do it but even then, the chart would be misleading.
Can you clarify the requirement as I don’t quite understand?
Hi Davide, i would like to align the max bars of each chart to the black line (whatever the datas) included the bottom line of the chart 2.2 (TOP 2.1 & 2.2 are not aligned) : Is that much clearer ?
I think I understand but it is not straight forward and would make the scale of each chart different so you could no longer compare across charts. 1.1 and 1.2 currently have the same data but if they did not and you wanted the max to finish at the same point, they would be using different scales which means they could not be compared to one another. Perhaps a percentage based scale would do it but even then, the chart would be misleading.
OK then, i drop this question. Do you need me to delete this post ?
I’ll just add my comment as the answer and you can mark as complete in case it helps anyone else.