Vega 如何对树图上每个节点的所有后代值求和

Vega How to SUM all descendants value of every node on a treemap

我正在尝试访问 VEGA 中节点的值总和。换句话说,我想显示每个父节点的所有叶子的“百分比”值之和。

获得了以下 Vega 规格 (https://gist.github.com/omerakko/655674f9f37e9361fe5378b6d440e411)

    {
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "description": "An example of treemap layout for hierarchical data.",
  "width": 960,
  "height": 500,
  "padding": 2.5,
  "autosize": "none",

 

  "data": [
    {
      "name": "tree",
      "url": "https://raw.githubusercontent.com/omerakko/VEGA/main/vegaTreemapData.json",
      "transform": [
        {
          "type": "stratify",
          "key": "id",
          "parentKey": "parent"
        },
        {
          "type": "treemap",
          "field": "percentage",
          "sort": {"field": "value", "order":"descending"},
          "round": true,
          "method": "resquarify",
          "ratio": 1,
          "size": [{"signal": "width"}, {"signal": "height"}],
          "paddingOuter": 2,
          "paddingInner":2

          
          
        }
      ]
    },
    {
      "name": "nodes",
      "source": "tree",
      "transform": [{ "type": "filter", "expr": "datum.children" }]
      
    },
     
      
    
    {
      "name": "leaves",
      "source": "tree",
      "transform": [{ "type": "filter", "expr": "!datum.children" },
      {"type": "filter", "expr": "datum.percentage > 0"}]
    }
  ],

  "scales": [
    {
      "name": "color",
      "type": "ordinal",
      "domain": {"data": "nodes", "field": "name"},
      "range": [
        "transparent", "#dd96ba", "#dea84e", "#c83836", "#dfde9b",
        "#5eafb9", "#adc35d"]
    },
    {
      "name": "size",
      "type": "ordinal",
      "domain": [0, 1, 2, 3],
      "range": [256, 28, 20, 14]
    },
    {
      "name": "opacity",
      "type": "ordinal",
      "domain": [0, 1, 2, 3],
      "range": [0.15, 0.5, 0.8, 1.0]
    }
  ],

  "marks": [
    {
      "type": "rect",
      "from": {"data": "nodes"},
      "interactive": false,
      "encode": {
        "enter": {
         "fill": {"value":"#333238"},
          "stroke": {"scale": "color", "field": "name"},
          "strokeWidth":{"value": 5}
        },
        "update": {
          "x": {"field": "x0"},
          "y": {"field": "y0"},
          "x2": {"field": "x1"},
          "y2": {"field": "y1"},
          "stroke": {"scale": "color", "field": "name"}
        }
      }
    },
    {
      "type": "rect",
      "from": {"data": "leaves"},
      "encode": {
        "enter": {
          "stroke": {"value": "#fff"}
        },
        "update": {
          "x": {"field": "x0"},
          "y": {"field": "y0"},
          "x2": {"field": "x1"},
          "y2": {"field": "y1"},
          "fill": {"value": "transparent"}
        },
        "hover": {
          "fill": {"value": "red"}
        }
      }
    },
    {
      "type": "text",
      "from": {"data": "nodes"},
      "interactive": false,
      "encode": {
        "enter": {
          "font": {"value": "Helvetica Neue, Arial"},
          "align": {"value": "center"},
          "baseline": {"value": "middle"},
          "fill": {"scale": "color", "field": "name"},
          "text": {"field": "name"},
          "fontSize": {"scale": "size", "field": "depth"}
          
        },
        "update": {
          "x": {"signal": "0.5 * (datum.x0 + datum.x1)"},
          "y": {"signal": "0.5 * (datum.y0 + datum.y1)"}
        }
      }
    }
  ]
}

这里有可用的文档 https://vega.github.io/vega/docs/transforms/treemap/ 说我可以访问我想要的内容,但我无法将其应用到规范中。

目前在 Vega 中似乎无法实现。还有 this PR 尚未合并。

但是您可以通过手动聚合值然后查找来解决这个问题。这里有一个 gist,其中现在每个节点都有一个 total 字段,相关部分是:

{
  "name": "leaves",
  "source": "tree",
  "transform": [
    {"type": "filter", "expr": "!datum.children"},
    {"type": "filter", "expr": "datum.percentage > 0.3"}
  ]
},
{
  "name": "totals",
  "source": "leaves",
  "transform": [
    {
      "type": "aggregate",
      "groupby": ["parent"],
      "fields": ["percentage"],
      "as": ["total"],
      "ops": ["sum"]
    }
  ]
},
{
  "name": "nodes",
  "source": "tree",
  "transform": [
    {"type": "filter", "expr": "datum.children"},
    {
      "type": "lookup",
      "from": "totals",
      "key": "parent",
      "fields": ["id"],
      "values": ["total"],
      "as": ["total"]
    }
  ]
},

基本上你只是得到 totals 中父级的所有叶子的总和,然后在构建基础 nodes 数据集之后,在 totals.[=17 中查找总数=]

请注意,这仅适用于此特定示例,其中层次结构中恰好有两个级别。