npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

webgl-plot-utils

v0.4.2

Published

webgl-plot wrapper for quickly making stacked time series.

Downloads

104

Readme

webgl-plot-utils

A quality of life wrapper for webgl-plot library. For creating simple, stacked real time plots. Incl thicc (triangle strip) lines, autoscaling for stacking, auto-interpolation or auto-slicing, text overlay support. If you don't specify the min and max yourself they will be calculated dynamically for up to 100K samples on line init, after that things start to overflow.

You can render millions of samples in real time. You can push partial buffers as well and the values will circularly buffer for you, but it's best to manage the WebglLine arrays manually if you need TONS of samples to render in real time. This library otherwise is convenient for animating and autoscaling tens of thousands of samples in real time.

~13kb dist

Capture


type WebglLinePlotProps = {
    canvas:HTMLCanvasElement,
    width?:number,
    height?:number,
    lineWidth?:number, //can specify the width of all lines by default
    linePoints?:number, //can specify default number of points on lines
    webglOptions?:{
        antialias?:boolean,
        transparent?:boolean,
        desynchronized?:boolean,
        powerPerformance?:'default'|'high-performance'|'low-power',
        preserveDrawing?:boolean,
        debug?:boolean
    },
    mode?:'sweep'|'scroll', //defaults to scrolling, sweep is more like a hospital monitor.
    sweepColor?:string, //sweep line fillStyle
    overlay?:HTMLCanvasElement|boolean, //automatically print the max and min values of the stacked lines
    overlayColor?:string, //overlay canvas fillStyle string
    overlayFont?:string,  //overlay canvas font string
    lines:{
        [key:string]:WebglLineProps|number[]
    },
    dividerColor?:[number,number,number,number]|ColorRGBA, //default gray
    generateNewLines?:boolean, //if unrecognized lines are in an update, reinit the plot?
    cleanGeneration?:boolean, //on regeneration, remove any lines not in the current update?
    [key:string]:any
}

type WebglLineProps = {
    values?:number[]
    color?:[number,number,number,number]|ColorRGBA,  

    position?:number, //stack position? default is the order you define the lines in this object or you can have them overlap
    autoscale?:boolean|2, //autoscale the data to -1 and 1 and stack, default true so you can just pass whatever, setting 2 allows for clamping but is slower (CPU based)
    scaled?:number[], //rescaled values (same as values if autoscale is false)
    ymin?:number, //min y to scale based on? sets bottom of line visible
    ymax?:number, //max y to scale based on? sets top of line visible
    centerZero?:boolean, //center the line at zero (if autoscaling), i.e. the positive and negative axis get the same amount of space, default false
    xAxis?:boolean, //draw an xaxis, default true
    xColor?:[number,number,number,number]|ColorRGBA, //default gray and transparent
    width?:number, //use thick triangle strip lines instead, 6x slower!!
    interpolate?:boolean, //we can up or downsample data provided to update arrays, else we will use the end of the array for the slice (assuming you're pushing to an array and visualizing the incoming data)
    useOverlay?:boolean, //specify if you want this line to print, set false for overlapping lines to prevent printing on top of each other (for now)
    units?:string, //units to appear on overlay
    viewing?:boolean, //are we rendering this line? reinit every time you want to change this setting
    [key:string]:any
} & ({ //define a fixed number of points
        nPoints?:number
    }|{ //or define by number of seconds + samplerate
        nSec?:number, 
        sps?:number
    }|{
        points?:number
    })


//returned from initPlot, you can reinit at any time by modifying the settings and passi
type WebglLinePlotInfo = {
    plot:WebglPlot,
    settings:WebglLinePlotProps, //settings, modified
    initial:WebglLinePlotProps, //original unmodified settings
    anim:any
}
import {WebglLinePlotUtil} from 'webgl=plot-utils'

let plotter = new WebglLinePlotUtil()

let canvas = document.createElement('canvas')
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.width = window.innerWidth;
canvas.style.height = window.innerHeight;

document.appendChild(canvas);

let settings = {
    canvas,
    overlay:true,
    lines:{
        'a': {
            values:new Array(10000).fill(Date.now()).map((v,i) => Math.sine(i*0.001+v)),
            color:[0,255,0,1]
        },
        'b': {
            values:new Array(10000).fill(Date.now()+2).map((v,i) => Math.cos(i*0.001+v)),
            color:[255,0,0,1],
            width:4
        },
        'c': {
            values:new Array(10000).fill(Date.now()+3).map((v,i) => Math.cos(i*0.001)*Math.sine(i*0.001+v)),
            color:[0,0,255,1],
            width:8
        }
    };
}

let plot = plotter.initPlot(settings);

let anim = () => {
    let lines = {
        'a': {
            values:new Array(10000).fill(Date.now()).map((v,i) => Math.sine(i*0.001+v))
        },
        'b': {
            values:new Array(10000).fill(Date.now()+2).map((v,i) => Math.cos(i*0.001+v))
        },
        'c': {
            values:new Array(10000).fill(Date.now()+3).map((v,i) => Math.cos(i*0.001)*Math.sine(i*0.001+v))
        } //or set each key as arrays to avoid an additional object being created 
    };

    plotter.update(plot,lines);

    requestAnimationFrame(anim);
}

anim();

//... later to change the plot but recycle the webgl context:

plotter.reinitPlot(plotInfo,{_id:plotInfo.settings._id, lines} as any); //

Reinitialize the plot at any time with new line settings etc. Plots with generateNewLines set to true can detect lines added when calling update after first initialization, and if cleanGeneration is false it can keep adding more lines and keep the originals e.g. for asynchronous data updates from different sources to a single graph