I migrated this https://bl.ocks.org/nbremer/d2720fdaab1123df73f4806360a09c9e D3 Chord layout to D3v7. My current problem is, I want to utilize the color attribute from var objects to fill the individual paths. Those are currently grey.
I managed to get it done for the outer circle with
.style("fill", function (d) {
return objects[d.index].color
])
I thought I could use the same line of code to display the respected color for the paths but I receive the error that objects[d.index].color is undefined, which confuse me. I assume I did not understood the path procedure fully, which makes me believe I do everything correct.. pathetic.
I appreciate any help.
// 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>
Lines 92 through 94:
.style("fill", function (d) {
return objects[d.index].color
})
... become:
.style('fill', ({ index }) => objects.find(({ id }) => id === index).color)
And lines 107 through 109:
.style("fill", function (d) {
return objects[d.index].color
})
... become:
.style('fill', ({ source: { index } }) => objects.find(({ id }) => id === index).color)
You have two problems:
d
in the second method actually contain both "source" and "target", for instance:{
"source": {
"index": 0,
"startAngle": 0.3399537106352038,
"endAngle": 0.6119166791433668,
"value": 4
},
"target": {
"index": 1,
"startAngle": 1.1378518740326522,
"endAngle": 1.4098148425408152,
"value": 4
}
}
... and you therefore need to dig into either "source" or "target" before having access to an "index" attribute.
objects
Array contains references to items that are apparently ordered such that their "id" attribute corresponds to their index in the objects
Array, but I presume it to be either an unreliable coincidence or an inadvertent oversight.In any case, you seem to be disregarding the index
property entirely, while I believe you meant to use it to identify each item. I suggest you use Array#find here!
// 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>