首页 > 解决方案 > D3.JS yScale 仅返回一个值的“未定义”

问题描述

我第一次使用 D3.js,我用这段代码绘制了一个条形图。

var dataset = [20, 55, 30, 40, 50, 35, 97, 75, 100, 45];
var w = 500;
var h =100;
var xScale = d3.scaleBand()
                .domain(d3.range(dataset.length))
                .rangeRound([0,w])
                .paddingInner(0.05);

var yScale = d3.scaleBand()
                .domain(d3.range(d3.max(dataset)))
                .rangeRound([0,h]);

var svg = d3.select("#chart")
            .append("svg")
            .attr("width", w)
            .attr("height", h);
svg.selectAll("rect")
    .data(dataset)
    .enter()
    .append("rect")
    .attr("x", function(d,i) {
        return xScale(i);
    })
    .attr("y",function(d){console.log(yScale(d)); return h - yScale(d);})
    .attr("width", xScale.bandwidth())
    .attr("fill", function(d) {if(d<50) { return "blue" }
            else if (d>=50) { return "red" }; })
    .attr("height", function(d){return yScale(d);
    });

但我得到了这个结果: 结果

我无法理解为什么我会为一个特定的值得到“未定义”。

标签: javascriptd3.js

解决方案


问题在于 yScale 域,并使用 d3.range 设置域。

d3.range(100) 创建一个包含 100 个元素的数组,其值从 0 到 99。因此,当您尝试获取 yScale(100) 时,“100”不在域中。

对于您的数据,您建议使用线性比例,例如

var yScale = d3.scaleLinear()
 .domain([0, d3.max(dataset)])
 .rangeRound([0,h]);

或者如果需要使用 d3.range,将元素数量设置为 1 + 最大值,例如:

var yScale = d3.scaleRange()
.domain(d3.range(d3.max(dataset) + 1))
.rangeRound([0,h]);

推荐阅读