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

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

问题描述

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

它为第二个 '16' 值生成了一个 'missing' 'rect' 元素的图表,当我检查 html 时,我看到两个 '16' rect 的 'y' 值都相同,为 72.

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

代码:

var 数据 = [4, 8, 15, 16, 23, 16];var chart = d3.select("body").append("svg").attr(类",图表").attr("宽度", 420).attr("高度", 20 * data.length);var x = d3.scale.linear().domain([0, d3.max(data)]).range([0, 420])var y = d3.scale.ordinal().域(数据).rangeBands([0, 120]);chart.selectAll("rect").data(数据).enter().append("rect").attr("y", y).attr("宽度", x).attr("高度", y.rangeBand());

解决方案

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

如果您希望每个输入值都映射到它自己的bar",那么您需要使用数组索引而不是数组值.

首先准备索引

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

然后你用它们来定义y尺度域

var y = d3.scale.ordinal().domain(索引)//当你的输出单位使用 rangeRoundBands 而不是 rangeBands//如果您想避免空行伪影,则为像素(或整数).rangeRoundBands([0, chartHeight]);

最后,在映射到 y

时,不要使用数组值作为输入,而是使用数组索引

chart.selectAll("rect").data(数据).enter().append("rect").attr(y",函数(值,索引){//使用索引作为输入而不是值;y(index) 而不是 y(value)返回 y(索引);}).attr("宽度", x).attr("高度", y.rangeBand());

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

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

完整代码:

var 数据 = [4, 8, 15, 16, 23, 16];var 索引 = d3.range(0, data.length);var chartWidth = 420;var chartHeight = 120;var chart = d3.select("body").append("svg").attr(类",图表").attr("宽度", 图表宽度).attr("高度", 图表高度);var x = d3.scale.linear().domain([0, d3.max(data)]).range([0, chartWidth])var y = d3.scale.ordinal().domain(索引).rangeRoundBands([0, chartHeight]);chart.selectAll("rect").data(数据).enter().append("rect").attr("y", function (value, index) { return y(index); }).attr("宽度", x).attr("高度", y.rangeBand());

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.

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

code:

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

解决方案

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.

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

First you prepare the indices

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

Then you use them to define the y scale domain

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

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.

Here's a jsFiddle demo: http://jsfiddle.net/q8SBN/1/

Complete code:

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天全站免登陆