Does the grouping in D3v7 changed? The graph below groups elements by all ribbons, all arcs and all labels. Means the data for one group is splitted into three elements. How can I group them to bundle each needed element into one group.
So instead of all ribbons, all arcs and all labels.. it should be:
group0
thisRibbony
thisArc
thisLabelgroup1
thisRibbony
thisArc
thisLabelgroup2
thisRibbony
thisArc
thisLabel
How it is:
What I wish for:
Each entry got an own g grouping element which contains the bundled data.
////////////////////////////////////////////////////////////
////////////////////// 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>

