[英]Reduce the size of a large data set by sampling/interpolation to improve chart performance
我有一大组(> 2000)时间序列数据,我想在浏览器中使用 d3 显示这些数据。 D3 非常适合向用户显示数据的子集(~100 点),但我也想要一个“上下文”视图(像这样)来显示整个数据集并允许用户选择子区域来详细查看.
然而,当试图在 d3 中显示那么多点时,性能非常糟糕。 我觉得一个好的解决方案是选择一个数据样本,然后使用某种插值(样条、多项式等,这是我知道如何做的部分)来绘制一条与实际数据。
但是,我不清楚我应该如何选择子集。 数据(如下所示)具有相当平坦的区域,在这些区域中,合适的插值需要较少的样本,而在绝对导数非常高的其他区域,需要更频繁的采样。
更复杂的是,数据存在间隙(生成数据的传感器出现故障或超出范围),我想将这些间隙保留在图表中,而不是通过它们进行插值。 不过,间隙的检测相当简单,在使用插值绘制整个数据集后简单地将它们剪掉似乎是一个合理的解决方案。
我在 JavaScript 中这样做,但是任何语言的解决方案或问题的数学答案都可以。
您可以使用d3fc-sample模块,它提供了许多不同的数据采样算法。 API 如下所示:
// Create the sampler
var sampler = fc_sample.largestTriangleThreeBucket();
// Configure the x / y value accessors
sampler.x(function (d) { return d.x; })
.y(function (d) { return d.y; });
// Configure the size of the buckets used to downsample the data.
sampler.bucketSize(10);
// Run the sampler
var sampledData = sampler(data);
您可以在网站上看到它运行的示例:
https://d3fc.io/examples/sample/
最大三角形三桶算法对“不完整”的数据非常有效。 它不会改变桶的大小,但会确保包括峰值/谷值,从而很好地表示采样数据。
我知道这并不能完全回答你的问题,但这个库可能会帮助你在渲染过程中简化你的线条。 不确定他们是否处理数据差距。
我的建议是在更长或更短的时间间隔内平均(而不是子样本)并将这些平均值绘制为水平条。 我认为这对用户来说是非常容易理解的——如果你尝试更高级的东西,你可能会放弃准确解释发生了什么的能力。 我假设您可以让用户选择放大或缩小以显示更多或更少的细节。
您也许能够让数据库引擎为您计算间隔内的平均值,因此这也是一个潜在的加速。
至于要选择的时间间隔,您可以尝试 (1) 固定间隔,例如 1 秒、15 秒、1 分钟、15 分钟、小时、天或其他; 这可能让用户更容易理解,或者 (2) 选择间隔以在整个时间范围内设置固定数量的单位,例如,如果您决定以 100 个单位显示 7 小时的数据,则每个单位 = 252 秒.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.