我想要一个“镜像”条形图(即一个看起来像声波的条形图),并使用d3 stack generator和线性y比例得出以下结果:
import * as d3 from "d3";
const WIDTH = 300;
const HEIGHT = 300;
const LIMIT = 4;
const container = d3.select("svg").append("g");
var data = [];
for (var i = 0; i < 100; i++) {
data.push({
index: i,
value: Math.random() * LIMIT
});
}
var stack = d3
.stack()
.keys(["value"])
.order(d3.stackOrderNone)
.offset(d3.stackOffsetSilhouette);
var series = stack(data);
var xScale = d3
.scaleLinear()
.range([0, WIDTH])
.domain([0, data.length]);
var yScale = d3
.scaleLinear()
.range([HEIGHT, 0])
.domain([0, LIMIT / 2]);
var xAxis = d3.axisBottom().scale(xScale);
var yAxis = d3.axisLeft().scale(yScale);
container
.selectAll(".bar")
.data(series[0])
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => {
return xScale(d.data.index);
})
.attr("y", d => {
return yScale(d[0]) / 2 - HEIGHT / 2;
})
.attr("width", WIDTH / series[0].length)
.attr("height", d => yScale(d[1]));
但是,我觉得我已经破解了y比例域和定位块的计算。
对于域,我目前对数据的upper limit / 2
使用0。
对于我的y位置,尽管高度直接基于刻度,即yScale(d[0]) / 2 - HEIGHT / 2;
,但我还是使用d => yScale(d[1])
。
是否有更好,更惯用的方式实现我想要的?
答案 0 :(得分:0)
自D3 v2以来,堆栈函数计算值的方式似乎已经改变,因此我不得不做两件事以更好的方式实现这一点。
我将y标度域切换为数据范围,然后通过-0.5 * HEIGHT
我修改了y位置和高度的计算:
.attr('y', d => yScale(d[1]))
.attr('height', d => yScale(d[0]) - yScale(d[1]));