gpt4 book ai didi

javascript - 使用 d3 中的相邻数据值

转载 作者:行者123 更新时间:2023-12-03 04:28:59 25 4
gpt4 key购买 nike

我正在使用 D3 来可视化一些随时间更新的数据,并且我有一个 (x,y) 坐标列表;例如:

[[0.1,0.2],
[0.3,0.4],
[0.5,0.4],
[0.7,0.2]]

我想从(0,0)到每对相邻坐标绘制三 Angular 形,例如,第一个三 Angular 形的坐标为(0,0),(0.1,0.2),(0.3,0.4)第二个三 Angular 形的坐标为 (0,0)、(0.3,0.4)、(0.5,0.4) 等等。

我的问题是是否有办法访问 D3 中的“相邻”值; D3 范例似乎是传递一个函数来分别访问每个数据值。所以我能够做到这一点,但只能通过从各个点的整个数据集显式构建三 Angular 形坐标的新数据集:

var margin = {top: 20, right: 20, bottom: 30, left: 40},
width = 500 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

// add the graph canvas to the body of the webpage
var svg = d3.select("div#plot1").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var axis = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var xsc = d3.scaleLinear()
.domain([-2, 2]) // the range of the values to plot
.range([ 0, width ]); // the pixel range of the x-axis

var ysc = d3.scaleLinear()
.domain([-2, 2])
.range([ height, 0 ]);
var closedLine = d3.line()
.x(function(d){ return xsc(d[0]); })
.y(function(d){ return ysc(d[1]); })
.curve(d3.curveLinearClosed);

function attrfunc(f,attr) {
return function(d) {
return f(d[attr]);
};
}


function doit(data)
{
var items = axis.selectAll("path.item")
.data(data);
items.enter()
.append("path")
.attr("class", "item")
.merge(items)
.attr("d", attrfunc(closedLine, "xy"))
.attr("stroke", "gray")
.attr("stroke-width", 1)
.attr("stroke-opacity", function(d) { return 1-d.age;})
.attr("fill", "gray")
.attr("fill-opacity", function(d) {return 1-d.age;});
items.exit().remove();
}

var state = {
t: 0,
theta: 0,
omega: 0.5,
A: 1.0,
N: 60,
history: []
}
d3.timer(function(elapsed)
{
var S = state;
if (S.history.length > S.N)
S.history.shift();
var dt = Math.min(0.1, elapsed*1e-3);
S.t += dt;
S.theta += S.omega * dt;
var sample = {
t: S.t,
x: S.A*(Math.cos(S.theta)+0.1*Math.cos(6*S.theta)),
y: S.A*(Math.sin(S.theta)+0.1*Math.sin(6*S.theta))
}
S.history.push(sample);

// Create triangular regions
var data = [];
for (var k = 0; k < S.history.length-1; ++k)
{
var pt1 = S.history[k];
var pt2 = S.history[k+1];
data.push({age: (S.history.length-1-k)/S.N,
xy:
[[0,0],
[pt1.x,pt1.y],
[pt2.x,pt2.y]]
});
}
doit(data);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.min.js"></script>
<div id="plot1">
</div>

最佳答案

您可以使用第二个参数(即索引)获取数据数组中的任何点。

当您将数据传递给任何 D3 方法时,传统上使用名为 d 的参数(用于数据),实际上您正在使用 data[i]i 是当前索引。您可以更改此索引以获取当前数据之前或之后的数据点。

因此,在任何 D3 方法中:

.attr("foo", function(d, i){
console.log(d)//this is the current datum
console.log(data[i])//this is the same current datum!
console.log(data[i + 1])//this is the next (adjacent) datum
});

这是一个简单的代码片段,显示了这一点:

var data = ["foo", "bar", "baz", "foobar", "foobaz"];

var foo = d3.selectAll("foo")
.data(data)
.enter()
.append("foo")
.attr("foo", function(d, i) {
if (data[i + 1]) {
console.log("this datum is " + d + ", the next datum is " + data[i + 1]);
}
})
<script src="https://d3js.org/d3.v4.min.js"></script>

看看if语句:我们必须检查是否有data[i + 1],因为当然,最后一个数据点没有它后面的相邻数据。

这是使用您的数据数组的演示:

var svg = d3.select("svg");

var scale = d3.scaleLinear()
.domain([-1, 1])
.range([0, 150]);

var data = [
[0.1, 0.2],
[0.3, 0.4],
[0.5, 0.4],
[0.7, 0.2]
];

var triangles = svg.selectAll("foo")
.data(data)
.enter()
.append("polygon");

triangles.attr("stroke", "teal")
.attr("stroke-width", 2)
.attr("fill", "none")
.attr("points", function(d, i) {
if (data[i + 1]) {
return scale(0) + "," + scale(0) + " " + scale(data[i][0]) + "," + scale(data[i][1]) + " " + scale(data[i + 1][0]) + "," + scale(data[i + 1][1]) + " " + scale(0) + "," + scale(0);
}
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="150" height="150"></svg>

PS:我没有使用您的代码片段,因为我使用多边形绘制三 Angular 形,但原理是相同的。

关于javascript - 使用 d3 中的相邻数据值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43576863/

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