如何从要在 d3.scale.linear().domain() 中使用的对象数组中获取最大值
Posted
技术标签:
【中文标题】如何从要在 d3.scale.linear().domain() 中使用的对象数组中获取最大值【英文标题】:How to get maximum value from an array of objects to use in d3.scale.linear().domain() 【发布时间】:2013-04-27 06:07:45 【问题描述】:我有一个外部 csv 文件,其列中的数据如下:
name, field_goal_attempts, field_goal_makes
我正在尝试使用线性比例,但在获取我的域的最大值时遇到了困难。
var yScale = d3.scale.linear()
.domain(0, d3.max(...
我很困惑:
1) 我应该把yScale函数放在外面还是里面
d3.csv("filename.csv", function(data)
回调函数;和
2) 如何获取 field_goal_attempts 列中项目的最大值,然后输入 yScale 函数。
这是我目前的代码:
var yScale = d3.scale.linear()
.domain([0, 4000]) //d3.max(data, function(d) return d )])
.range([0, 500]);
d3.csv("test.csv", function (data)
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("fill", "blue")
.attr("x", magic_number) // I'm not concerned about the magic numbers at this point :)
.attr("y", 0)
.attr("width", another_magic_number)
.attr("height", function (d)
return d.field_goal_attempts
)
.attr("id", function (d, i)
return i
);
);
【问题讨论】:
【参考方案1】:您的 csv 文件中的数据将在您传递给 csv 函数的回调中(在您的情况下为“data”参数)。因此,您可以在 csv 函数之外定义 yScale,但如果您希望最大值依赖于数据,则需要在回调中进行设置。
至于找到最大值,许多在数组上工作的 D3 函数将接受针对您的场景的可选访问器函数。所以计算我将使用的最大值:
var max = d3.max(data, function(d) return +d.field_goal_attempts; );
因此,您可以通过以下两种方式之一将它们组合在一起:
var yScale = d3.scale.linear().domain(0,100);
d3.csv("test.csv", function(data)
var max = d3.max(data, function(d) return +d.field_goal_attempts; );
yScale.domain([0,max]);
...
或
d3.csv("test.csv", function(data)
var max = d3.max(data, function(d) return +d.field_goal_attempts; );
var yScale = d3.scale.linear().domain([0,max]);
...
如果你想同时找到最大值和最小值,那么我建议使用 d3.extent(...) 它也应该接受一个访问器函数,并将返回一个长度为 2 的数组,其中包含最小值和最大值。
【讨论】:
感谢您的帮助。这是我的第一个问题,非常感谢提供的帮助和友好的方式。我接受了你对 Christopher Chiche 的回答,因为它不需要循环,感觉“更多 d3”。我实现了您的第二个解决方案,但必须进行两项更改才能使其正常工作,即在 d.field_goal_attempts 前面使用“+”,以便 max 返回 2000 而不是 600,并将 domain() 中的值括在方括号中。我是新手,所以我不想更改你的代码以防我错了,但我想告诉你会很好:)。再次感谢! 是的,如果将值存储为字符串,则需要在 field_goal_attempts 前面加上“+”。你对 domain 是一个数组的论点是绝对正确的!我将进行编辑。很高兴我能帮上忙! 哇,不要在开头加上 + 给了我这么多问题,你是一个救生员@Superboggly! 这个答案对我作为 d3 新手非常有帮助。我在计算嵌套数据的最大值时遇到了同样的困难。【参考方案2】:1) 只要在计算最大值时更新函数内部的域,yScale 就可以留在d3.csv()
函数之外。例如,您可以在 d3.csv()
内部执行以下操作:
yScale.domain([0, my_max])
2) 计算最大值,这里是我常用的方法:
//Create list containing only field_goal_attempts
field_goal_attempts_list = data.forEach(function(d)return d.field_goal_attempts)
//Compute max using d3.max() function
field_goal_attempts_max = d3.max(field_goal_attempts_list)
确实,将这样的函数传递给d3.max()
会很棒,但据我所知并非如此。首先计算列表然后计算最大值的优点是,如果你想计算最小值、平均值或其他任何东西,你可以做更少的计算。
【讨论】:
感谢您的帮助。这是我的第一个问题,非常感谢提供的帮助和友好的方式。我会投票赞成你的答案,但我对这样做的声誉很害羞:(。我接受了@Superbogly 的回答,因为它忽略了对 forEach 方法的需求,“感觉”“更多 d3”——听起来很糟糕,不是吗,无论如何,将“Pythonic”这个词归咎于 Python 人群 - 我对编码和 *** 都是新手,所以我只想表达我对你的回应的感激之情。谢谢 :) 不客气。他的回答确实比我的好。我通过阅读学到了新东西。以上是关于如何从要在 d3.scale.linear().domain() 中使用的对象数组中获取最大值的主要内容,如果未能解决你的问题,请参考以下文章