我是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(数据)没有按预期工作?
答案 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]);