【问题标题】:d3 hierarchy ability to average children node valuesd3 层次结构平均子节点值的能力
【发布时间】:2020-01-19 12:56:32
【问题描述】:

我有一个 d3 可视化,它有一个类似于以下内容的 JSON 对象,我想在最低节点上平均 score 的值,并将该平均值动态添加到上面的父节点......等等.看起来 d3 没有一个简单的方法来做到这一点。我想要的是让最终的 JSON 输出看起来像第二个例子。

 {
  "name": "A1",
  "children": [
    {
      "name": "B1",
      "children": [
        {
          "name": "B1-C1",
          "children": [
            {
              "name": "B1-C1-D1",
              "children": [
                {
                  "name": "B1-C1-D1-E1",
                  "value": 30,
                  "score": 0.8
                },
                {
                  "name": "B1-C1-D1-E2",
                  "value": 35,
                  "score": 0.5
                }
              ]
            },
            {
              "name": "B1-C1-D2",
              "children": [
                {
                  "name": "B1-C1-D2-E1",
                  "value": 31,
                  "score": 0.4
                },
                {
                  "name": "B1-C1-D2-E2",
                  "value": 23,
                  "score": 0.7
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

我希望最终 JSON 对象的样子:

{
  "name": "A1",
  "scoreAvg": 0.625,
  "children": [
    {
      "name": "B1",
      "scoreAvg": 0.625,
      "children": [
        {
          "name": "B1-C1",
          "scoreAvg": 0.625,
          "children": [
            {
              "name": "B1-C1-D1",
              "scoreAvg": 0.7,
              "children": [
                {
                  "name": "B1-C1-D1-E1",
                  "value": 30,
                  "score": 0.8
                },
                {
                  "name": "B1-C1-D1-E2",
                  "value": 35,
                  "score": 0.6
                }
              ]
            },
            {
              "name": "B1-C1-D2",
              "scoreAvg": 0.55,
              "children": [
                {
                  "name": "B1-C1-D2-E1",
                  "value": 31,
                  "score": 0.4
                },
                {
                  "name": "B1-C1-D2-E2",
                  "value": 23,
                  "score": 0.7
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

【问题讨论】:

    标签: javascript json d3.js ecmascript-6


    【解决方案1】:

    你可以使用递归函数:

    const obj = {
      "name": "A1",
      "children": [{
        "name": "B1",
        "children": [{
          "name": "B1-C1",
          "children": [{
              "name": "B1-C1-D1",
              "children": [{
                  "name": "B1-C1-D1-E1",
                  "value": 30,
                  "score": 0.8
                },
                {
                  "name": "B1-C1-D1-E2",
                  "value": 35,
                  "score": 0.5
                }
              ]
            },
            {
              "name": "B1-C1-D2",
              "children": [{
                  "name": "B1-C1-D2-E1",
                  "value": 31,
                  "score": 0.4
                },
                {
                  "name": "B1-C1-D2-E2",
                  "value": 23,
                  "score": 0.7
                }
              ]
            }
          ]
        }]
      }]
    }
    
    function getWithAverageScore(objToRecurse) {
      // If I have a score I am already done
    	if (objToRecurse.score) {
    		return objToRecurse;
    	}
      // Otherwise, I get my children with their average score
    	const children = objToRecurse.children.map(getWithAverageScore);
    
    	return {
    		...objToRecurse,
    		children,
        // And I set my scoreAvg to their average (score or scoreAvg)
    		scoreAvg: children.reduce((total, { score, scoreAvg }) => total + (score || scoreAvg), 0) / children.length
    	};
    }
    
    console.log(JSON.stringify(getWithAverageScore(obj), null, 2))

    【讨论】:

      【解决方案2】:
      let o = {
        "name": "A1",
        "children": [
          {
            "name": "B1",
            "children": [
              {
                "name": "B1-C1",
                "children": [
                  {
                    "name": "B1-C1-D1",
                    "children": [
                      {
                        "name": "B1-C1-D1-E1",
                        "value": 30,
                        "score": 0.8
                      },
                      {
                        "name": "B1-C1-D1-E2",
                        "value": 35,
                        "score": 0.5
                      }
                    ]
                  },
                  {
                    "name": "B1-C1-D2",
                    "children": [
                      {
                        "name": "B1-C1-D2-E1",
                        "value": 31,
                        "score": 0.4
                      },
                      {
                        "name": "B1-C1-D2-E2",
                        "value": 23,
                        "score": 0.7
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      };
      
      
      function avgUp(object){
        object.avgScore = 0;
      if(object.children){
        for(child of object.children){
          object.avgScore += avgUp(child);
         }
      object.avgScore =  object.avgScore /Math.max(1,object.children.length);
         return object.avgScore;
      }else{
      return object.score;
      }
      }
      
      avgUp(o);
      
      console.log(JSON.stringify(o));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-27
        • 1970-01-01
        相关资源
        最近更新 更多