Mercurial > code > home > repos > streamed-graph
view src/render/StreamedGraph.ts @ 108:5e6840229a05
rewrite freeStatements rendering to put more planning in layout
author | drewp@bigasterisk.com |
---|---|
date | Fri, 18 Mar 2022 11:57:38 -0700 |
parents | 042bd3361339 |
children | cbcd82d21356 |
line wrap: on
line source
import { LitElement, html, render, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators.js"; import { Store } from "n3"; import { GraphView } from "./GraphView"; import { StreamedGraphClient } from "../layout/StreamedGraphClient"; import { style, addFontToRootPage } from "./style"; import { ViewConfig } from "../layout/ViewConfig"; // export * from "./graph_queries"; 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() 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>