High performance graph plotter
npm install owp.graphnpm install owp.graph --save``javascript
import Graph from "owp.graph";
const graph = Graph(
document.getElementById("root"),
{
title: {
label: "Standard line plot with two data sets"
},
axes: {
x: {
"label": "Frequency (Hz)"
},
y: {
"label": "Amplitude (dB)"
}
},
graph: {
names: ["x", "Left", "Right"],
dataX: [
[100, 200, 400]
],
dataY: [
[1, 2, 3],
[1.5, 2.5, 3.5]
]
}
}
);
`
#### Data types
dataX and dataY are always standard JS arrays, but the inner arrays that hold the actual data can be either a standard JS array or a typed array(uint8, int32, float32..).
The data in the inner arrays can be any number.
#### Length of arrays
The inner arrays in dataY hold the Y-axis values for each coordinate. Each new inner array will create a new line to plot on the graph.
The inner arrays in dataX hold the X-axis values for each coordinate. dataX doesn't neccessary need to contain the same number of inner arrays as dataY. The X-coordinates can be implicit.
There are three different possibilities for the coordinates to be interpreted.
* dataX.length == 0: Each coordinate gets the implicit X-value of n+1.
Coordinate: { n+1, dataY[i][n] }
* dataX.length == 1: Each inner array in dataY uses the same inner array in dataX.
Coordinate: { dataX[0][n], dataY[i][n] }
* dataX.length == dataY.length: Each inner array in dataY has each own inner array in dataX.
Coordinate: { dataX[i][n], dataY[i][n] }
NOTE: If dataX has length 0 or 1, then we only have one (implicit or explicit) data set for X. Each inner array in dataY has to have the same length.
NOTE: If dataX has length greater than 1, then dataY.length must be equal to dataX.length and dataY[i].length must be equal to dataX[i].length.
#### Why use separate X and Y arrays?
Many other similar systems use matrices or an arrays of objects to describe each coordinate. Graph on the other hand uses separate X and Y arrays. This has several advantages:
* Increased performance. Accessing members is costly in JavaScript so instead of having to do data[i][1] or data[i].y Graph just do dataY[i].
* Implicit X-coordinates. Less data thats needs processing. Use custom value formatter to get the output you want for X.
* One X for each Y. Possible to plot data sets that have different length and distribution. Not possible with format: {x, y1, y2, y3}
* Can use typed arrays. Less CPU overhead, more memory efficient, possible to transfer between web workers and so on.
Pseudo code:
```
if |pixelXOld - pixelX[n]| < simplify:
valueYMin = min(valueYMin, valueY[n])
valueYMax = max(valueYMax, valueY[n])
else:
plot(x, pixelYMin)
plot(x, pixelYMax)