diff --git a/example.html b/example.html index 1342053..2e2c5dc 100644 --- a/example.html +++ b/example.html @@ -35,15 +35,15 @@
-
-
+

Selected node code

+

Full script code

diff --git a/src/main.js b/src/main.js index c33ad17..4b752ea 100644 --- a/src/main.js +++ b/src/main.js @@ -2,7 +2,6 @@ import {demoConfig} from "./demo-config"; import "@vanillawc/wc-codemirror"; import "./script-graph"; -import "./script-graph2"; import { ActionHandler } from "./script-to-graph"; @@ -24,28 +23,27 @@ window.onload = () => { src = jsyaml.safeLoad(fullcode.value); index_counter = 0; nodes = []; - // graph.tree = structure_tree(src); + tr.actions = src; + graph.tree = tr.graph; }); - const graph2 = document.createElement("script-graph2"); + const graph = document.createElement("script-graph"); const tr = new ActionHandler(); window.tr = tr; tr.actions = src; tr.updateCallback = (actions) => { - graph2.tree = tr.graph; + graph.tree = tr.graph; fullcode.value = jsyaml.safeDump(tr.actions); }; tr.selectCallback = (idx, action, update) => { - graph2.tree = tr.graph; + graph.tree = tr.graph; const code = document.querySelector("#snippet"); code.value = jsyaml.safeDump(action); - console.log(update); document.querySelector("#saveSnippet").onclick = () => update(jsyaml.safeLoad(code.value)); document.querySelector("#deleteSnippet").onclick = () => update(jsyaml.safeLoad(null)); } - // graph2.tree = structure_tree2(src); - graph2.tree = tr.graph; - document.querySelector("#graph2").appendChild(graph2); + graph.tree = tr.graph; + document.querySelector("#graph").appendChild(graph); } diff --git a/src/script-graph.ts b/src/script-graph.ts index afddb62..b01bd79 100644 --- a/src/script-graph.ts +++ b/src/script-graph.ts @@ -5,288 +5,200 @@ import { svg, property } from "lit-element"; -import { - mdiCallSplit, - mdiAbTesting, - mdiCheck, - mdiClose, - mdiChevronRight, - mdiExclamation, - mdiTimerOutline, - mdiTrafficLight, - mdiRefresh, - mdiArrowUp, - mdiCodeJson, - mdiCheckBoxOutline, - mdiCheckboxBlankOutline, - mdiAsterisk, -} from "@mdi/js"; + +import { mdiPlus } from "@mdi/js"; const SIZE = 35; -const BORDER = 5; -const R = SIZE/2; const DIST = 20; -const ICONS = { - choose: mdiCallSplit, - chooseChoice: mdiCheckBoxOutline, - chooseDefault: mdiCheckboxBlankOutline, - condition: mdiAbTesting, - TRUE: mdiCheck, - FALSE: mdiClose, - service: mdiChevronRight, - event: mdiExclamation, - delay: mdiTimerOutline, - wait: mdiTrafficLight, - loop: mdiRefresh, - loopReturn: mdiArrowUp, - YAML: mdiCodeJson, -}; +interface TreeNode { + icon: String; + styles: String; + end?: Boolean; + children?: (TreeNode | TreeNode[])[]; + clickCallback?: any; + addCallback?: any; +} -class ScriptGraph extends LitElement { +class ScriptGraph2 extends LitElement { + @property() selected = null; + @property() tree: [TreeNode]; + @property() nodeSize = SIZE; + @property() nodeSeparation = DIST; - /* - * GOAL: - * Tree Node Structure - * { - * icon: svg, - * styles: - * end: false - * children: [[TreeNode],...] - * click: callback,undefined - * add: callback,undefined - * } - */ - - @property() selected = undefined; - @property() tree; - - - _select(idx) { - this.selected = idx; - const ev = new CustomEvent("selected", {detail: idx}); - this.dispatchEvent(ev); - } - - _draw_node(x, y, node, idx) { - const selected = (Array.isArray(this.selected) - ? (this.selected[0] === idx) - : false - ) || (idx === this.selected); + private _draw_node(x, y, node) { return svg` this._select(idx)} + cx="${x}" + cy="${y + this.nodeSize/2}" + r="${this.nodeSize/2}" + class="node" + @click=${node.clickCallback} + style=${node.styles} /> - - ${node in ICONS - ? svg` - - - - ` - : svg` - ${node} - `} - + + + `; } - _draw_connector(x1, y1, x2, y2) { + + private _draw_new_node(x, y, node) { + return svg` + + `; + } + + + private _draw_connector(x1, y1, x2, y2) { return svg` `; } - - draw_tree(tree) { - if(!tree) return {svg: svg``, width: 1, height: 1}; - let nodes = []; - let connections = []; + private _draw_tree(tree: TreeNode | TreeNode[]) { + if(!tree) return {svg: `Hello`, width: 0, height: 0}; if(!Array.isArray(tree)) { - const selected = tree.idx == this.selected; - if(tree.type === "loop") { - const seq = this.draw_tree(tree.sequence); - const sep = seq.width + DIST; - const left = -(seq.width + SIZE + DIST)/2 + SIZE/2; - const right = left+DIST+seq.width/2 + SIZE/2; - return { - svg: svg` - ${this._draw_connector( - 0, R, - left, SIZE + DIST + R - )} - ${this._draw_connector( - 0, R, - right, SIZE + DIST + R - )} - ${this._draw_connector( - right, SIZE + DIST + seq.height - R, - 0, SIZE + DIST + seq.height + DIST - )} - ${this._draw_connector( - left, SIZE + DIST + seq.height - R, - 0, SIZE + DIST + seq.height + DIST - )} - ${this._draw_connector( - left, SIZE + DIST + R, - left, SIZE + DIST + seq.height - R - )} - ${this._draw_node(0, 0, "loop", tree.idx)} - ${this._draw_node(left, SIZE+DIST+seq.height/2-R, "loopReturn", tree.idx)} - - ${seq.svg} - - `, - height: SIZE + DIST + seq.height + DIST, - width: seq.width + SIZE, - } - } - if(tree.type === "condition") { - const sep = SIZE + DIST; - return { - svg: svg` - ${this._draw_connector( - 0, R, - -sep/2, SIZE + DIST + R - )} - ${this._draw_connector( - 0, R, - sep/2, SIZE + DIST + R - )} - ${this._draw_connector( - -sep/2, SIZE + DIST + R, - 0, SIZE + DIST + SIZE + DIST, - )} - ${this._draw_node(0, 0, "condition", tree.idx)} - ${this._draw_node(-sep/2, SIZE+DIST, "TRUE", tree.idx)} - ${this._draw_node(sep/2, SIZE+DIST, "FALSE", tree.idx)} - `, - height: SIZE + DIST + SIZE + DIST, - width: SIZE + DIST + SIZE, - } - } + let height = this.nodeSize; + let width = this.nodeSize; + let pieces = []; - if(tree.type === "choose") { - const choices = tree.choices.map(x => this.draw_tree(x)); - const maxHeight = choices.reduce((a,i) => Math.max(a, i.height), 0); - const sep = SIZE + DIST; - const totWidth = choices.reduce((a,i) => a+i.width, 0)+DIST*(choices.length-1); - const offset = choices.map((sum => value => sum += value.width)(0)); - return { - svg: svg` - ${choices.map((choice, idx) => this._draw_connector( - 0, - R, - -totWidth/2+idx*DIST + (idx?offset[idx-1]:0) + choice.width/2, - SIZE + DIST + R, - ))} - ${choices.map((choice, idx) => this._draw_connector( - -totWidth/2+idx*DIST + (idx?offset[idx-1]:0)+ choice.width/2, - SIZE + DIST + R, - -totWidth/2+idx*DIST + (idx?offset[idx-1]:0)+ choice.width/2, - SIZE + DIST + R + DIST, - ))} - ${choices.map((choice, idx) => svg` - ${this._draw_connector( - -totWidth/2+idx*DIST + (idx?offset[idx-1]:0) + choice.width/2, - SIZE + DIST + R + DIST + choice.height, - -totWidth/2+idx*DIST + (idx?offset[idx-1]:0) + choice.width/2, - SIZE + DIST + R + DIST + maxHeight + DIST - )} - ${this._draw_connector( - -totWidth/2+idx*DIST + (idx?offset[idx-1]:0) + choice.width/2, - SIZE + DIST + R + DIST + maxHeight + DIST, - 0, - SIZE + DIST + R + DIST + maxHeight + DIST + SIZE + DIST - )} - `)} - ${this._draw_node(0, 0, tree.type, tree.idx)} - ${choices.map((choice, idx) => svg` - - ${choice.svg} - - `)} - `, - height: SIZE + DIST + R + DIST + maxHeight + DIST + SIZE + DIST, - width: totWidth, - } - } + if(tree.children) { + const childTrees = tree.children.map((c) =>this._draw_tree(c)); + height += childTrees.reduce((a,i) => Math.max(a, i.height), 0); + width = childTrees.reduce((a,i) => a+i.width, 0) + this.nodeSeparation*(tree.children.length - 1); + const offsets = childTrees.map((sum => value => sum += value.width + this.nodeSeparation)(0)); + + let bottomConnectors = false; + + for (const [idx, child] of childTrees.entries()) { + const x = -width/2 + (idx? offsets[idx-1] : 0) + child.width/2; + // Draw top connectors + pieces.push(this._draw_connector( + 0, + this.nodeSize/2, + x, + this.nodeSize + this.nodeSeparation + )); + + + let endNode = tree.children[idx]; + if(Array.isArray(endNode)) endNode = endNode[endNode.length -1]; + if(endNode.end !== false) { + // Draw bottom fill + pieces.push(this._draw_connector( + x, + this.nodeSeparation + child.height, + x, + this.nodeSeparation + height + )); + + // Draw bottom connectors + pieces.push(this._draw_connector( + x, + this.nodeSeparation + height, + 0, + this.nodeSeparation + height + this.nodeSize/2 + this.nodeSeparation + )); + bottomConnectors = true; + } + + // Draw child tree + pieces.push(svg` + + ${child.svg} + + `); + } + if(bottomConnectors) + height += this.nodeSize + this.nodeSeparation; - return { - svg: this._draw_node(0, 0, tree.type, tree.idx), - height: SIZE, - width: SIZE, } - } - let height = 0; - let width = 0; - for (const [idx, node] of tree.entries()) { - const n = this.draw_tree(node); - if(idx) { - nodes.splice(nodes.length-1, 0, this._draw_connector( - 0, - height-DIST, - 0, - height+DIST + if(tree.addCallback) { + pieces.push(this._draw_connector( + 0, + height, + 0, + height + this.nodeSeparation )); + pieces.push(this._draw_new_node( + 0, height + this.nodeSeparation, + tree + )); + height += this.nodeSeparation + this.nodeSize/2; } - nodes.push(svg`${n.svg}`); - height += n.height+DIST; - width = Math.max(width, n.width); + if(tree.end !== false) { + // Draw bottom connector + pieces.push(this._draw_connector( + 0, + height, + 0, + height + this.nodeSeparation + )); + height += this.nodeSeparation; + } + + // Draw the node itself + pieces.push(this._draw_node(0, 0, tree)); + + return {svg: pieces, width, height}; } - height = height-DIST; - return { - svg: svg`${nodes.map((node, idx) => node)}`, - height, - width, - }; + + // Array of trees + let pieces = []; + let height = 0; + const children = tree.map((n) => this._draw_tree(n)); + const width = children.reduce((a,i) => Math.max(a, i.width), 0); + for (const [_, node] of children.entries()) { + pieces.push(svg` + + ${node.svg} + + `); + height += node.height; + } + + return {svg: pieces, width, height}; } + render() { - let processed_tree = this.draw_tree(this.tree); + let tree = this._draw_tree(this.tree); return html` - - - ${processed_tree.svg} + + + ${tree.svg} - + `; } } -customElements.define("script-graph", ScriptGraph); +customElements.define("script-graph", ScriptGraph2); + diff --git a/src/script-graph2.ts b/src/script-graph2.ts deleted file mode 100644 index fe72b98..0000000 --- a/src/script-graph2.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { - LitElement, - html, - css, - svg, - property -} from "lit-element"; - -import { mdiPlus } from "@mdi/js"; - -const SIZE = 35; -const DIST = 20; - -interface TreeNode { - icon: String; - styles: String; - end?: Boolean; - children?: (TreeNode | TreeNode[])[]; - clickCallback?: any; - addCallback?: any; -} - -class ScriptGraph2 extends LitElement { - @property() selected = null; - @property() tree: [TreeNode]; - @property() nodeSize = SIZE; - @property() nodeSeparation = DIST; - - private _draw_node(x, y, node) { - return svg` - - - - - `; - } - - private _draw_new_node(x, y, node) { - return svg` - - `; - } - - - private _draw_connector(x1, y1, x2, y2) { - return svg` - - `; - } - - private _draw_tree(tree: TreeNode | TreeNode[]) { - if(!tree) return {svg: `Hello`, width: 0, height: 0}; - if(!Array.isArray(tree)) { - let height = this.nodeSize; - let width = this.nodeSize; - let pieces = []; - - if(tree.children) { - const childTrees = tree.children.map((c) =>this._draw_tree(c)); - height += childTrees.reduce((a,i) => Math.max(a, i.height), 0); - width = childTrees.reduce((a,i) => a+i.width, 0) + this.nodeSeparation*(tree.children.length - 1); - const offsets = childTrees.map((sum => value => sum += value.width + this.nodeSeparation)(0)); - - let bottomConnectors = false; - - for (const [idx, child] of childTrees.entries()) { - const x = -width/2 + (idx? offsets[idx-1] : 0) + child.width/2; - // Draw top connectors - pieces.push(this._draw_connector( - 0, - this.nodeSize/2, - x, - this.nodeSize + this.nodeSeparation - )); - - - let endNode = tree.children[idx]; - if(Array.isArray(endNode)) endNode = endNode[endNode.length -1]; - if(endNode.end !== false) { - // Draw bottom fill - pieces.push(this._draw_connector( - x, - this.nodeSeparation + child.height, - x, - this.nodeSeparation + height - )); - - // Draw bottom connectors - pieces.push(this._draw_connector( - x, - this.nodeSeparation + height, - 0, - this.nodeSeparation + height + this.nodeSize/2 + this.nodeSeparation - )); - bottomConnectors = true; - } - - // Draw child tree - pieces.push(svg` - - ${child.svg} - - `); - } - if(bottomConnectors) - height += this.nodeSize + this.nodeSeparation; - - } - if(tree.addCallback) { - pieces.push(this._draw_connector( - 0, - height, - 0, - height + this.nodeSeparation - )); - pieces.push(this._draw_new_node( - 0, height + this.nodeSeparation, - tree - )); - height += this.nodeSeparation + this.nodeSize/2; - } - if(tree.end !== false) { - // Draw bottom connector - pieces.push(this._draw_connector( - 0, - height, - 0, - height + this.nodeSeparation - )); - height += this.nodeSeparation; - } - - // Draw the node itself - pieces.push(this._draw_node(0, 0, tree)); - - return {svg: pieces, width, height}; - } - - // Array of trees - let pieces = []; - let height = 0; - const children = tree.map((n) => this._draw_tree(n)); - const width = children.reduce((a,i) => Math.max(a, i.width), 0); - for (const [_, node] of children.entries()) { - pieces.push(svg` - - ${node.svg} - - `); - height += node.height; - } - - // TODO TEMPORARY - return {svg: pieces, width, height}; - - } - - - render() { - let tree = this._draw_tree(this.tree); - return html` - - - - ${tree.svg} - - - `; - } - -} - -customElements.define("script-graph2", ScriptGraph2); - diff --git a/src/script-to-graph.ts b/src/script-to-graph.ts index 0041d1f..cbbe9eb 100644 --- a/src/script-to-graph.ts +++ b/src/script-to-graph.ts @@ -101,16 +101,12 @@ const SPECIAL = { let def = action.default || [{}]; const defaultHandler = new ActionHandler(def); - console.log(selected) if(selected[0] === -2) defaultHandler.selected = selected.slice(1); defaultHandler.selectCallback = (i, a, u) => { select( [-2].concat(i), a, u); }; defaultHandler.updateCallback = (a) => { - console.log("UPDATE"); - console.log(defaultHandler.actions); - console.log(a); action.default = defaultHandler.actions; update(action); };