3

我是 d3 的新手,并使用它来创建一个简单的图表,该图表使用数字数组,其中值“16”出现两次。

它为第二个“16”值生成带有一个“缺失”“矩形”元素的图表,当我检查 html 时,我看到两个“16”矩形具有相同的“y”值 72。

请告诉我我做错了什么,谢谢

代码:

var data = [4, 8, 15, 16, 23, 16];

var chart = d3.select("body").append("svg")
     .attr("class", "chart")
     .attr("width", 420)
     .attr("height", 20 * data.length);


var x = d3.scale.linear()
     .domain([0, d3.max(data)])
     .range([0, 420])

var y = d3.scale.ordinal()
     .domain(data)
     .rangeBands([0, 120]);

chart.selectAll("rect")
     .data(data)
     .enter().append("rect")
     .attr("y", y)
     .attr("width", x)
     .attr("height", y.rangeBand());
4

2 回答 2

10

您的代码的问题是您试图使用data数组中的值来创建序数范围内的范围。由于相同的输入值将始终映射到相同的输出值,这意味着两个输入16都映射到相同的范围范围72

如果您希望每个输入值都映射到自己的“条”,那么您需要使用数组索引而不是数组值。

首先你准备索引

var indices = d3.range(0, data.length);    // [0, 1, 2, ..., data.length-1]

然后使用它们来定义y比例域

var y = d3.scale.ordinal()
    .domain(indices)
    // use rangeRoundBands instead of rangeBands when your output units
    // are pixels (or integers) if you want to avoid empty line artifacts
    .rangeRoundBands([0, chartHeight]);  

最后,不是使用数组值作为输入,而是在映射到时使用数组索引y

chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("y", function (value, index) { 
        // use the index as input instead of value; y(index) instead of y(value)
        return y(index); 
    })
    .attr("width", x)
    .attr("height", y.rangeBand());

作为额外的奖励,如果数据量发生变化或您决定更改图表宽度或高度,此代码将自动重新缩放图表。

这是一个 jsFiddle 演示:http: //jsfiddle.net/q8SBN/1/

完整代码:

var data = [4, 8, 15, 16, 23, 16];
var indices = d3.range(0, data.length);

var chartWidth = 420;
var chartHeight = 120;

var chart = d3.select("body").append("svg")
     .attr("class", "chart")
     .attr("width", chartWidth)
     .attr("height", chartHeight);

var x = d3.scale.linear()
     .domain([0, d3.max(data)])
     .range([0, chartWidth])

var y = d3.scale.ordinal()
     .domain(indices)
     .rangeRoundBands([0, chartHeight]);

chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("y", function (value, index) { return y(index); })
    .attr("width", x)
    .attr("height", y.rangeBand());
于 2013-07-24T19:43:45.373 回答
0

您设置y矩形属性的方式将对所有重复元素使用相同的值。您可以像这样使用一些偏移量:

chart.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("y", function (d, i) {
       return (i * y.rangeBand()) + y.rangeBand();})
    .attr("width", x)
    .attr("height", y.rangeBand());

此外,您可能需要调整整个图表的高度才能看到所有波段。

于 2013-07-24T18:33:00.097 回答