根据数据为 D3 和弦路径着色

colorize D3 chord paths based on data

我将此 https://bl.ocks.org/nbremer/d2720fdaab1123df73f4806360a09c9e D3 和弦布局迁移到 D3v7。我目前的问题是,我想利用 var objects 中的 color 属性来填充各个路径。这些目前是灰色的。

我设法用

完成了外圈
.style("fill", function (d) {
      return objects[d.index].color
])

我想我可以使用同一行代码来显示路径的受尊重颜色,但我收到错误消息 objects[d.index].color 未定义,这让我感到困惑。我假设我没有完全理解路径程序,这让我相信我做的一切都是正确的..可悲。

感谢任何帮助。

 // Setup

        var objects = [
            { id: 0, name: "Black Widow", color: "#301E1E" },
            { id: 1, name: "Captian America", color: "#083E77" },
            { id: 2, name: "Hawkeye", color: "#342350" },
            { id: 3, name: "The Hulk", color: "##567235" },
            { id: 4, name: "Iron Man", color: "#8B161C" },
            { id: 5, name: "Thor", color: "#DF7C00" }
        ]

        var flows = [
            { from: 0, to: 0, quantity: 0 },
            { from: 0, to: 1, quantity: 4 },
            { from: 0, to: 2, quantity: 3 },
            { from: 0, to: 3, quantity: 2 },
            { from: 0, to: 4, quantity: 5 },
            { from: 0, to: 5, quantity: 2 },
            { from: 1, to: 0, quantity: 4 },
            { from: 1, to: 1, quantity: 0 },
            { from: 1, to: 2, quantity: 3 },
            { from: 1, to: 3, quantity: 2 },
            { from: 1, to: 4, quantity: 4 },
            { from: 1, to: 5, quantity: 3 },
            { from: 2, to: 0, quantity: 3 },
            { from: 2, to: 1, quantity: 3 },
            { from: 2, to: 2, quantity: 0 },
            { from: 2, to: 3, quantity: 2 },
            { from: 2, to: 4, quantity: 3 },
            { from: 2, to: 5, quantity: 3 },
            { from: 3, to: 0, quantity: 2 },
            { from: 3, to: 1, quantity: 2 },
            { from: 3, to: 2, quantity: 2 },
            { from: 3, to: 3, quantity: 0 },
            { from: 3, to: 4, quantity: 3 },
            { from: 3, to: 5, quantity: 3 },
            { from: 4, to: 0, quantity: 5 },
            { from: 4, to: 1, quantity: 4 },
            { from: 4, to: 2, quantity: 3 },
            { from: 4, to: 3, quantity: 3 },
            { from: 4, to: 4, quantity: 0 },
            { from: 4, to: 5, quantity: 2 },
            { from: 5, to: 0, quantity: 2 },
            { from: 5, to: 1, quantity: 3 },
            { from: 5, to: 2, quantity: 3 },
            { from: 5, to: 3, quantity: 3 },
            { from: 5, to: 4, quantity: 2 },
            { from: 5, to: 5, quantity: 0 },
        ]

        var matrix = [];
        
        // Map flows data to valid matrix
        flows.forEach(function (flow) {
            //initialize sub-array if not yet exists
            if (!matrix[flow.to]) {
                matrix[flow.to] = [];
            }
            
            matrix[flow.to][flow.from] = flow.quantity;
        })   

        const width = window.innerWidth
        const height = window.innerHeight

        const svg = d3.select("body")
            .append("svg")
                .attr("width", width)
                .attr("height", height)
            .append("g")
                .attr("transform", "translate(" + width/2 + "," + height/2 + ")")

        // Übergibt die Daten-Matrix zu d3.chord()
        const root = d3.chord()
            .padAngle(0.05)
            .sortSubgroups(d3.descending)(matrix)

        // Fügt die Gruppen für den inneren Kreis hinzu
        svg
            .datum(root)
            .append("g")
            .selectAll("g")
            .data(d => d.groups)
            .join("g")
            .append("path")
                .style("fill", "grey")
                .style("stroke", "black")
                .attr("d", d3.arc()
                    .innerRadius(width/2 - 210)
                    .outerRadius(width/2 - 200)
                )
            .style("fill", function (d) {
                return objects[d.index].color
            })
            

        // Fügt Verlinkungen zwischen den Gruppen hinzu
        svg
            .datum(root)
            .append("g")
            .selectAll("path")
            .data(d => d)
            .join("path")
                .attr("d", d3.ribbon()
                    .radius(width/2 - 220)
                )
                .style("fill", function (d) {
                    return objects[d.index].color
                })
                //.style("fill", "grey")
                .style("stroke", "black")
    body {
        font-size: 12px;
        font-family: 'Lato', sans-serif;
        text-align: center;
        fill: #2B2B2B;
        cursor: default;
        overflow: hidden;
    }

    @media (min-width: 600px) {
        #chart {
            font-size: 16px;
        }
    }
<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title>Step 1 - Collaborations between MCU Avengers</title>

    <!-- D3.js -->
    <script src="https://d3js.org/d3.v7.js"></script>
    
</head>



<body>
    
</body>

</html>

TL;DR:

92 至 94 行

.style("fill", function (d) {
    return objects[d.index].color
})

...成为:

.style('fill', ({ index }) => objects.find(({ id }) => id === index).color)

107 到 109 行:

.style("fill", function (d) {
    return objects[d.index].color
})

...成为:

.style('fill', ({ source: { index } }) => objects.find(({ id }) => id === index).color)

说明

你有两个问题:

  1. 您在第二种方法中的项目 d 实际上包含“来源”和“目标”,例如:
{
  "source": {
    "index": 0,
    "startAngle": 0.3399537106352038,
    "endAngle": 0.6119166791433668,
    "value": 4
  },
   "target": {
   "index": 1,
   "startAngle": 1.1378518740326522,
   "endAngle": 1.4098148425408152,
   "value": 4
  }
}

...因此您需要在访问“索引”属性之前深入研究“源”或“目标”。

  1. 您的 objects 数组包含对显然已排序的项目的引用,因此它们的“id”属性对应于它们在 objects 数组中的索引,但我认为这可能是一个不可靠的巧合或无意的疏忽。

无论如何,您似乎完全无视 index 属性,而我相信您打算用它来识别每个项目。我建议你在这里使用Array#find

更新的代码片段

// Setup

        var objects = [
            { id: 0, name: "Black Widow", color: "#301E1E" },
            { id: 1, name: "Captian America", color: "#083E77" },
            { id: 2, name: "Hawkeye", color: "#342350" },
            { id: 3, name: "The Hulk", color: "##567235" },
            { id: 4, name: "Iron Man", color: "#8B161C" },
            { id: 5, name: "Thor", color: "#DF7C00" }
        ]

        var flows = [
            { from: 0, to: 0, quantity: 0 },
            { from: 0, to: 1, quantity: 4 },
            { from: 0, to: 2, quantity: 3 },
            { from: 0, to: 3, quantity: 2 },
            { from: 0, to: 4, quantity: 5 },
            { from: 0, to: 5, quantity: 2 },
            { from: 1, to: 0, quantity: 4 },
            { from: 1, to: 1, quantity: 0 },
            { from: 1, to: 2, quantity: 3 },
            { from: 1, to: 3, quantity: 2 },
            { from: 1, to: 4, quantity: 4 },
            { from: 1, to: 5, quantity: 3 },
            { from: 2, to: 0, quantity: 3 },
            { from: 2, to: 1, quantity: 3 },
            { from: 2, to: 2, quantity: 0 },
            { from: 2, to: 3, quantity: 2 },
            { from: 2, to: 4, quantity: 3 },
            { from: 2, to: 5, quantity: 3 },
            { from: 3, to: 0, quantity: 2 },
            { from: 3, to: 1, quantity: 2 },
            { from: 3, to: 2, quantity: 2 },
            { from: 3, to: 3, quantity: 0 },
            { from: 3, to: 4, quantity: 3 },
            { from: 3, to: 5, quantity: 3 },
            { from: 4, to: 0, quantity: 5 },
            { from: 4, to: 1, quantity: 4 },
            { from: 4, to: 2, quantity: 3 },
            { from: 4, to: 3, quantity: 3 },
            { from: 4, to: 4, quantity: 0 },
            { from: 4, to: 5, quantity: 2 },
            { from: 5, to: 0, quantity: 2 },
            { from: 5, to: 1, quantity: 3 },
            { from: 5, to: 2, quantity: 3 },
            { from: 5, to: 3, quantity: 3 },
            { from: 5, to: 4, quantity: 2 },
            { from: 5, to: 5, quantity: 0 },
        ]

        var matrix = [];
        
        // Map flows data to valid matrix
        flows.forEach(function (flow) {
            //initialize sub-array if not yet exists
            if (!matrix[flow.to]) {
                matrix[flow.to] = [];
            }
            
            matrix[flow.to][flow.from] = flow.quantity;
        })   

        const width = window.innerWidth
        const height = window.innerHeight

        const svg = d3.select("body")
            .append("svg")
                .attr("width", width)
                .attr("height", height)
            .append("g")
                .attr("transform", "translate(" + width/2 + "," + height/2 + ")")
                
        // Übergibt die Daten-Matrix zu d3.chord()
        const root = d3.chord()
            .padAngle(0.05)
            .sortSubgroups(d3.descending)(matrix)
            
        // Fügt die Gruppen für den inneren Kreis hinzu
        svg
            .datum(root)
            .append("g")
            .selectAll("g")
            .data(d => d.groups)
            .join("g")
            .append("path")
                .style("fill", "grey")
                .style("stroke", "black")
                .attr("d", d3.arc()
                    .innerRadius(width/2 - 210)
                    .outerRadius(width/2 - 200)
                )
            .style("fill", function ({ index }) {
                return objects.find(({ id }) => id === index).color;
            })
            

        // Fügt Verlinkungen zwischen den Gruppen hinzu
        svg
            .datum(root)
            .append("g")
            .selectAll("path")
            .data(d => d)
            .join("path")
                .attr("d", d3.ribbon()
                    .radius(width/2 - 220)
                )
                .style("fill", function ({ source: { index } }) {
                    return objects.find(({ id }) => id === index).color;
                })
                //.style("fill", "grey")
                .style("stroke", "black")
body {
        font-size: 12px;
        font-family: 'Lato', sans-serif;
        text-align: center;
        fill: #2B2B2B;
        cursor: default;
        overflow: hidden;
    }

    @media (min-width: 600px) {
        #chart {
            font-size: 16px;
        }
    }
<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
    <title>Step 1 - Collaborations between MCU Avengers</title>

    <!-- D3.js -->
    <script src="https://d3js.org/d3.v7.js"></script>
    
</head>



<body>
    
</body>

</html>