我在 Vega 中制作了一个条形图,每个类别有两列。这些列可以有正值或负值。我已将tickCount设置为以下值:
tickCount: 4
,但根据数据,tickCount有时小于4。对于下面的示例数据,tickCount仅为2。我对 Vega 如何计算和显示 tickCount 感到很困惑。
这是预期的行为吗?无论传递的数据如何,图表的 tickCount 是否可能始终为 4?
这是当前输出,我预计有 4 个刻度计数,最小值为 -400,最大值为 400。
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 817,
"height": 278,
"autosize": {"type": "fit", "contains": "padding"},
"padding": {"bottom": 2, "right": 9, "left": 5},
"config": {
"axis": {
"labelFont": "HelveticaNeueLTW01-55Roman",
"titleFont": "HelveticaNeueLTW01-55Roman"
}
},
"data": [
{
"name": "capital_flows",
"values": [
{"label": "Aug 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Sep 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Oct 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Nov 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Dec 2023", "capital_inflow": 0, "capital_outflow": -317.18},
{"label": "Jan 2024", "capital_inflow": 0, "capital_outflow": -117.19},
{"label": "Feb 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Mar 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Apr 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "May 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Jun 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Jul 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Aug 2024", "capital_inflow": 0, "capital_outflow": 0}
],
"transform": [
{"type": "formula", "expr": "split(datum.label, ' ')", "as": "label"}
]
},
{
"name": "parsed",
"source": ["capital_flows"],
"transform": [
{
"type": "aggregate",
"fields": [
"capital_inflow",
"capital_inflow",
"capital_outflow",
"capital_outflow"
],
"ops": ["min", "max", "min", "max"],
"as": ["min_value1", "max_value1", "min_value2", "max_value2"]
},
{
"type": "formula",
"expr": "datum.max_value1 == 0 && datum.max_value2 == 0 ? 1 : datum.max_value1 > datum.max_value2 ? abs(datum.max_value1) : abs(datum.max_value2)",
"as": "mergedMax"
},
{
"type": "formula",
"expr": "datum.min_value1 == 0 && datum.min_value2 == 0 ? -1 : 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": "capital_flows", "field": "label"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": false,
"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": 12,
"labelColor": "#85868C",
"labelAlign": "center",
"labelLineHeight": 16.8,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"domainWidth": 1,
"ticks": false
},
{
"orient": "left",
"scale": "y",
"zindex": 0,
"labelFontSize": 12,
"labelColor": "#85868C",
"labelLineHeight": 16.8,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"grid": true,
"gridOpacity": 0.5,
"ticks": false,
"tickCount": 4,
"gridDash": {"signal": "datum.value == 0 ? [0,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": "inflow",
"type": "rect",
"from": {"data": "capital_flows"},
"encode": {
"enter": {
"xc": {"scale": "x", "field": "label", "band": 0.5},
"width": {"value": 14},
"y": {"scale": "y", "field": "capital_inflow"},
"y2": {
"scale": "y",
"value": 0,
"offset": {"signal": "datum.capital_inflow < 0 ? 1.5: 0"}
},
"fill": {"value": "#68c487"},
"cornerRadiusTopLeft": {
"signal": "datum.capital_inflow > 0 ? '1' : '0'"
},
"cornerRadiusTopRight": {
"signal": "datum.capital_inflow > 0 ? '1' : '0'"
},
"cornerRadiusBottomLeft": {
"signal": "datum.capital_inflow > 0 ? '0' : '1'"
},
"cornerRadiusBottomRight": {
"signal": "datum.capital_inflow > 0 ? '0' : '1'"
},
"stroke": {"signal": "datum.capital_inflow !== 0 ? '#68c487': null"},
"strokeWidth": {"value": 1.5},
"fillOpacity": {"signal": "datum.capital_inflow !== 0 ? 1 : 0"}
}
}
},
{
"name": "outflow",
"type": "rect",
"from": {"data": "capital_flows"},
"encode": {
"enter": {
"xc": {"scale": "x", "field": "label", "band": 0.5, "offset": 17},
"width": {"value": 14},
"y": {"scale": "y", "field": "capital_outflow"},
"y2": {
"scale": "y",
"value": 0,
"offset": {"signal": "datum.capital_outflow < 0 ? 1.5: 0"}
},
"fill": {"value": "#FFB066"},
"cornerRadiusTopLeft": {
"signal": "datum.capital_outflow > 0 ? '1' : '0'"
},
"cornerRadiusTopRight": {
"signal": "datum.capital_outflow > 0 ? '1' : '0'"
},
"cornerRadiusBottomLeft": {
"signal": "datum.capital_outflow > 0 ? '0' : '1'"
},
"cornerRadiusBottomRight": {
"signal": "datum.capital_outflow > 0 ? '0' : '1'"
},
"stroke": {"signal": "datum.capital_outflow !== 0 ? '#FFB066': null"},
"strokeWidth": {"value": 1.5},
"fillOpacity": {"signal": "datum.capital_outflow !== 0 ? 1 : 0"}
}
}
}
]
}
tickCount 使用一些内部逻辑和启发式方法,因此不幸的是,它不能总是保证您会看到指定的刻度数。如果您想完全控制,您可以使用values属性来控制它。在您的情况下,您将通过使用domainMin(-317)和domainMax(317)来覆盖。例如:
由以下人员制作。您需要确保您的域最小值和最大值的计算是适当的。
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 817,
"height": 278,
"autosize": {"type": "fit", "contains": "padding"},
"padding": {"bottom": 2, "right": 9, "left": 5},
"config": {
"axis": {
"labelFont": "HelveticaNeueLTW01-55Roman",
"titleFont": "HelveticaNeueLTW01-55Roman"
}
},
"data": [
{
"name": "capital_flows",
"values": [
{"label": "Aug 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Sep 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Oct 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Nov 2023", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Dec 2023", "capital_inflow": 0, "capital_outflow": -317.18},
{"label": "Jan 2024", "capital_inflow": 0, "capital_outflow": -117.19},
{"label": "Feb 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Mar 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Apr 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "May 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Jun 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Jul 2024", "capital_inflow": 0, "capital_outflow": 0},
{"label": "Aug 2024", "capital_inflow": 0, "capital_outflow": 0}
],
"transform": [
{"type": "formula", "expr": "split(datum.label, ' ')", "as": "label"}
]
},
{
"name": "parsed",
"source": ["capital_flows"],
"transform": [
{
"type": "aggregate",
"fields": [
"capital_inflow",
"capital_inflow",
"capital_outflow",
"capital_outflow"
],
"ops": ["min", "max", "min", "max"],
"as": ["min_value1", "max_value1", "min_value2", "max_value2"]
},
{
"type": "formula",
"expr": "datum.max_value1 == 0 && datum.max_value2 == 0 ? 1 : datum.max_value1 > datum.max_value2 ? abs(datum.max_value1) : abs(datum.max_value2)",
"as": "mergedMax"
},
{
"type": "formula",
"expr": "datum.min_value1 == 0 && datum.min_value2 == 0 ? -1 : 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": "capital_flows", "field": "label"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true,
"zero": false,
"domain": {"data": "parsed", "field": "limit"},
"domainMin": {"signal": "-400"},
"domainMax": {"signal": "400"}
}
],
"axes": [
{
"orient": "bottom",
"scale": "x",
"zindex": 1,
"labelFontSize": 12,
"labelColor": "#85868C",
"labelAlign": "center",
"labelLineHeight": 16.8,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"domainWidth": 1,
"ticks": false
},
{
"orient": "left",
"scale": "y",
"zindex": 0,
"labelFontSize": 12,
"labelColor": "#85868C",
"labelLineHeight": 16.8,
"labelFontWeight": "normal",
"labelPadding": 8,
"labelOpacity": 1,
"domain": false,
"domainColor": "#e5e5e5",
"grid": true,
"gridOpacity": 0.5,
"ticks": false,
"tickCount": 4,
"gridDash": {"signal": "datum.value == 0 ? [0,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": "inflow",
"type": "rect",
"from": {"data": "capital_flows"},
"encode": {
"enter": {
"xc": {"scale": "x", "field": "label", "band": 0.5},
"width": {"value": 14},
"y": {"scale": "y", "field": "capital_inflow"},
"y2": {
"scale": "y",
"value": 0,
"offset": {"signal": "datum.capital_inflow < 0 ? 1.5: 0"}
},
"fill": {"value": "#68c487"},
"cornerRadiusTopLeft": {
"signal": "datum.capital_inflow > 0 ? '1' : '0'"
},
"cornerRadiusTopRight": {
"signal": "datum.capital_inflow > 0 ? '1' : '0'"
},
"cornerRadiusBottomLeft": {
"signal": "datum.capital_inflow > 0 ? '0' : '1'"
},
"cornerRadiusBottomRight": {
"signal": "datum.capital_inflow > 0 ? '0' : '1'"
},
"stroke": {"signal": "datum.capital_inflow !== 0 ? '#68c487': null"},
"strokeWidth": {"value": 1.5},
"fillOpacity": {"signal": "datum.capital_inflow !== 0 ? 1 : 0"}
}
}
},
{
"name": "outflow",
"type": "rect",
"from": {"data": "capital_flows"},
"encode": {
"enter": {
"xc": {"scale": "x", "field": "label", "band": 0.5, "offset": 17},
"width": {"value": 14},
"y": {"scale": "y", "field": "capital_outflow"},
"y2": {
"scale": "y",
"value": 0,
"offset": {"signal": "datum.capital_outflow < 0 ? 1.5: 0"}
},
"fill": {"value": "#FFB066"},
"cornerRadiusTopLeft": {
"signal": "datum.capital_outflow > 0 ? '1' : '0'"
},
"cornerRadiusTopRight": {
"signal": "datum.capital_outflow > 0 ? '1' : '0'"
},
"cornerRadiusBottomLeft": {
"signal": "datum.capital_outflow > 0 ? '0' : '1'"
},
"cornerRadiusBottomRight": {
"signal": "datum.capital_outflow > 0 ? '0' : '1'"
},
"stroke": {"signal": "datum.capital_outflow !== 0 ? '#FFB066': null"},
"strokeWidth": {"value": 1.5},
"fillOpacity": {"signal": "datum.capital_outflow !== 0 ? 1 : 0"}
}
}
}
]
}