我用这个https://www.d3-graph-gallery.com/graph/chord_colors.html创建了一个和弦图。但是我不喜欢组之间链接的颜色只有一种颜色。因此决定将其平滑地从第一组的颜色过渡到第二组的颜色。我的代码看起来像这样。
svg.datum(res)
.append("g")
.selectAll("path")
.data(function(d) { return d; })
.enter()
.append("path")
.attr("d", d3.ribbon()
.radius(200)
)
.style("fill", function(d){
//make a color transition
return (d3.scaleLinear()
.domain([0, 2])
.range([colors[d.source.index], colors[d.target.index]])
.interpolate(d3.interpolateHcl))
}) // colors depend on the source group. Change to target otherwise.
.style("stroke", "black");
但是它似乎不起作用,因为现在组之间的链接全都是黑色的。谁能帮我解决这个问题?
// create the svg area
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", 440)
.attr("height", 440)
.append("g")
.attr("transform", "translate(220,220)")
// create a matrix
var matrix = [
[0, 5871, 8916, 2868],
[1951, 0, 2060, 6171],
[8010, 16145, 0, 8045],
[1013, 990, 940, 0]
];
// 4 groups, so create a vector of 4 colors
var colors = ["#440154ff", "#31668dff", "#37b578ff", "#fde725ff"]
// give this matrix to d3.chord(): it will calculates all the info we need to draw arc and ribbon
var res = d3.chord()
.padAngle(0.05)
.sortSubgroups(d3.descending)
(matrix)
// add the groups on the outer part of the circle
svg
.datum(res)
.append("g")
.selectAll("g")
.data(function(d) {
return d.groups;
})
.enter()
.append("g")
.append("path")
.style("fill", function(d, i) {
return colors[i]
})
.style("stroke", "black")
.attr("d", d3.arc()
.innerRadius(200)
.outerRadius(210)
)
// Add the links between groups
svg
.datum(res)
.append("g")
.selectAll("path")
.data(function(d) {
return d;
})
.enter()
.append("path")
.attr("d", d3.ribbon()
.radius(200)
)
.style("fill", function(d) {
return (colors[d.source.index])
}) // colors depend on the source group. Change to target otherwise.
.style("stroke", "black");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id="my_dataviz"></div>
答案 0 :(得分:0)
您可以使用radial gradients。与线性渐变形成一个从一种颜色到另一种颜色的正方形不同,径向渐变在每个方向上都发生变化。这对于曲线非常有用,因为它们的唯一常数是它们趋向于远离源而不是距离方向。
我为每个链接放置了一个径向渐变,在每个源上都有一个中心,并在每个方向上将颜色更改为目标的颜色。这样,每个和弦在逻辑方向上都有清晰的渐变。
const size = 440;
// create the svg area
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", size)
.attr("height", size)
.append("g")
.attr("transform", "translate(" + (size / 2) + ", " + (size / 2) + ")");
var defs = svg.append('defs');
// create a matrix
var matrix = [
[0, 5871, 8916, 2868],
[1951, 0, 2060, 6171],
[8010, 16145, 0, 8045],
[1013, 990, 940, 0]
];
// 4 groups, so create a vector of 4 colors
var colors = ["#440154ff", "#31668dff", "#37b578ff", "#fde725ff"]
// give this matrix to d3.chord(): it will calculates all the info we need to draw arc and ribbon
var res = d3.chord()
.padAngle(0.05)
.sortSubgroups(d3.descending)
(matrix)
// add the groups on the outer part of the circle
svg
.datum(res)
.append("g")
.selectAll("g")
.data(function(d) {
return d.groups;
})
.enter()
.append("g")
.append("path")
.style("fill", function(d, i) {
return colors[i]
})
.style("stroke", "black")
.attr("d", d3.arc()
.innerRadius(size / 2 - 20)
.outerRadius(size / 2 - 10)
)
// Add one gradient for each link
var gradient = defs.selectAll("radialGradient")
.data(res)
.enter()
.append("radialGradient")
.attr("id", function(d) {
return "gradient-" + d.source.index + '-' + d.target.index;
})
.each(function(d) {
var centerAngle = (d.source.endAngle - d.source.startAngle) / 2;
centerAngle += d.source.startAngle;
const radius = 0.5;
d3.select(this)
.attr('cx', function() {
return Math.sin(centerAngle) * radius + 0.5;
})
.attr('cy', function() {
return -Math.cos(centerAngle) * radius + 0.5;
})
.attr('r', 1);
});
gradient.append("stop")
.attr('class', 'start')
.attr("offset", "0%")
.attr("stop-color", function(d) {
return colors[d.source.index];
})
.attr("stop-opacity", 1);
gradient.append("stop")
.attr('class', 'end')
.attr("offset", "100%")
.attr("stop-color", function(d) {
return colors[d.target.index];
})
.attr("stop-opacity", 1);
// Add the links between groups
svg
.datum(res)
.append("g")
.selectAll("path")
.data(function(d) {
return d;
})
.enter()
.append("path")
.attr("d", d3.ribbon()
.radius(size / 2 - 20)
)
.style("fill", function(d) {
return "url(#gradient-" + d.source.index + '-' + d.target.index + ")";
}) // colors depend on the source group. Change to target otherwise.
.style("stroke", "black");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<div id="my_dataviz"></div>