Skip to content

Commit

Permalink
added thick line
Browse files Browse the repository at this point in the history
  • Loading branch information
danchitnis committed Feb 25, 2022
1 parent 65b192a commit e5a5235
Show file tree
Hide file tree
Showing 40 changed files with 2,519 additions and 399 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules
temp
tmp
.now
.vscode
docs
Expand Down
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules
temp
tmp
test
benchmark
docs
Expand Down
23 changes: 13 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ multi-line high-performance 2D plotting library using native WebGL. The advantag
- Using WebGL native line drawing
- High update rate which matches the screen's refresh rate (FPS)
- Works for both dynamic and static data
- supports both thin (native) and thick lines
- Full control over the color of each line in each frame
- No dependencies
- Works on any browser/platform that [supports WebGL](https://caniuse.com/#feat=webgl)
- Works on any browsers/platforms that [supports WebGL](https://caniuse.com/#feat=webgl)
- Compatible with [OffScreenCanvas](https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas) and [WebWorkers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) for offloading cpu time from the main thread
- Ideal for embedded systems with low resources or large datasets

Expand All @@ -22,27 +23,27 @@ multi-line high-performance 2D plotting library using native WebGL. The advantag

**Static**: Enables rapid pan and zoom capability for inspecting very large datasets. See the [static example](https://danchitnis.github.io/webgl-plot-examples/vanilla/static.html)

## Limitations
## Thick Lines are now supported! 🥳

It cannot change the line width due to the OpenGL implementation of a line. The OpenGL specification only guarantees a minimum of a single pixel line width. There are other solutions to increase the line width however they substantially increase the size of the data vector and take a hit on the performance. Top performance (refresh rate, memory, etc) is the top priority for this library.
However notice that due to computation of the line data points, the performance of the thick lines is nearly _6 times slower_ than the normal lines. Only use thick lines when you need to see the lines clearly for example when highlighting a specific line. Further information can be found below. For benchmarking, see the [benchmark]() section.

## Getting started

Create an HTML canvas with an appropriate width or height:
### Create an HTML canvas with an appropriate width or height:

```html
<div>
<canvas style="width: 100%;" id="my_canvas"></canvas>
</div>
```

Import WebGL-Plot library using ES6 modules:
### Import the `webgl-plot` library using ES6 modules:

```javascript
import { WebglPlot, WebglLine, ColorRGBA } from "webgl-plot";
```

Prepare the canvas
### Prepare the canvas:

```javascript
const canvas = document.getElementById("my_canvas");
Expand All @@ -51,7 +52,9 @@ canvas.width = canvas.clientWidth * devicePixelRatio;
canvas.height = canvas.clientHeight * devicePixelRatio;
```

Initialization:
Note: The canvas width and height must be set in order to be able to draw on the canvas.

### Initialization:

```javascript
const numX = canvas.width;
Expand All @@ -72,7 +75,7 @@ Add the line to the webgl canvas:
wglp.addLine(line);
```

Configure the requestAnimationFrame call:
### Configure the requestAnimationFrame call:

```javascript
function newFrame() {
Expand All @@ -83,7 +86,7 @@ function newFrame() {
requestAnimationFrame(newFrame);
```

Add the update function:
### Add the `update` function:

```javascript
function update() {
Expand Down Expand Up @@ -121,7 +124,7 @@ React website is under development...

[https://webgl-plot-react.vercel.app/](https://webgl-plot-react.vercel.app/)

## JS Bundle
## JS Bundles

To use WebGL-Plot as a JS pre-bundled package first import the following in your HTML file:

Expand Down
21 changes: 21 additions & 0 deletions benchmark/bench-thick.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Webgl line plotting framework - Lines</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>

<body>
<div>
<canvas class="canvas" id="my_canvas"></canvas>
<p>Entre the number of lines to be created and push Click button</p>
<button id="btClick" class="button">Click!</button>
<input type="number" id="inNum" name="tentacles" min="1" max="100000" value="1" />
<p>Open the console (F12) for logs</p>
</div>
</body>

<script type="module" src="./bench-thick.js"></script>
</html>
75 changes: 75 additions & 0 deletions benchmark/bench-thick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { WebglPlot, ColorRGBA, WebglThickLine } from "../dist/webglplot.esm.js";

const canvas = document.getElementById("my_canvas");

const devicePixelRatio = window.devicePixelRatio || 1;
canvas.width = canvas.clientWidth * devicePixelRatio;
canvas.height = canvas.clientHeight * devicePixelRatio;

const numX = canvas.width;

const wglp = new WebglPlot(canvas, { powerPerformance: "high-performance" });

const createLines = (num) => {
wglp.removeAllLines();
for (let i = 0; i < num; i++) {
const color = new ColorRGBA(Math.random(), Math.random(), Math.random(), 1);
const thickLine = new WebglThickLine(color, numX, 0.01);
thickLine.lineSpaceX(-1, 2 / numX);
thickLine.offsetY = (i - Math.floor(num / 2)) / num;
wglp.addThickLine(thickLine);
}
};

createLines(1);

let frame = 0;
let prevTime = new Date();

const newFrame = () => {
//const timeStrat = +new Date();
update();
wglp.update();
const timeNow = new Date();
if (timeNow - prevTime > 1000) {
console.log(frame);
frame = 0;
prevTime = timeNow;
} else {
frame++;
}

requestAnimationFrame(newFrame);
};
requestAnimationFrame(newFrame);

const update = () => {
const freq = 0.001;
const amp = 0.5;
const noise = 0.01;

let yFinal = new Float32Array(numX);

for (let i = 0; i < yFinal.length; i++) {
const ySin = Math.sin(Math.PI * i * freq * Math.PI * 2);
const yNoise = Math.random() - 0.5;
yFinal[i] = ySin * amp + yNoise * noise;
}
//console.log(yFinal);

wglp.thickLines.forEach((line) => {
for (let i = 0; i < yFinal.length; i++) {
line.setY(i, yFinal[i]);
}
});
};

const btClick = document.getElementById("btClick");
const inNum = document.getElementById("inNum");
btClick.addEventListener("click", () => {
const numLine = inNum.value;
const timeStart = new Date();
createLines(numLine);
const timeEnd = new Date();
console.log(`Created ${numLine} in ${timeEnd - timeStart} milliseconds`);
});
4 changes: 2 additions & 2 deletions benchmark/bench1.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WebGLplot, { WebglLine, ColorRGBA } from "../dist/webglplot.esm.js";
import { WebglPlot, WebglLine, ColorRGBA } from "../dist/webglplot.esm.js";

const canvas = document.getElementById("my_canvas");

Expand All @@ -8,7 +8,7 @@ canvas.height = canvas.clientHeight * devicePixelRatio;

const numX = canvas.width;

const wglp = new WebGLplot(canvas, { powerPerformance: "high-performance" });
const wglp = new WebglPlot(canvas, { powerPerformance: "high-performance" });

const createLines = (num) => {
wglp.removeAllLines();
Expand Down
51 changes: 51 additions & 0 deletions dist/WbglThickLine.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { ColorRGBA } from "./ColorRGBA";
import { WebglBase } from "./WebglBase";
/**
* The standard Line class
*/
export declare class WebglThickLine extends WebglBase {
private currentIndex;
private _linePoints;
private _thickness;
/**
* Create a new line
* @param c - the color of the line
* @param numPoints - number of data pints
* @example
* ```typescript
* x= [0,1]
* y= [1,2]
* line = new WebglLine( new ColorRGBA(0.1,0.1,0.1,1), 2);
* ```
*/
constructor(c: ColorRGBA, numPoints: number, thickness: number);
convertToTriPoints(): void;
/**
* Set the X value at a specific index
* @param index - the index of the data point
* @param x - the horizontal value of the data point
*/
setX(index: number, x: number): void;
/**
* Set the Y value at a specific index
* @param index : the index of the data point
* @param y : the vertical value of the data point
*/
setY(index: number, y: number): void;
/**
* Make an equally spaced array of X points
* @param start - the start of the series
* @param stepSize - step size between each data point
*
* @example
* ```typescript
* //x = [-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8]
* const numX = 10;
* line.lineSpaceX(-1, 2 / numX);
* ```
*/
lineSpaceX(start: number, stepSize: number): void;
setThickness(thickness: number): void;
getThickness(): number;
}
//# sourceMappingURL=WbglThickLine.d.ts.map
1 change: 1 addition & 0 deletions dist/WbglThickLine.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 90 additions & 0 deletions dist/WbglThickLine.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions dist/WbglThickLine.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/thick.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ export declare type NormalMiter = {
vec2: Vec2;
miterLength: number;
};
export declare const PolyLine: (linePoints: Vec2[]) => NormalMiter[];
export declare const PolyLine: (lineXY: Float32Array) => NormalMiter[];
//# sourceMappingURL=thick.d.ts.map
2 changes: 1 addition & 1 deletion dist/thick.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit e5a5235

Please sign in to comment.