我目前正在 Vega 中制作分组+堆叠柱形图,其中如果类别中的值是正数和负数,它们将堆叠在一列中,但如果类别中的值都是正数或都是负数,那么它们必须并排显示而不是堆叠显示。
有没有办法即使两个条上的数据都为零值仍然显示 y 轴线?
假设我仍然希望它显示最少 2 条网格线。请参阅随附的第二个屏幕截图以了解所需的结果。
1, 0.5, 0, -0.5, 1
谢谢。感谢您的帮助。下面是我目前在 Vega 中的实现。
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 700,
"height": 370,
"autosize": {"type": "fit", "contains": "padding"},
"padding": {"bottom": 2, "right": 9, "left": 5},
"config": {
"axis": {
"labelFont": "HelveticaNeueLTW01-55Roman",
"titleFont": "HelveticaNeueLTW01-55Roman"
}
},
"data": [
{
"name": "income_and_expenses",
"values": [
{"label": "2012", "value1": 0, "value2": 0},
{"label": "2013", "value1": 0, "value2": 0},
{"label": "2014", "value1": 0, "value2": 0},
{"label": "2015", "value1": 0, "value2": 0},
{"label": "2016", "value1": 0, "value2": 0},
{"label": "2017", "value1": 0, "value2": 0},
{"label": "2018", "value1": 0, "value2": 0},
{"label": "2019", "value1": 0, "value2": 0},
{"label": "2020", "value1": 0, "value2": 0},
{"label": "2021", "value1": 0, "value2": 0},
{"label": "2022", "value1": 0, "value2": 0},
{"label": "2023", "value1": 0, "value2": 0},
{"label": "2024", "value1": 0, "value2": 0}
],
"transform": [
{"type": "formula", "expr": "split(datum.label, ' ')", "as": "label"}
]
},
{
"name": "parsed",
"source": ["income_and_expenses"],
"transform": [
{
"type": "aggregate",
"fields": ["value1", "value1", "value2", "value2"],
"ops": ["min", "max", "min", "max"],
"as": ["min_value1", "max_value1", "min_value2", "max_value2"]
},
{
"type": "formula",
"expr": "datum.max_value1 > datum.max_value2 ? abs(datum.max_value1) : abs(datum.max_value2)",
"as": "mergedMax"
},
{
"type": "formula",
"expr": "datum.min_value1 < datum.min_value2 ? abs(datum.min_value1) : abs(datum.min_value2)",
"as": "mergedMin"
},
{
"type": "formula",
"expr": "datum.mergedMax > datum.mergedMin ? datum.mergedMax : datum.mergedMin",
"as": "max"
},
{"type": "formula", "expr": "-(datum.max)", "as": "min"}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"range": "width",
"domain": {"data": "income_and_expenses", "field": "label"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": true,
"domain": {"data": "parsed", "field": "limit"},
"domainMin": {"signal": "pluck(data('parsed'), 'min')"},
"domainMax": {"signal": "pluck(data('parsed'), 'max')"}
}
],
"axes": [
{
"orient": "bottom",
"scale": "x",
"zindex": 1,
"labelFontSize": 14,
"labelColor": "#85868C",
"labelAlign": "center",
"labelLineHeight": 19.6,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"domainWidth": 1,
"ticks": false,
"grid": true
},
{
"orient": "left",
"scale": "y",
"zindex": 0,
"labelFontSize": 14,
"labelColor": "#85868C",
"labelLineHeight": 19.6,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"grid": true,
"gridOpacity": 0.5,
"ticks": false,
"tickCount": 4,
"gridDash": {"signal": "datum.value == 0 ? [] : [4,4]"},
"encode": {
"labels": {
"update": {
"text": {
"signal": "if(abs(datum.value) >= 1e9, format(datum.value/1e9, '$,.1~f') + 'B', if(abs(datum.value) >= 1e6, format(datum.value/1e6, '$,.1~f') + 'M', if(abs(datum.value) >= 1e3, format(datum.value/1e3, '$,.1~f') + 'K', format(datum.value, '$,.2~f'))))"
}
}
}
}
}
],
"marks": [
{
"name": "income",
"type": "rect",
"from": {"data": "income_and_expenses"},
"encode": {
"enter": {
"x": {"scale": "x", "field": "label", "band": 0.34},
"width": {"value": 16},
"y": {"scale": "y", "field": "value1"},
"y2": {"scale": "y", "value": 0},
"fill": {"value": "#68abf2"},
"cornerRadiusTopLeft": {"signal": "datum.value1 > 0 ? '2' : '0'"},
"cornerRadiusTopRight": {"signal": "datum.value1 > 0 ? '2' : '0'"},
"cornerRadiusBottomLeft": {"signal": "datum.value1 > 0 ? '0' : '2'"},
"cornerRadiusBottomRight": {"signal": "datum.value1 > 0 ? '0' : '2'"}
}
}
},
{
"name": "expenses",
"type": "rect",
"from": {"data": "income_and_expenses"},
"encode": {
"enter": {
"x": {
"scale": "x",
"field": "label",
"band": 0.34,
"offset": {
"signal": "datum.value1 > 0 && datum.value2 > 0 || datum.value1 < 0 && datum.value2 < 0 ? 20 : 0"
}
},
"width": {"value": 16},
"y": {"scale": "y", "field": "value2"},
"y2": {"scale": "y", "value": 0},
"fill": {"value": "#f7615c"},
"cornerRadiusTopLeft": {"signal": "datum.value2 > 0 ? '2' : '0'"},
"cornerRadiusTopRight": {"signal": "datum.value2 > 0 ? '2' : '0'"},
"cornerRadiusBottomLeft": {"signal": "datum.value2 > 0 ? '0' : '2'"},
"cornerRadiusBottomRight": {"signal": "datum.value2 > 0 ? '0' : '2'"}
}
}
}
]
}
设置您的domainMin和domainMax:
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 700,
"height": 370,
"autosize": {"type": "fit", "contains": "padding"},
"padding": {"bottom": 2, "right": 9, "left": 5},
"config": {
"axis": {
"labelFont": "HelveticaNeueLTW01-55Roman",
"titleFont": "HelveticaNeueLTW01-55Roman"
}
},
"data": [
{
"name": "income_and_expenses",
"values": [
{"label": "2012", "value1": 0, "value2": 0},
{"label": "2013", "value1": 0, "value2": 0},
{"label": "2014", "value1": 0, "value2": 0},
{"label": "2015", "value1": 0, "value2": 0},
{"label": "2016", "value1": 0, "value2": 0},
{"label": "2017", "value1": 0, "value2": 0},
{"label": "2018", "value1": 0, "value2": 0},
{"label": "2019", "value1": 0, "value2": 0},
{"label": "2020", "value1": 0, "value2": 0},
{"label": "2021", "value1": 0, "value2": 0},
{"label": "2022", "value1": 0, "value2": 0},
{"label": "2023", "value1": 0, "value2": 0},
{"label": "2024", "value1": 0, "value2": 0}
],
"transform": [
{"type": "formula", "expr": "split(datum.label, ' ')", "as": "label"}
]
},
{
"name": "parsed",
"source": ["income_and_expenses"],
"transform": [
{
"type": "aggregate",
"fields": ["value1", "value1", "value2", "value2"],
"ops": ["min", "max", "min", "max"],
"as": ["min_value1", "max_value1", "min_value2", "max_value2"]
},
{
"type": "formula",
"expr": "datum.max_value1 > datum.max_value2 ? abs(datum.max_value1) : abs(datum.max_value2)",
"as": "mergedMax"
},
{
"type": "formula",
"expr": "datum.min_value1 < datum.min_value2 ? abs(datum.min_value1) : abs(datum.min_value2)",
"as": "mergedMin"
},
{
"type": "formula",
"expr": "datum.mergedMax > datum.mergedMin ? datum.mergedMax : datum.mergedMin",
"as": "max"
},
{"type": "formula", "expr": "-(datum.max)", "as": "min"}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"range": "width",
"domain": {"data": "income_and_expenses", "field": "label"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": true,
"domain": {"data": "parsed", "field": "limit"},
"domainMin": {"signal": "-1"},
"domainMax": {"signal": "1"}
}
],
"axes": [
{
"orient": "bottom",
"scale": "x",
"zindex": 1,
"labelFontSize": 14,
"labelColor": "#85868C",
"labelAlign": "center",
"labelLineHeight": 19.6,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"domainWidth": 1,
"ticks": false,
"grid": true
},
{
"orient": "left",
"scale": "y",
"zindex": 0,
"labelFontSize": 14,
"labelColor": "#85868C",
"labelLineHeight": 19.6,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"grid": true,
"gridOpacity": 0.5,
"ticks": false,
"tickCount": 4,
"gridDash": {"signal": "datum.value == 0 ? [] : [4,4]"},
"encode": {
"labels": {
"update": {
"text": {
"signal": "if(abs(datum.value) >= 1e9, format(datum.value/1e9, '$,.1~f') + 'B', if(abs(datum.value) >= 1e6, format(datum.value/1e6, '$,.1~f') + 'M', if(abs(datum.value) >= 1e3, format(datum.value/1e3, '$,.1~f') + 'K', format(datum.value, '$,.2~f'))))"
}
}
}
}
}
],
"marks": [
{
"name": "income",
"type": "rect",
"from": {"data": "income_and_expenses"},
"encode": {
"enter": {
"x": {"scale": "x", "field": "label", "band": 0.34},
"width": {"value": 16},
"y": {"scale": "y", "field": "value1"},
"y2": {"scale": "y", "value": 0},
"fill": {"value": "#68abf2"},
"cornerRadiusTopLeft": {"signal": "datum.value1 > 0 ? '2' : '0'"},
"cornerRadiusTopRight": {"signal": "datum.value1 > 0 ? '2' : '0'"},
"cornerRadiusBottomLeft": {"signal": "datum.value1 > 0 ? '0' : '2'"},
"cornerRadiusBottomRight": {"signal": "datum.value1 > 0 ? '0' : '2'"}
}
}
},
{
"name": "expenses",
"type": "rect",
"from": {"data": "income_and_expenses"},
"encode": {
"enter": {
"x": {
"scale": "x",
"field": "label",
"band": 0.34,
"offset": {
"signal": "datum.value1 > 0 && datum.value2 > 0 || datum.value1 < 0 && datum.value2 < 0 ? 20 : 0"
}
},
"width": {"value": 16},
"y": {"scale": "y", "field": "value2"},
"y2": {"scale": "y", "value": 0},
"fill": {"value": "#f7615c"},
"cornerRadiusTopLeft": {"signal": "datum.value2 > 0 ? '2' : '0'"},
"cornerRadiusTopRight": {"signal": "datum.value2 > 0 ? '2' : '0'"},
"cornerRadiusBottomLeft": {"signal": "datum.value2 > 0 ? '0' : '2'"},
"cornerRadiusBottomRight": {"signal": "datum.value2 > 0 ? '0' : '2'"}
}
}
}
]
}