首页 > 解决方案 > D3.js:从 Stack 函数计算 y 比例

问题描述

我想要一个“镜像”条形图(即看起来像声波的条形图),并使用 d3堆栈生成器和线性 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 比例域和定位块的计算。

对于我目前使用 0 到数据的域upper limit / 2

对于我的 y 位置,我使用yScale(d[0]) / 2 - HEIGHT / 2;尽管高度直接基于比例,即d => yScale(d[1]).

有没有更好、更惯用的方法来实现我想要的?

标签: javascriptd3.js

解决方案


自 D3 v2 以来,堆栈函数计算值的方式似乎发生了变化,因此我必须做两件事才能以更好的方式实现这一点。

我将我的 y 比例域切换为数据的范围,然后由-0.5 * HEIGHT

我修改了对 y 位置和高度的计算:

.attr('y', d => yScale(d[1]))
.attr('height', d => yScale(d[0]) - yScale(d[1]));

推荐阅读