Reputation: 2609
I have a list of timeserieses. Each timeseries conists of objects that contain a timestamp and a value. The timestamps of the different timeserieses may or may not overlap. I want to plot these timeserieses in one DyGraph.
An example:
data["first series"] = [{timestamp: 1, value: 10.3},
{timestamp: 3, value: 12.5}]
data["second series"] = [{timestamp: 2, value: 11.5},
{timestamp: 3, value: 13.0},
{timestamp: 4, value: 14.3}]
What's the most efficent way to transform my input data to a form suitable for DyGraph?
Upvotes: 0
Views: 640
Reputation: 17867
I had to do the exact same for a dygraphs project recently. At a high level, you will need to create a combined dataset so that there is one row per unique x value across all of your series. For the columns/series that do not have a value at given x, you can insert a null.
I'll paste the general code I used here. This is a quick copy-paste and has been heavily modified, variables renamed, etc. It likely has a few minor errors. I was also using min/max with dygraph's customBars, which is why this code as pasted is using arrays for columns even where it probably isn't necessary.
function combineSeries(seriesArr) {
var dyDataRows = [];
for (var seriesIdx = 0; seriesIdx < seriesArr.length; seriesIdx++) {
var seriesData = seriesArr[seriesIdx];
var newDyDataRows = [];
var nextDataRowInsertIdx = 0;
for (var dpIdx = 0; dpIdx < seriesData.length; dpIdx++) {
var dp = seriesData[dpIdx];
if (nextDataRowInsertIdx < dyDataRows.length) {
var nextDataRowCols = dyDataRows[nextDataRowInsertIdx];
var nextDataRowX = nextDataRowCols[0].getTime();
}
if (nextDataRowInsertIdx >= dyDataRows.length || dp.x < nextDataRowX) {
var newDataRowCols = [new Date(dp.x)];
for (var colIdx = 0; colIdx < seriesIdx; colIdx++) {
newDataRowCols.push([null]);
}
newDataRowCols.push([dp.y]);
newDyDataRows.push(newDataRowCols);
}
else if (dp.x > nextDataRowX) {
var newDataRowCols = nextDataRowCols.slice(0);
newDataRowCols.push([null]);
newDyDataRows.push(newDataRowCols);
nextDataRowInsertIdx++;
dpIdx--;
}
else {//(dp.x == nextDataRowX) {
var newDataRowCols = nextDataRowCols.slice(0);
newDataRowCols.push([dp.y]);
newDyDataRows.push(newDataRowCols);
nextDataRowInsertIdx++;
}
}
//insert any remaining existing rows
for (var i = nextDataRowInsertIdx; i < dyDataRows.length; i++) {
var nextDataRowCols = dyDataRows[i];
var nextDataRowDateTm = nextDataRowCols[0];
var newDataRowCols = nextDataRowCols.slice(0);
newDataRowCols.push([null]);
newDyDataRows.push(newDataRowCols);
}
dyDataRows = newDyDataRows;
}
return dyDataRows;
};
This is brute force approach, and there are likely more efficient JavaScript coding techniques. It worked for me though.
Upvotes: 2