Mercurial > code > home > repos > streamed-graph
diff src/render/StreamedGraph.ts @ 107:042bd3361339
renames
author | drewp@bigasterisk.com |
---|---|
date | Sun, 13 Mar 2022 22:02:30 -0700 |
parents | src/render/element.ts@2468f2227d22 |
children | 5e6840229a05 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/render/StreamedGraph.ts Sun Mar 13 22:02:30 2022 -0700 @@ -0,0 +1,150 @@ +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"; + +// 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) { + await this._graphAreaShowGraph( + new GraphView(this.url, this.view, this.graph.store) + ); + 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>