为了账号安全,请及时绑定邮箱和手机立即绑定

d3 层次结构平均子节点值的能力

d3 层次结构平均子节点值的能力

呼唤远方 2021-10-21 14:15:39
我有一个 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                },               
查看完整描述

2 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

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));


查看完整回答
反对 回复 2021-10-21
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

您可以使用递归函数:


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))



查看完整回答
反对 回复 2021-10-21
  • 2 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信