【发布时间】:2016-04-23 01:57:37
【问题描述】:
我对 JavaScript 有点陌生,但我对一般编程有相当的经验。我怀疑我的问题可能与范围界定或将数组作为参数传递的细节有关,但我不确定。
高级目标是使用多个“节点”进行实时绘图,每个节点每秒生成 50 个点。我已经让这个工作直接运行到一个数组中,并由 dygraphs 和 C3.js 渲染,并很快意识到这是太多的数据,无法持续实时渲染。 Dygraphs 似乎在大约 30 秒后开始影响用户体验,而 C3.js 似乎在大约 10 秒后窒息。
下一个尝试是根据缩放级别抽取绘制的数据。
我将数据保存到一个“对象”中,我使用的对象有点像其他语言的字典。使用 AJAX 请求进展顺利。思路是利用AJAX请求创建一个大的数据缓冲区,并使用keys来存储单元根据序列号生成的数据作为keys。这运行良好,并且正在按预期填充对象。我觉得在我提出问题之前了解这个对象的“结构”是有益的。如下:
{
1: [[x10,y10], [x11,y11], [...], [x1n, y1n]],
2: [[x20,y20], [x21,y21], [...], [x2n, y2n]],
... : [ ... ]
a: [[xa0,ya0], [xa1,ya1], [...], [xan, yan]]
}
定期地,该数据的一个子集将用于生成 dygraphs 图。我正在抽取存储的数据并创建一个“绘图缓冲区”来保存实际数据的子集。
dygraphs 库以多种方式获取数据,但我想“本地”构造它,它只是一个数组数组。数组中的每个数组都是数据的“行”。所有行必须具有相同数量的元素才能排列成列。生成的数据可能同时也可能不同。如果数据 x 值完全匹配,则结果数据将如下所示,仅针对两个节点,因为 x10 = x20 = xn0:
[
[x10, y10, y20],
[x11, y11, y21],
[ ... ],
[xan, yan, yan]
]
请注意,这只是行中的 x 和 y。实际上,每个序列号的时间可能不对齐,因此可能更接近:
[
[x10, y10, null],
[x20, null, y20],
[x11, y11, y21],
[ ... ],
[xan, yan, yan]
]
对不起所有的背景。我们可以找到我遇到问题的代码。我定期尝试使用以下代码创建绘图缓冲区:
window.intervalId = setInterval(
function(){
var plotData = formatData(nodeData, 45000, 49000, 200);
/* dygraphs stuff here */
},
500
);
function formatData(dataObject, start, end, stride){
var smallBuffer = [];
var keys = Object.keys(dataObject);
keys.forEach(
function(key){
console.log('key: ', key);
mergeArrays(dataObject[key], smallBuffer, start, end, stride);
}
);
return smallBuffer;
}
function mergeArrays(sourceData2D, destDataXD, startInMs, endInMs, strideInMs){
/* ensure that the source data isn't undefined */
if(sourceData2D){
/* if the destDataXD is empty, then basically copy the
* sourceData2D into it as-is taking the stride into account */
if(destDataXD.length == 0){
/* does sourceData2D have a starting point in the time range? */
var startIndexSource = indexNear2D(sourceData2D, startInMs);
var lastTimeInMs = sourceData2D[startIndexSource][0];
for(var i=startIndexSource; i < sourceData2D.length; i++){
/* start to populate the destDataXD based on the stride */
if(sourceData2D[i][0] >= (lastTimeInMs + strideInMs)){
destDataXD.push(sourceData2D[i]);
lastTimeInMs = sourceData2D[i][0];
}
/* when the source data is beyond the time, then break the loop */
if(sourceData2D[i][0] > endInMs){
break;
}
}
}else{
/* the destDataXD already has data in it, so this needs to use that data
* as a starting point to merge the new data into the destination array */
var finalColumnCount = destDataXD[0].length + 1;
console.log('final column count: ', finalColumnCount);
/* add the next column to each existing row as 'null' */
destDataXD.forEach(
function(element){
element.push(null);
}
);
/* TODO: move data into destDataXD from sourceData2D */
}
}
}
添加一些信息,因为它可能不费吹灰之力就不言自明了。我创建了两个函数,“formatData”和“mergeArrays”。这些可以在一个函数中完成,但我更容易从概念上分离出“对象”域和“数组”域。 “formatData”函数简单地遍历存储在每个键中的所有数据,每次调用“mergeArray”例程。 “mergeArray”例程尚未完成,这是我遇到问题的地方。
第一次,formatData 应该创建一个空数组 - smallBuffer - 使用 mergeArrays 将数据合并到该数组中。第一次执行 'mergeArrays' 我看到 smallBuffer 确实正在创建并且是一个空数组。这个空数组作为参数提供给 'mergeArrays' 并且 - 第一次通过 - 这非常有效。下一次,“smallBuffer”数组不再为空,因此“mergeArrays”中的第二种情况被执行。我的第一步是计算列数,以便我可以适当地填充每一行。这工作正常,但有助于指出问题。下一步是简单地将空列的“null”值附加到每一行。这就是事情变得奇怪的地方。第一次通过“mergeData”后,destDataXD 仍包含来自先前执行的“空”数据。从本质上讲,'var smallBuffer = [];'实际上并没有清除并保留一些东西。直到接近尾声,这件事才明显。我无法准确解释 b/c 发生了什么我不完全理解,但 destDataXD 在最后不断增长“空值”,而没有按预期正确重置。
感谢您的宝贵时间,我期待听到您的想法,j
【问题讨论】:
-
创建一个有效的 sn-p(带有一些固定数据)来演示该问题会很有用,因为您的 sn-p 失败了,因为
nodeData不存在。 -
好主意。我应该包括 nodeData。感谢您花时间浏览和评论。
标签: javascript arrays parameters scope