在 Vega 中使用不同颜色的负值和正值构建条形图
Build bar chart in Vega with different colors for negative and positive values
所以我需要使用 Vega 库构建这样的东西:
现在我是超级n00b,还请大家见谅
第一个解决方案:使用某种条件格式(如 Excel):如果栏值 < 0,则将其设为红色。如果条形值 > 0,则将其变为绿色。我可以为 Vega-Lite 找到一些条件语法,这给了我希望,但我不知道如何将语法转换为普通 Vega,我不知道。
其次,我考虑过对范围使用某种配色方案,例如具有阈值的配色方案。但是我完全不知道要使用什么比例范围类型,并且注意到比例范围类型和配色方案之间存在关系,所以是的。困惑。
然后,我的同事提出了这个建议:https://vega.github.io/editor/#/examples/vega-lite/layer_bar_annotations
因此在示例中,我们可以看到高于阈值的条形值具有条件格式。所以我尝试过滤数据以获得 2 个子集:values_lower_than_0
和 values_higher_than_0
将它们用作标记的来源。但好像我不知道如何过滤。我的数据如下所示:
[
{ "date": "2018-12-10", "difference": 20 },
{ "date": "2018-10-21", "difference": -10 }
...
]
然后我对其应用变换:
...
{
'name': 'values_lower_than_0',
'source': 'temps',
'transform': [{ 'type': 'filter', 'expr': 'datum.difference.Value < 0' }]
}
但是当我在标记中使用 values_lower_than_0
时,似乎什么也没有发生。
那么,我有两个问题:
- 这是构建此类图表的最佳方法吗? (老实说,这对我来说似乎很复杂)。
- 如果是,那我应该如何获取这两个数据集并使用它们来获得正确的颜色?
我好累,我今天犯了愚蠢的错误!如果有人想使用上面描述的第三种方法,那么我是对的,我只是将错误的源名称传递给了标记。
另一种说法是:对于负值(例如values_lower_than_0
),您只需要计算一个子集。
完成后,所有柱状图都会有一个名为 bars
的标记(与默认值一样,带有绿色填充)。该标记的数据源将是默认数据。在该标记之上,您将应用第二个标记,称为 negative_bars
(例如),其来源为 values_lower_than_0
,您将为其填充红色。
我关于最佳方法的问题仍然存在。
更好的方法是不对数据集应用转换。
以here
为例
想法是将 y2
值设置为 Height
的中间值。 y
然后将根据值是负值还是正值分别调整到低于 midHeight 或高于 midHeight。请参考下面的 rect
类型标记配置。
{
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 600,
"height": 360,
"autosize": "fit",
"data": [
{
"name": "table",
"url": "https://uat.gramener.com/vega/chart/data/pos-neg-items.json"
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "table",
"field": "category"
},
"range": "width",
"padding": 0.2,
"round": true
},
{
"name": "yscale",
"domain": {
"data": "table",
"field": "amount"
},
"nice": true,
"range": "height"
}
],
"marks": [
{
"name": "bars",
"type": "rect",
"from": {
"data": "table"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "amount"
},
"y2": {
"signal": "scale('yscale', 0)"
},
"fill": {
"signal": "datum['amount'] > 0 ? '#5CB38B' : '#E6685C'"
},
"tooltip": {
"signal": "datum"
}
}
}
},
{
"name": "item_score",
"type": "text",
"from": {
"data": "table"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"y": {
"scale": "yscale",
"field": "amount"
},
"dy": {
"signal": "datum['amount'] > 0 ? -4 : 14"
},
"dx": {
"signal": "bandwidth('xscale')/2"
},
"align": {
"value": "center"
},
"fill": {
"value": "black"
},
"text": {
"field": "amount"
},
"fontSize": {
"value": 12
}
}
}
},
{
"name": "item_name",
"type": "text",
"from": {
"data": "table"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"dx": {
"value": 20
},
"dy": {
"signal": "datum['amount'] > 0 ? height/2 + 14 : height/2 - 6"
},
"align": {
"value": "center"
},
"fill": {
"value": "#000000"
},
"text": {
"field": "category"
},
"fontSize": {
"value": 12
}
}
}
}
]
}
所以我需要使用 Vega 库构建这样的东西:
现在我是超级n00b,还请大家见谅
第一个解决方案:使用某种条件格式(如 Excel):如果栏值 < 0,则将其设为红色。如果条形值 > 0,则将其变为绿色。我可以为 Vega-Lite 找到一些条件语法,这给了我希望,但我不知道如何将语法转换为普通 Vega,我不知道。
其次,我考虑过对范围使用某种配色方案,例如具有阈值的配色方案。但是我完全不知道要使用什么比例范围类型,并且注意到比例范围类型和配色方案之间存在关系,所以是的。困惑。
然后,我的同事提出了这个建议:https://vega.github.io/editor/#/examples/vega-lite/layer_bar_annotations
因此在示例中,我们可以看到高于阈值的条形值具有条件格式。所以我尝试过滤数据以获得 2 个子集:values_lower_than_0
和 values_higher_than_0
将它们用作标记的来源。但好像我不知道如何过滤。我的数据如下所示:
[
{ "date": "2018-12-10", "difference": 20 },
{ "date": "2018-10-21", "difference": -10 }
...
]
然后我对其应用变换:
...
{
'name': 'values_lower_than_0',
'source': 'temps',
'transform': [{ 'type': 'filter', 'expr': 'datum.difference.Value < 0' }]
}
但是当我在标记中使用 values_lower_than_0
时,似乎什么也没有发生。
那么,我有两个问题:
- 这是构建此类图表的最佳方法吗? (老实说,这对我来说似乎很复杂)。
- 如果是,那我应该如何获取这两个数据集并使用它们来获得正确的颜色?
我好累,我今天犯了愚蠢的错误!如果有人想使用上面描述的第三种方法,那么我是对的,我只是将错误的源名称传递给了标记。
另一种说法是:对于负值(例如values_lower_than_0
),您只需要计算一个子集。
完成后,所有柱状图都会有一个名为 bars
的标记(与默认值一样,带有绿色填充)。该标记的数据源将是默认数据。在该标记之上,您将应用第二个标记,称为 negative_bars
(例如),其来源为 values_lower_than_0
,您将为其填充红色。
我关于最佳方法的问题仍然存在。
更好的方法是不对数据集应用转换。
以here
为例想法是将 y2
值设置为 Height
的中间值。 y
然后将根据值是负值还是正值分别调整到低于 midHeight 或高于 midHeight。请参考下面的 rect
类型标记配置。
{
"$schema": "https://vega.github.io/schema/vega/v4.json",
"width": 600,
"height": 360,
"autosize": "fit",
"data": [
{
"name": "table",
"url": "https://uat.gramener.com/vega/chart/data/pos-neg-items.json"
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {
"data": "table",
"field": "category"
},
"range": "width",
"padding": 0.2,
"round": true
},
{
"name": "yscale",
"domain": {
"data": "table",
"field": "amount"
},
"nice": true,
"range": "height"
}
],
"marks": [
{
"name": "bars",
"type": "rect",
"from": {
"data": "table"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"width": {
"scale": "xscale",
"band": 1
},
"y": {
"scale": "yscale",
"field": "amount"
},
"y2": {
"signal": "scale('yscale', 0)"
},
"fill": {
"signal": "datum['amount'] > 0 ? '#5CB38B' : '#E6685C'"
},
"tooltip": {
"signal": "datum"
}
}
}
},
{
"name": "item_score",
"type": "text",
"from": {
"data": "table"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"y": {
"scale": "yscale",
"field": "amount"
},
"dy": {
"signal": "datum['amount'] > 0 ? -4 : 14"
},
"dx": {
"signal": "bandwidth('xscale')/2"
},
"align": {
"value": "center"
},
"fill": {
"value": "black"
},
"text": {
"field": "amount"
},
"fontSize": {
"value": 12
}
}
}
},
{
"name": "item_name",
"type": "text",
"from": {
"data": "table"
},
"encode": {
"enter": {
"x": {
"scale": "xscale",
"field": "category"
},
"dx": {
"value": 20
},
"dy": {
"signal": "datum['amount'] > 0 ? height/2 + 14 : height/2 - 6"
},
"align": {
"value": "center"
},
"fill": {
"value": "#000000"
},
"text": {
"field": "category"
},
"fontSize": {
"value": 12
}
}
}
}
]
}