gpt4 book ai didi

javascript - D3js - 从特定域的 d3.line() 获取最大值

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:11:29 24 4
gpt4 key购买 nike

我正在制作一个多折线图,并且我实现了一个画笔以能够放大到 x 轴上的特定域。但是,当我放大时,我希望 y 轴沿比例缩放,以便其域从 [0, maxY] 开始,其中 maxY 是最大 y 值x 轴上的当前选择。为了生成我正在使用的行 d3.line() (它在 x 和 y 值之间有联系)。这就是我目前计算 maxY 值的方式:

//Find max and min values in data to set the domain of the y-axis
var maxArray = updatedData.map(function(variable){
//First map the values in the array to a new array
var valuesArray = variable.values.map(function(d){
return d.value;
})
//Find max value in array
return Math.max(...valuesArray);
});
var maxY = Math.max(...maxArray);

这里是我设置比例并创建 d3.line() 的地方:

var xScale = d3.scaleTime()
.range([0, chartWidth]);
var yScale = d3.scaleLinear()
.domain([0, maxY])
.range([chartHeight, 0]);

var brush = d3.brushX()
.on("end", brushend);

var line = d3.line()
.curve(d3.curveBasis)
.x(function(d) {return xScale(d.date)})
.y(function(d) {return yScale(d.value)})

//Save this to be able to zoom back out
var originalDomain = [new Date(data[0].Timestamp), new Date(data[data.length-1].Timestamp)];
xScale.domain(originalDomain);

这是我设置新的 xScale.domain() 并放大该间隔的代码(在刷完结束时调用):

function brushend(){
//sourceEvent - the underlying input event, such as mousemove or touchmove.
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
var brushInterval = d3.event.selection; //The interval of the current brushed selection
//If the function is called with no selection: ignore
if(!brushInterval) return;
//Enable reset button
resetButton.attr("disabled", null)
.on("click", resetAxis);

var newDomain = brushInterval.map(xScale.invert, xScale);

//TODO: Find max and min values in data to set the domain of the y-axis

xScale.domain(newDomain);
chart.selectAll(".line")
.transition()
.duration(1000)
.attr("d", function(d){ return line(d.values)});
chart.select(".x-axis")
.transition()
.duration(1000)
.call(xAxis);
//Remove the visual brush
d3.select(".brush").call(brush.move, null);
}

我想做的是在当前选定的域中找到最大的 y 值。我知道我可以过滤数据值以删除不在当前选定域中的数据值,然后从中计算最大值(就像我对原始域所做的那样)。但似乎应该有一个更简单的解决方案。我没有在 d3.line() 的文档中找到任何可以计算最大值的函数。

有什么简单的方法可以从 d3.line() 计算最大值吗?

谢谢

最佳答案

没有真正更简单的解决方案,因为您必须以某种方式过滤值以仅考虑您选择的 x 域中的值。但是,使用两个嵌套调用 d3.max()您至少可以通过避免额外调用 .filter() 来给它一个愉快的外观并节省一些迭代。由于 d3.max() 将忽略 null 值,如果当前数据在x 域的边界。要获得最大值,您可以使用如下内容:

const maxY = xDomain => d3.max(updatedData, variable => 
d3.max(
variable.values,
v => v.Timestamp >= xDomain[0] && v.Timestamp <= xDomain[1] ? v.value : null
)
);

查看以下工作演示片段:

var updatedData = [{
values: [{Timestamp:0, value:1},{Timestamp:1, value:5},{Timestamp:2, value:10},{Timestamp:3, value:3},{Timestamp:4, value:30}]
}, {
values: [{Timestamp:0, value:19},{Timestamp:1, value:12},{Timestamp:2, value:13},{Timestamp:3, value:8},{Timestamp:4, value:50}]
}];

const maxY = xDomain => d3.max(updatedData, variable =>
d3.max(
variable.values,
v => (!xDomain || v.Timestamp >= xDomain[0] && v.Timestamp <= xDomain[1]) ? v.value : null
)
);

console.log(maxY()); // Default, check all values: max 50
console.log(maxY([1,3])); // Max 13
console.log(maxY([0,3])); // Max 19
<script src="https://d3js.org/d3.v4.js"></script>

关于javascript - D3js - 从特定域的 d3.line() 获取最大值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45483041/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com