因此,我试图创建一个凹凸图,但其中的颜色还表示一个随时间变化的变量。但是这种变化在每个领域都是不同的。到目前为止,我的代码是:
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();}
然后我尝试以此更改颜色,但这显然将面积更改为第一年的颜色。
.attr("fill", d=> d3.interpolateRdBu((d.values[0].diff+1)/2))
我尝试从以下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();
}
因此,理想情况下,我希望将这两种解决方案结合起来。但是我不知道如何实现这一目标。有人有提示吗?
答案 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})`)