为什么域不在D3中使用d3.max(数据)?

时间:2012-03-13 16:43:44

标签: d3.js

我是D3的新手并且正在玩散点图。我无法让d3.max(数据)在设置域时正常工作!

我有以下设置随机数据集:

var data = [];
      for (i=0; i < 40; i++){
            data.push({"x": i/40, "y": i/8, "a": Math.floor(Math.random() * 3), "x2": Math.random()});
        }

接下来设置我的坐标:

 var x = d3.scale.linear().domain([0, 1]).range([0 + margin, w-margin]),
            y = d3.scale.linear().domain([0, d3.max(data)]).range([0 + margin, h-margin]),
            c = d3.scale.linear().domain([0, 3]).range(["hsl(100,50%,50%)", "rgb(350, 50%, 50%)"]).interpolate(d3.interpolateHsl);

这将所有40个点放在一条水平线上。如果我用'5'替换d3.max(数据)那么它是一个对角线(尽管从左上角到右下角,我仍然在努力翻转y坐标)。为什么d3.max(数据)没有按预期工作?

3 个答案:

答案 0 :(得分:10)

d3.max()需要一组数字,而不是对象。 data的元素具有内部键值结构,d3.max()无法知道最大值。{1}}。您可以使用类似jQuery's $.map的内容来获取所需对象的元素,然后取最大值,例如

var maxy = d3.max($.map(data, function(d) { return d.y; }));

编辑:

正如下面的评论所指出的那样,你甚至不需要JQuery,因为.map()是一个原生的Array方法。然后代码就变成了

var maxy = d3.max(data.map(function(d) { return d.y; }));

甚至更简单(对于那些没有实现Array.map()的浏览器),使用d3.max的可选第二个参数来告诉它如何访问数组中的值

var maxy = d3.max(data, function(d) { return d.y; });

答案 1 :(得分:3)

d3.max可以找到API文档here

  

#d3。 max 数组 [,访问者])

     

使用自然顺序返回给定数组中的最大值。如果   数组为空,返回undefined。可选的访问器功能   可以指定,这相当于调用array.map(accessor)   在计算最大值之前。与内置的Math.max不同,这个   方法忽略未定义的值;这对计算有用   一个规模的领域,而只考虑定义的区域   数据。此外,使用自然顺序比较元素   比数字顺序。例如,[“20”,“3”]的最大值为“3”,   而[20,3]的最大值为20。

将此信息应用于我们得到的原始问题:

function accessor(o){
    return o.y;
}
var y = d3.scale.linear()
        .domain([0, d3.max(data, accessor)])
        .range([0 + margin, h-margin]);

如果你最终使用了许多访问者功能,你可以建立一个工厂。

function accessor(key) {
    return function (o) {
        return o[key];
    };
}
var x = d3.scale.linear()
        .domain([0, d3.max(data, accessor('x'))])
        .range([...]),
    y = d3.scale.linear()
        .domain([0, d3.max(data, accessor('y'))])
        .range([...]);

答案 2 :(得分:0)

我遇到了处理关联数组的类似问题。我的数据如下所示:[{&#34; year_decided&#34;:1982,&#34; total&#34;:0},{&#34; year_decided&#34;:&#34; 1983&#34; &#34;总计&#34;:&#34; 847&#34;},...}]

在返回值之前简单地传递parseInt。

var yScale = d3.scale.linear()
    .domain([0, d3.max(query,function(d){ return parseInt(d["Total"]); }) ])
    .range([0,h]);