我有一个数组timeSeries,让我们说10个系列,每个100个数据点。我有另外一个包含100个日期的数组日期。
如何让d3在同一图表上绘制10个系列,使用100个日期作为x值,将100个相应值(例如timeSeries [0])作为y值?
需要说明的是,timeSeries中的10个数组只有y值 - 将它们视为价格序列。这10个阵列(每个100个价格)完全映射到日期中的100个日期,我需要以某种方式进入这个日期。如果只有一个价格序列,我会将它们解析成一个数组并执行d.date和d.price,但是它们可能效率不高10(或1000)?
这让我走到了一半:
canvas.selectAll("path")
.data(timeSeries)
.enter()
.append("path")
.attr("class", "line")
.attr("d", d3.line().x((d,i) => x(i)).y(d => y(d)));
现在我只需要找到一种方法来使用日期而不是我......
实现这一目标的最有效方法是什么,没有10个关联数组,每个关联数组都包含日期?我可能会把它缩放到100或1000,所以我希望尽可能保持精益。
谢谢!
[加分问题:假设我在timeSeries中添加了另一层嵌套,即有10个系列的2D数组 - 为什么不(d => y(d [0]))绘制任何东西,即使控制台输出与在上面的情况?]
既然你说过......
10个数组(每个100个价格)精确映射到日期中的100个日期[数组]
...你只需要那些日期的索引。
所以,这可以是你的线路生成器:
var lineGenerator = d3.line()
.x((d, i) => xScale(dates[i]))
//index here--------------^
这是一个非常基本的演示。我正在创建2011年至2017年的日期数组......
var dates = d3.range(2011, 2018, 1).map(d => d3.timeParse("%Y")(d));
...然后创建一个包含10个内部数组的数组,每个数组为y轴提供10个随机值:
var data = d3.range(10).map(d => d3.range(10).map(d => Math.random() * 150));
结果如下:
var dates = d3.range(2011, 2018, 1).map(d => d3.timeParse("%Y")(d));
var data = d3.range(10).map(d => d3.range(10).map(d => Math.random() * 150));
var svg = d3.select("svg");
var xScale = d3.scaleTime().range([0, 300]).domain(d3.extent(dates));
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var lineGenerator = d3.line()
.x((d, i) => xScale(dates[i]))
.y(d => d);
var lines = svg.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("d", lineGenerator)
.style("fill", "none")
.style("stroke", (d, i) => colors(i))
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>