标签和文本的统一数字格式

时间:2019-11-26 16:52:11

标签: vega vega-lite

我有一个Vega-Lite可视化工具,可以处理字段值范围从0到数百万的数据集。
我试图在轴,图例,标记和工具提示上使用统一的SI格式,以使单位(k,M等)根据值而变化,并保持精度不变。 (以下示例中的小数点后2位)

Sample in Vega Editor

SI format

在Y轴上,"format": "$,.2s"的标签始终遵循小数点后两位的精度,并限制为适用于所应用数据集的最高单位。图例标签的工作原理类似,但是值718.6呈现为0.00M。

text通道上,format具有不同的输出。单位根据值而变化,但是无法控制精度。在不指定~的情况下修剪值。

    {
      "mark": {"type": "text", "dy": -5},
      "encoding": {
        "text": {"field": "revenue", "type": "quantitative", "format": "$,.2s"}
      }
    }

使用计算来格式化值也将得到相同的输出。

    {
      "calculate": "format(datum['revenue'],'$,.7s')",
      "as": "revenue_text"
    }

是否存在任何配置,axislegend标签的单位将随着值的增加而变化? 对于text,如何确保固定精度?

在100.00(没有任何单位符号)的行上进行的操作,然后是100.00k,然后是1.00M,依此类推,以保持指定的精度。

                  +------------+-------------------+-------------------+-------------------+
                  |            |                      Present Output                       |
    +-------------+  Expected  +-------------------+-------------------+-------------------+
    |    value    |   Output   | (format: '$,.2s') | (format: '$,.3s') | (format: '$,.7s') |
    +-------------+------------+-------------------+-------------------+-------------------+
    | 25175.39919 | $25.18k    | $25k              | $25.2k            | $25.17540k        |
    | 849601.8777 | $849.60k   | $850k             | $850k             | $849.6019k        |
    | 718.6143971 | $719.00    | $720              | $719              | $718.6144         |
    | 1597752.776 | $1.60M     | $1.60M            | $1.60M            | $1.597753M        |
    +-------------+------------+-------------------+-------------------+-------------------+

1 个答案:

答案 0 :(得分:0)

确定罪魁祸首

  

“取决于类型,精度要么表示小数点后的位数(类型f和%),要么表示有效位数(类型e,g,r,s和p)。 ”   (请参阅d3 format help

因此,一旦选择了SI,您将被困在有效数字上。

范围的限制

对于图例和轴,我没有任何解决方案。恐怕您现在可能已经达到了Vega-lite的限制。此外,考虑到巨大的领域和您的精度要求(在数字较小的情况下,精度很高),条形图可能不再适用。如果您切换到例如点图,您可以使用具有原始域值的对数标度,从而扩展/压缩轴值,从而使每个标签的精度都很高。

其余建议

对于文本标记,一种替代方法是编写您自己的格式预处理器。例如,在vega-lite中,您可以使用一系列calculate转换来创建字符串格式的新变量。每个计算表达式将测试不同类型的数字(千,百万等),并应用必要的格式。在您的用例中,将有3种这样的转换:

  • 如果(千,请以固定格式“’”转换为数千)
  • if(millions,以固定格式转换为百万,返回新变量)
  • 如果(既不成千上万,也不转换成固定格式,返回新变量)

在所有情况下,as将包含相同的新变量名。

您可以在帖子中回收字符串变量revenue_text,以每次都测试是否存在SI字母,例如第一个表达式:

if(lastindexof(datum.revenue_text, ‘k’) > 0, format(datum.revenue / 1000, '$,.2s') + 'k', ‘’)

第一个转换将以“”作为else子句,而其他任何情况都必须包含新变量本身。除了lastindexof(),您还可以将test()用于正则表达式。显然,您可以在单个转换中完成所有这些操作-无论您认为哪种可读性和可维护性都可能与口味有关。

P.S。我现在没有电脑可以测试所说的表情。