Mercurial > code > home > repos > streamed-graph
view src/render/StreamedGraph.ts @ 118:c2923b20bf5c
support multi labels per column
author | drewp@bigasterisk.com |
---|---|
date | Sun, 20 Mar 2022 00:54:19 -0700 |
parents | 3cdbbd913f1d |
children |
line wrap: on
line source
import { html, LitElement, render, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; import { Store } from "n3"; import { StreamedGraphClient } from "../layout/StreamedGraphClient"; import { ViewConfig } from "../layout/ViewConfig"; import { GraphView } from "./GraphView"; import { addFontToRootPage, style } from "./style"; export interface VersionedGraph { version: number; store: Store; } @customElement("streamed-graph") export class StreamedGraph extends LitElement { @property({ type: String }) url: string = ""; @property({ type: String }) view: string = ""; @property({ type: Object }) graph!: VersionedGraph; @property({ type: Boolean }) expanded: boolean = false; @property({ type: String }) status: string = ""; sg!: StreamedGraphClient; graphViewDirty = true; static styles = style; render() { const expandAction = this.expanded ? "-" : "+"; return html` <div id="ui"> <span class="expander" ><button @click="${this.toggleExpand}">${expandAction}</button></span > StreamedGraph <a href="${this.url}">[source]</a>: ${this.status} </div> <div id="graphView"></div> `; } connectedCallback() { super.connectedCallback(); addFontToRootPage(); const emptyStore = new Store(); this.graph = { version: -1, store: emptyStore }; this._onUrl(this.url); // todo: watch for changes and rebuild if (this.expanded) { this.redrawGraph(); } } toggleExpand() { this.expanded = !this.expanded; if (this.expanded) { this.redrawGraph(); } else { this.graphViewDirty = false; this._graphAreaClose(); } } redrawGraph() { this.graphViewDirty = true; const rl: () => Promise<void> = this._redrawLater.bind(this); requestAnimationFrame(rl); } _onUrl(url: string) { if (this.sg) { this.sg.close(); } this.sg = new StreamedGraphClient( url, this.onGraphChanged.bind(this), (st) => { this.status = st; }, [], //window.NS, [] ); } onGraphChanged() { this.graph = { version: this.graph.version + 1, store: this.sg.store, }; if (this.expanded) { this.redrawGraph(); } this.dispatchEvent( new CustomEvent("graph-changed", { detail: { graph: this.graph } }) ); } async _redrawLater() { if (!this.graphViewDirty) return; if ((this.graph as VersionedGraph).store && this.graph.store) { const vc = new ViewConfig(); if (this.view) { await vc.readFromUrl(this.view); // too often! } await this._graphAreaShowGraph( new GraphView([this.url], this.graph.store, vc) ); this.graphViewDirty = false; } else { this._graphAreaShowPending(); } } _graphAreaClose() { this._setGraphArea(html``); } _graphAreaShowPending() { this._setGraphArea(html` <span>waiting for data...</span> `); } async _graphAreaShowGraph(graphView: GraphView) { this._setGraphArea(await graphView.makeTemplate()); } _setGraphArea(tmpl: TemplateResult) { const el = this.shadowRoot?.getElementById("graphView"); if (!el) { return; } render(tmpl, el); } } declare global { interface HTMLElementTagNameMap { "streamed-graph": StreamedGraph; } } // // allow child nodes to combine a few graphs and statics // //<streamed-graph id="timebankGraph" graph="{{graph}}" expanded="true"> // // <member-graph url="graph/timebank/events"></member-graph> // // <member-graph url="/some/static.n3"></member-graph> // //</streamed-graph>