d3刻度在数据中具有相同值的使用错误? [英] Wrong usage of d3 scale with same values in data?

查看:158
本文介绍了d3刻度在数据中具有相同值的使用错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to d3 and using it for creating a simple chart using array of numbers where the value '16' appears twice in it.

图表与一个'缺少''rect'元素为第二'16'值,当我检查html我看到两个'16'rect有相同的'y'值72。

It generate the chart with one 'missing' 'rect' element for the 2nd '16' value, when I check the html I see that both '16' rect has same 'y' value of 72.

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

Please tell me what I'm doing wrong, thanks

代码:

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


推荐答案

您的代码的问题是,使用数据数组中的值在顺序尺度上创建范围带。由于相同的输入值将始终映射到相同的输出值,这意味着两个输入 16 被映射到相同的范围带 72

The problem with your code is that you are trying to use the values from your data array to create range bands on an ordinal scale. Since the same input value will always be mapped to the same output value that means that both inputs 16 get mapped to the same range band 72.

如果你想要每个输入值映射到自己的bar,那么你需要使用数组索引而不是数组值。

If you want each input value to be mapped to its own "bar" then you need to use array indices instead of array values.

首先准备索引

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

Finally, instead of using array values as inputs use array indices when mapping to 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());

另外一个好处是,如果数据量改变或者你决定

As an added bonus this code will automatically rescale the chart if the amount of data changes or if you decide to change the chart width or height.

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

Here's a jsFiddle demo: 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());

这篇关于d3刻度在数据中具有相同值的使用错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆