每个区域的梯度不同

时间:2020-07-31 14:11:48

标签: d3.js

因此,我试图创建一个凹凸图,但其中的颜色还表示一个随时间变化的变量。但是这种变化在每个领域都是不同的。到目前为止,我的代码是:

chart = {
  const svg = d3.create("svg")
  .attr("viewBox", [0, 0, width, height])
  .style("overflow", "visible");

  svg.append("g")
  .call(xAxis);

  svg.append("g")
  .call(yAxis);

 const areaBand = d3.area()
.x((d, i) => x(data.dates[i]))
.y0(d => y(d.middle - d.votes/2))
.y1(d => y(d.middle + d.votes/2))

  const path = svg.append("g")
  .attr("stroke", "white")
  .attr("stroke-width", 1.5)
  .attr("stroke-miterlimit", 1)
.selectAll("path")
.data(data.series)
.join("path")
.attr("d", d => areaBand(d.values))

return svg.node();}

这将导致以下结果:enter image description here

然后我尝试以此更改颜色,但这显然将面积更改为第一年的颜色。

 .attr("fill", d=> d3.interpolateRdBu((d.values[0].diff+1)/2))

enter image description here 我尝试从以下stackoverflow问题中添加代码:d3.js chart area filling with different colors 因此,我以此作为测试:

chart = {
  
....

  const areaBand = d3.area()
    .x((d, i) => x(data.dates[i]))
    .y0(d => y(d.middle - d.votes/2))
    .y1(d => y(d.middle + d.votes/2))
  

  const path = svg.append("g")
      .attr("stroke", "white")
      .attr("stroke-width", 1.5)
      .attr("stroke-miterlimit", 1)
    .selectAll("g")
      .data(data.series)
    .enter().append("g")
  
  path.append("path")
    .attr("d", d => areaBand(d.values))
  .attr("fill", "url(#grad)")
  
    //.attr("fill", d=> d3.interpolateRdBu((d.values[0].diff+1)/2))
  var grad = path.append("defs")
     .append("linearGradient")
     .attr("id", "grad");
grad.append("stop").attr("offset", "0%").attr("stop-color", function(d) {return d.values[0].diff < 0 ? "red" : "blue";});
grad.append("stop").attr("offset", "10%").attr("stop-color", "yellow");
grad.append("stop").attr("offset", "10%").attr("stop-color", "red");
grad.append("stop").attr("offset", "20%").attr("stop-color", "red");

  

  return svg.node();
}

但是随后我又在每个区域获得了相同的颜色。 enter image description here

因此,理想情况下,我希望将这两种解决方案结合起来。但是我不知道如何实现这一目标。有人有提示吗?

请注意,我的数据如下所示: enter image description here

1 个答案:

答案 0 :(得分:1)

我认为,每条路径的梯度应不同。从Lars' answer开始,我们可以为每条路径创建一个渐变,并根据您的比例确定停靠点的位置。

要这样做,我们需要一个标尺,该标尺告诉我们索引i处当前梯度的位置。例如,如果我们有三个值,则此刻度将以这种方式起作用:

i | gradientScale(i)
--------------------
0 | 0
1 | 50
2 | 100

这使我们每次都能获取offset的值。如果i为1,则偏移量的值为“ 50%”。

这样,您可以拥有一个颜色函数,该颜色函数可以根据该值进行着色,就像您的示例中一样。

var color = d => d3.interpolateRdBu((d.diff+1)/2) // color here...

var innerLength = data.values[0].values.length
var gradientScale = d3.scaleBand()
  .domain(Array.from(Array(innerLength).keys())) // [0,1,2,...,length-1]
  .range([0, 100])

data.series.forEach((values,i) => {
  var grad = graph.append("defs")
    .append("linearGradient")
    .attr("id", (d,i) => `grad-${i}`)

  grad.selectAll("stop")
    .data(values)
    .append("stop")
    .attr("offset", `${gradientScale(i)}`)
    .attr("stop-color", d => color(d))
})

完成此操作后,对于您的路径,我们需要将每个路径与我们刚生成的相应渐变相关联:

path.append("path")
  .attr("d", d => areaBand(d.values))
  .attr("fill", (d,i) => `url(#grad-${i})`)