D3.js:从Stack函数计算y缩放

时间:2018-09-24 13:49:56

标签: javascript d3.js

我想要一个“镜像”条形图(即一个看起来像声波的条形图),并使用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])

是否有更好,更惯用的方式实现我想要的?

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