根据数据为 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)
说明
你有两个问题:
- 您在第二种方法中的项目
d
实际上包含“来源”和“目标”,例如:
{
"source": {
"index": 0,
"startAngle": 0.3399537106352038,
"endAngle": 0.6119166791433668,
"value": 4
},
"target": {
"index": 1,
"startAngle": 1.1378518740326522,
"endAngle": 1.4098148425408152,
"value": 4
}
}
...因此您需要在访问“索引”属性之前深入研究“源”或“目标”。
- 您的
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>
我将此 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)
说明
你有两个问题:
- 您在第二种方法中的项目
d
实际上包含“来源”和“目标”,例如:
{
"source": {
"index": 0,
"startAngle": 0.3399537106352038,
"endAngle": 0.6119166791433668,
"value": 4
},
"target": {
"index": 1,
"startAngle": 1.1378518740326522,
"endAngle": 1.4098148425408152,
"value": 4
}
}
...因此您需要在访问“索引”属性之前深入研究“源”或“目标”。
- 您的
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>