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.