Skip to content

Instantly share code, notes, and snippets.

@amir-arad
Created November 22, 2020 12:26
Show Gist options
  • Select an option

  • Save amir-arad/1d88c4931b0bfc9377dd05f2c25089d2 to your computer and use it in GitHub Desktop.

Select an option

Save amir-arad/1d88c4931b0bfc9377dd05f2c25089d2 to your computer and use it in GitHub Desktop.

Revisions

  1. amir-arad created this gist Nov 22, 2020.
    79 changes: 79 additions & 0 deletions lines-data-collector.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,79 @@
    // originally copied from https://gist.github.com/amir-arad/3c140b3c44b81dcc1ec108e109355c27

    export type LineData = {
    name: string;
    y: number[];
    x: number[];
    };

    export type GraphPointInput = {
    annotate: (t: string) => unknown;
    addtoLine: (n: string, v: number) => unknown;
    };

    export function limitPercision(num: number) {
    return Math.round(num * 1e2) / 1e2;
    }
    export class LinesDataCollector {
    public readonly lines: Record<string, LineData | undefined> = {};
    public readonly annotations = Array.of<[string, number]>();
    private lastAnnotation = '';
    constructor(private metrics: Record<string, () => number> = {}) {}

    private getLine(name: string) {
    return this.lines[name] || (this.lines[name] = { name, y: Array.of<number>(), x: Array.of<number>() });
    }

    /**
    * build a [plotly](https://plotly.com/javascript/) graph configuration
    * works well with [vscode Debug Visualizer](https://marketplace.visualstudio.com/items?itemName=hediet.debug-visualizer)
    */
    public graph() {
    return {
    kind: { plotly: true },
    data: Object.values(this.lines),
    layout: {
    showlegend: true,
    legend: { orientation: 'h' },
    annotations: this.annotations.map(([text, x], i) => {
    const y = (i % 2) * 2 - 1;
    return { x, y, xref: 'x', yref: 'y', text };
    }),
    },
    };
    }

    public snapshot(){
    const res : Record<string, number> = {};
    for (const line of Object.values(this.lines)){
    for (const idx in line.x){
    const yValue = line.y[idx];
    if (yValue){
    res[line.name + '@' + line.x[idx]] = line.y[idx];
    }
    }
    }
    return res;
    }

    newPoint(time: number): GraphPointInput {
    const addtoLine = (name: string, value: number) => {
    const lineData = this.getLine(name);
    lineData.y.push(limitPercision(value));
    lineData.x.push(time);
    };
    const annotate = (text: string) => {
    if (this.lastAnnotation !== text) {
    this.lastAnnotation = text;
    this.annotations.push([text, time]);
    }
    };
    for (const [name, getVal] of Object.entries(this.metrics)) {
    addtoLine(name, getVal());
    }
    return {
    annotate,
    addtoLine,
    };
    }
    }