D3v7 中的分組是否發生了變化?下圖按所有功能區、所有弧線和所有標簽對元素進行分組。意味著一組的資料被分成三個元素。我如何將它們分組以將每個需要的元素捆綁到一個組中。
所以不是所有的絲帶,所有的弧線和所有的標簽..它應該是:
group0
thisRibbony
thisArc
thisLabelgroup1
thisRibbony
thisArc
thisLabelgroup2
thisRibbony
thisArc
thisLabel
它是怎樣的:

我的愿望:
每個條目都有一個自己的 g 分組元素,其中包含捆綁的資料。

////////////////////////////////////////////////////////////
////////////////////// Set-Up Data /////////////////////////
////////////////////////////////////////////////////////////
let groups = [
{ name: "A", color: "blue" },
{ name: "B", color: "red" },
{ name: "C", color: "green" },
{ name: "D", color: "grey" },
]
let paths = [
{ from: groups.name = "A", to: groups.name = "A", strength: 0 },
{ from: groups.name = "A", to: groups.name = "B", strength: 5 },
{ from: groups.name = "A", to: groups.name = "C", strength: 5 },
{ from: groups.name = "A", to: groups.name = "D", strength: 5 },
{ from: groups.name = "B", to: groups.name = "A", strength: 5 },
{ from: groups.name = "B", to: groups.name = "B", strength: 0 },
{ from: groups.name = "B", to: groups.name = "C", strength: 5 },
{ from: groups.name = "B", to: groups.name = "D", strength: 5 },
{ from: groups.name = "C", to: groups.name = "A", strength: 5 },
{ from: groups.name = "C", to: groups.name = "B", strength: 5 },
{ from: groups.name = "C", to: groups.name = "C", strength: 0 },
{ from: groups.name = "C", to: groups.name = "D", strength: 5 },
{ from: groups.name = "D", to: groups.name = "D", strength: 0 },
{ from: groups.name = "D", to: groups.name = "A", strength: 5 },
{ from: groups.name = "D", to: groups.name = "B", strength: 5 },
{ from: groups.name = "D", to: groups.name = "C", strength: 5 },
]
let matrix = []
function getMatrix(paths, groups) {
matrix = []
var mapPaths = paths.map(item => {
const container = {}
container.from = groups.findIndex(ele => ele.name == item.from)
container.to = groups.findIndex(ele => ele.name == item.to)
container.strength = item.strength
return container
})
mapPaths.forEach(function (item) {
// initialize sub-arra if not yet exists
if (!matrix[item.to]) {
matrix[item.to] = []
}
matrix[item.to][item.from] = item.strength
})
return matrix
}
////////////////////////////////////////////////////////////
///////////////////// Set-Up Visualization /////////////////
////////////////////////////////////////////////////////////
const vw = window.innerWidth
const vh = window.innerHeight
const innerRadius = Math.min(vw, vh) * 0.3;
const outerRadius = innerRadius * 1.1;
const duration = 1000;
const svg = d3.select("#chart").append("svg")
.attr("width", vw)
.attr("height", vh)
.attr("overflow", "unset")
const wrapper = svg.append("g")
.attr("id", "wrapper")
.attr("transform", "translate(" vw / 2 "," vh / 2 ")")
const ribbonsG = wrapper.append("g").attr("id", "ribbons")
const arcsG = wrapper.append("g").attr("id", "arcs")
const labelsG = wrapper.append("g").attr("id", "labels")
var chordGenerator = d3.chord()
.padAngle(0.10)
.sortSubgroups(d3.ascending)
.sortChords(d3.descending)
var arc = d3.arc()
.innerRadius(innerRadius * 1.01)
.outerRadius(outerRadius)
var ribbon = d3.ribbon()
.radius(innerRadius);
window.update = update;
update(paths, groups)
function update(thisPaths, thisGroups) {
const chords = chordGenerator(getMatrix(thisPaths, thisGroups))
// ribbons
const ribbonsUpdate = ribbonsG
.selectAll("path.ribbon")
.data(chords)
const ribbonsEnter = ribbonsUpdate
.enter()
.append("path")
ribbonsUpdate
.merge(ribbonsEnter)
.transition(duration)
.attr("opacity", 0)
.attr("class", "ribbon")
.transition()
.duration(duration)
.attr("d", ribbon)
.style("fill", function (d) { return thisGroups[d.target.index].color; })
.attr('opacity', 1)
ribbonsUpdate
.exit()
.transition()
.duration(duration)
.attr("opacity", 0)
.remove();
// arcs
const arcsUpdate = arcsG
.selectAll("path.arc")
.data(chords.groups)
const arcsEnter = arcsUpdate
.enter()
.append("path")
arcsUpdate
.merge(arcsEnter)
.transition(duration)
.attr("opacity", 0)
.attr("class", "arc")
.transition()
.duration(duration)
.attr("d", arc)
.style("fill", function (d) { return thisGroups[d.index].color; })
.attr('opacity', 1)
arcsUpdate
.exit()
.transition()
.duration(duration)
.attr("opacity", 0)
.remove();
// adding labels
const labelsUpdate = labelsG
.selectAll("text.titles")
.data(chords.groups)
const labelsEnter = labelsUpdate
.enter()
.append("text")
labelsUpdate
.merge(labelsEnter)
.attr("class", "titles")
.attr("opacity", 0)
.transition()
.duration(duration)
.each(function(d){ d.angle = (d.startAngle d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.attr("transform", function(d) {
return "rotate(" (d.angle * 180 / Math.PI - 90) ")"
"translate(" (outerRadius 10) ")"
(d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d,i){ return thisGroups[i].name; })
.attr("opacity", 1)
labelsUpdate
.exit()
.remove()
}
body {
font-size: 16px;
font-family: 'Oswald', sans-serif;
background-color: #ECF0F3;
cursor: default;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>D3v7</title>
<!-- D3.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js" charset="utf-8"></script>
<!-- fontawesome stylesheet https://fontawesome.com/ -->
<script src="https://kit.fontawesome.com/98a5e27706.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="chart"></div>
</body>
</html>
uj5u.com熱心網友回復:
問題是,弧、絲帶和標簽有 3 個不同的分組。要將一個部分的各個部分邏輯地組合在一起,可以為圖表的每個部分創建一個分組,然后將弧線和標簽附加到每個部分。
之后可以select用來更改 g.group 中的路徑和文本元素。
絲帶不屬于任何部分,因此它們不能輕易分配,應單獨放置。
請查看https://bost.ocks.org/mike/selection/以更深入地了解選擇以及如何操作它們。
這是預期行為的作業解決方案:
////////////////////////////////////////////////////////////
////////////////////// Set-Up Data /////////////////////////
////////////////////////////////////////////////////////////
let groups = [
{ name: "A", color: "blue" },
{ name: "B", color: "red" },
{ name: "C", color: "green" },
{ name: "D", color: "grey" },
]
let paths = [
{ from: groups.name = "A", to: groups.name = "A", strength: 0 },
{ from: groups.name = "A", to: groups.name = "B", strength: 5 },
{ from: groups.name = "A", to: groups.name = "C", strength: 5 },
{ from: groups.name = "A", to: groups.name = "D", strength: 5 },
{ from: groups.name = "B", to: groups.name = "A", strength: 5 },
{ from: groups.name = "B", to: groups.name = "B", strength: 0 },
{ from: groups.name = "B", to: groups.name = "C", strength: 5 },
{ from: groups.name = "B", to: groups.name = "D", strength: 5 },
{ from: groups.name = "C", to: groups.name = "A", strength: 5 },
{ from: groups.name = "C", to: groups.name = "B", strength: 5 },
{ from: groups.name = "C", to: groups.name = "C", strength: 0 },
{ from: groups.name = "C", to: groups.name = "D", strength: 5 },
{ from: groups.name = "D", to: groups.name = "D", strength: 0 },
{ from: groups.name = "D", to: groups.name = "A", strength: 5 },
{ from: groups.name = "D", to: groups.name = "B", strength: 5 },
{ from: groups.name = "D", to: groups.name = "C", strength: 5 },
]
let matrix = []
function getMatrix(paths, groups) {
matrix = []
var mapPaths = paths.map(item => {
const container = {}
container.from = groups.findIndex(ele => ele.name == item.from)
container.to = groups.findIndex(ele => ele.name == item.to)
container.strength = item.strength
return container
})
mapPaths.forEach(function (item) {
// initialize sub-arra if not yet exists
if (!matrix[item.to]) {
matrix[item.to] = []
}
matrix[item.to][item.from] = item.strength
})
return matrix
}
////////////////////////////////////////////////////////////
///////////////////// Set-Up Visualization /////////////////
////////////////////////////////////////////////////////////
const vw = window.innerWidth
const vh = window.innerHeight
const innerRadius = Math.min(vw, vh) * 0.3;
const outerRadius = innerRadius * 1.1;
const duration = 1000;
const svg = d3.select("#chart").append("svg")
.attr("width", vw)
.attr("height", vh)
.attr("overflow", "unset")
const wrapper = svg.append("g")
.attr("id", "wrapper")
.attr("transform", "translate(" vw / 2 "," vh / 2 ")")
const ribbonsG = wrapper.append("g").attr("id", "ribbons")
const groupsG = wrapper.append("g").attr("id", "groups")
var chordGenerator = d3.chord()
.padAngle(0.10)
.sortSubgroups(d3.ascending)
.sortChords(d3.descending)
var arc = d3.arc()
.innerRadius(innerRadius * 1.01)
.outerRadius(outerRadius)
var ribbon = d3.ribbon()
.radius(innerRadius);
update(paths, groups)
function update(thisPaths, thisGroups) {
const chords = chordGenerator(getMatrix(thisPaths, thisGroups))
// ribbons
const ribbonsUpdate = ribbonsG
.selectAll("path.ribbon")
.data(chords)
const ribbonsEnter = ribbonsUpdate
.enter()
.append("path")
ribbonsUpdate
.merge(ribbonsEnter)
.transition(duration)
.attr("opacity", 0)
.attr("class", "ribbon")
.transition()
.duration(duration)
.attr("d", ribbon)
.style("fill", function (d) { return thisGroups[d.target.index].color; })
.attr('opacity', 1)
ribbonsUpdate
.exit()
.transition()
.duration(duration)
.attr("opacity", 0)
.remove();
let itemsUpdate = groupsG.selectAll("g.group")
.data(chords.groups);
const itemsEnter = itemsUpdate.enter().append("g").attr("class", "group");
itemsEnter.append('path')
.attr("class", "arc");
itemsEnter.append('text')
.attr("class", "title");
itemsUpdate = itemsUpdate.merge(itemsEnter);
itemsUpdate.select("path.arc")
.transition(duration)
.attr("opacity", 0)
.transition()
.duration(duration)
.attr("d", arc)
.style("fill", function (d) { return thisGroups[d.index].color; })
.attr('opacity', 1)
itemsUpdate.exit()
.select("path.arc")
.transition()
.duration(duration)
.attr("opacity", 0)
.remove();
itemsUpdate.select("text.title")
.attr("opacity", 0)
.transition()
.duration(duration)
.each(function(d){ d.angle = (d.startAngle d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.attr("transform", function(d) {
return "rotate(" (d.angle * 180 / Math.PI - 90) ")"
"translate(" (outerRadius 10) ")"
(d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d,i){ return thisGroups[i].name; })
.attr("opacity", 1)
itemsUpdate.exit()
.select("text.title")
.remove()
}
body {
font-size: 16px;
font-family: 'Oswald', sans-serif;
background-color: #ECF0F3;
cursor: default;
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>D3v7</title>
<!-- D3.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.6.1/d3.min.js" charset="utf-8"></script>
<!-- fontawesome stylesheet https://fontawesome.com/ -->
<script src="https://kit.fontawesome.com/98a5e27706.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="chart"></div>
</body>
</html>
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/516099.html
標籤:d3.js
上一篇:D3.js錯誤:加載資源失敗:服務器回應狀態為406(不可接受)
下一篇:D3圈問題
