简体   繁体   English

和弦图中的平滑颜色过渡

[英]smooth color transition in chord diagram

I used this https://www.d3-graph-gallery.com/graph/chord_colors.html to create a chord diagram.我使用这个https://www.d3-graph-gallery.com/graph/chord_colors.html来创建一个和弦图。 But I didn't like that the colors of the links between the groups have only 1 color.但我不喜欢组之间链接的颜色只有 1 种颜色。 So decided to make it so that it smoothly transitions from the color of the first group to the color of the second group.所以决定让它从第一组的颜色平滑过渡到第二组的颜色。 My code looks like this.我的代码看起来像这样。

   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");

but it doesn't seem to work, because now the links between the groups are all black.但是好像不行,因为现在群之间的链接全是黑的。 Can anyone help me fix this?谁能帮我解决这个问题?

 // 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>

You can use radial gradients for that.您可以为此使用径向渐变 In contrast to linear gradients, which format a square that goes from one colour to the other, a radial gradient changes in every direction.与形成从一种颜色到另一种颜色的正方形的线性渐变不同,径向渐变在每个方向上都会发生变化。 This is very useful for curved lines, since their only constant is that they tend to get further from the source, but not their direction.这对于曲线非常有用,因为它们唯一的常数是它们倾向于远离源,而不是它们的方向。

I've placed a radial gradient for every link, with a centre at every source, and a colour change to the colour of the target in every direction.我为每个链接放置了一个径向渐变,在每个源处都有一个中心,并且在每个方向上都会改变目标颜色的颜色。 That way, every chord has a clear gradient in a logical direction.这样,每个和弦在逻辑方向上都有清晰的渐变。

 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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM