Removing old stuff
This commit is contained in:
parent
6ffed6a69e
commit
14ec3e37da
@ -35,15 +35,15 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="card" id="graph">
|
<div class="card" id="graph">
|
||||||
</div>
|
</div>
|
||||||
<div class="card" id="graph2">
|
|
||||||
</div>
|
|
||||||
<div class="card code">
|
<div class="card code">
|
||||||
|
<h1> Selected node code </h1>
|
||||||
<wc-codemirror mode="json" id="snippet">
|
<wc-codemirror mode="json" id="snippet">
|
||||||
</wc-codemirror>
|
</wc-codemirror>
|
||||||
<button id="saveSnippet">Save</button>
|
<button id="saveSnippet">Save</button>
|
||||||
<button id="deleteSnippet">Delete</button>
|
<button id="deleteSnippet">Delete</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card code">
|
<div class="card code">
|
||||||
|
<h1>Full script code</h1>
|
||||||
<wc-codemirror mode="yaml" id="fullcode">
|
<wc-codemirror mode="yaml" id="fullcode">
|
||||||
</wc-codemirror>
|
</wc-codemirror>
|
||||||
<button id="updateButton">Update</button>
|
<button id="updateButton">Update</button>
|
||||||
|
16
src/main.js
16
src/main.js
@ -2,7 +2,6 @@ import {demoConfig} from "./demo-config";
|
|||||||
import "@vanillawc/wc-codemirror";
|
import "@vanillawc/wc-codemirror";
|
||||||
|
|
||||||
import "./script-graph";
|
import "./script-graph";
|
||||||
import "./script-graph2";
|
|
||||||
|
|
||||||
import { ActionHandler } from "./script-to-graph";
|
import { ActionHandler } from "./script-to-graph";
|
||||||
|
|
||||||
@ -24,28 +23,27 @@ window.onload = () => {
|
|||||||
src = jsyaml.safeLoad(fullcode.value);
|
src = jsyaml.safeLoad(fullcode.value);
|
||||||
index_counter = 0;
|
index_counter = 0;
|
||||||
nodes = [];
|
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();
|
const tr = new ActionHandler();
|
||||||
window.tr = tr;
|
window.tr = tr;
|
||||||
tr.actions = src;
|
tr.actions = src;
|
||||||
tr.updateCallback = (actions) => {
|
tr.updateCallback = (actions) => {
|
||||||
graph2.tree = tr.graph;
|
graph.tree = tr.graph;
|
||||||
fullcode.value = jsyaml.safeDump(tr.actions);
|
fullcode.value = jsyaml.safeDump(tr.actions);
|
||||||
};
|
};
|
||||||
tr.selectCallback = (idx, action, update) => {
|
tr.selectCallback = (idx, action, update) => {
|
||||||
graph2.tree = tr.graph;
|
graph.tree = tr.graph;
|
||||||
const code = document.querySelector("#snippet");
|
const code = document.querySelector("#snippet");
|
||||||
code.value = jsyaml.safeDump(action);
|
code.value = jsyaml.safeDump(action);
|
||||||
console.log(update);
|
|
||||||
document.querySelector("#saveSnippet").onclick = () => update(jsyaml.safeLoad(code.value));
|
document.querySelector("#saveSnippet").onclick = () => update(jsyaml.safeLoad(code.value));
|
||||||
document.querySelector("#deleteSnippet").onclick = () => update(jsyaml.safeLoad(null));
|
document.querySelector("#deleteSnippet").onclick = () => update(jsyaml.safeLoad(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
// graph2.tree = structure_tree2(src);
|
graph.tree = tr.graph;
|
||||||
graph2.tree = tr.graph;
|
document.querySelector("#graph").appendChild(graph);
|
||||||
document.querySelector("#graph2").appendChild(graph2);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,283 +5,194 @@ import {
|
|||||||
svg,
|
svg,
|
||||||
property
|
property
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import {
|
|
||||||
mdiCallSplit,
|
import { mdiPlus } from "@mdi/js";
|
||||||
mdiAbTesting,
|
|
||||||
mdiCheck,
|
|
||||||
mdiClose,
|
|
||||||
mdiChevronRight,
|
|
||||||
mdiExclamation,
|
|
||||||
mdiTimerOutline,
|
|
||||||
mdiTrafficLight,
|
|
||||||
mdiRefresh,
|
|
||||||
mdiArrowUp,
|
|
||||||
mdiCodeJson,
|
|
||||||
mdiCheckBoxOutline,
|
|
||||||
mdiCheckboxBlankOutline,
|
|
||||||
mdiAsterisk,
|
|
||||||
} from "@mdi/js";
|
|
||||||
|
|
||||||
const SIZE = 35;
|
const SIZE = 35;
|
||||||
const BORDER = 5;
|
|
||||||
const R = SIZE/2;
|
|
||||||
const DIST = 20;
|
const DIST = 20;
|
||||||
|
|
||||||
const ICONS = {
|
interface TreeNode {
|
||||||
choose: mdiCallSplit,
|
icon: String;
|
||||||
chooseChoice: mdiCheckBoxOutline,
|
styles: String;
|
||||||
chooseDefault: mdiCheckboxBlankOutline,
|
end?: Boolean;
|
||||||
condition: mdiAbTesting,
|
children?: (TreeNode | TreeNode[])[];
|
||||||
TRUE: mdiCheck,
|
clickCallback?: any;
|
||||||
FALSE: mdiClose,
|
addCallback?: any;
|
||||||
service: mdiChevronRight,
|
}
|
||||||
event: mdiExclamation,
|
|
||||||
delay: mdiTimerOutline,
|
|
||||||
wait: mdiTrafficLight,
|
|
||||||
loop: mdiRefresh,
|
|
||||||
loopReturn: mdiArrowUp,
|
|
||||||
YAML: mdiCodeJson,
|
|
||||||
};
|
|
||||||
|
|
||||||
class ScriptGraph extends LitElement {
|
class ScriptGraph2 extends LitElement {
|
||||||
|
@property() selected = null;
|
||||||
|
@property() tree: [TreeNode];
|
||||||
|
@property() nodeSize = SIZE;
|
||||||
|
@property() nodeSeparation = DIST;
|
||||||
|
|
||||||
/*
|
private _draw_node(x, y, node) {
|
||||||
* 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);
|
|
||||||
return svg`
|
return svg`
|
||||||
<circle
|
<circle
|
||||||
cx=${x}
|
cx="${x}"
|
||||||
cy=${y + SIZE/2}
|
cy="${y + this.nodeSize/2}"
|
||||||
r=${R}
|
r="${this.nodeSize/2}"
|
||||||
stroke-width=${BORDER}
|
class="node"
|
||||||
stroke="black"
|
@click=${node.clickCallback}
|
||||||
fill="white"
|
style=${node.styles}
|
||||||
class="${selected ? 'selected' : ''}"
|
|
||||||
@click=${() => this._select(idx)}
|
|
||||||
/>
|
/>
|
||||||
<g style="pointer-events: none">
|
<g style="pointer-events: none" transform="translate(${x - 12} ${y + this.nodeSize/2 - 12})">
|
||||||
${node in ICONS
|
<path d="${node.icon}"/>
|
||||||
? svg`
|
|
||||||
<g transform="translate(${x-12} ${y+R-12})">
|
|
||||||
<path d="${ICONS[node]}"/>
|
|
||||||
</g>
|
|
||||||
`
|
|
||||||
: svg`
|
|
||||||
<text
|
|
||||||
x=${x}
|
|
||||||
y=${y+R}
|
|
||||||
text-anchor="middle"
|
|
||||||
dominant-baseline="middle"
|
|
||||||
>${node}</text>
|
|
||||||
`}
|
|
||||||
</g>
|
</g>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
_draw_connector(x1, y1, x2, y2) {
|
|
||||||
|
private _draw_new_node(x, y, node) {
|
||||||
|
return svg`
|
||||||
|
<circle
|
||||||
|
cx="${x}"
|
||||||
|
cy="${y + this.nodeSize/4}"
|
||||||
|
r="${this.nodeSize/4}"
|
||||||
|
class="newnode"
|
||||||
|
@click=${node.addCallback}
|
||||||
|
/>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private _draw_connector(x1, y1, x2, y2) {
|
||||||
return svg`
|
return svg`
|
||||||
<line
|
<line
|
||||||
x1=${x1}
|
x1=${x1}
|
||||||
y1=${y1}
|
y1=${y1}
|
||||||
x2=${x2}
|
x2=${x2}
|
||||||
y2=${y2}
|
y2=${y2}
|
||||||
stroke-width=${BORDER}
|
|
||||||
stroke="black"
|
|
||||||
stroke-linecap="round"
|
|
||||||
/>
|
/>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _draw_tree(tree: TreeNode | TreeNode[]) {
|
||||||
draw_tree(tree) {
|
if(!tree) return {svg: `Hello`, width: 0, height: 0};
|
||||||
if(!tree) return {svg: svg``, width: 1, height: 1};
|
|
||||||
let nodes = [];
|
|
||||||
let connections = [];
|
|
||||||
if(!Array.isArray(tree)) {
|
if(!Array.isArray(tree)) {
|
||||||
const selected = tree.idx == this.selected;
|
let height = this.nodeSize;
|
||||||
if(tree.type === "loop") {
|
let width = this.nodeSize;
|
||||||
const seq = this.draw_tree(tree.sequence);
|
let pieces = [];
|
||||||
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)}
|
|
||||||
<g transform="translate(${right} ${SIZE + DIST})">
|
|
||||||
${seq.svg}
|
|
||||||
</g>
|
|
||||||
`,
|
|
||||||
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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tree.type === "choose") {
|
if(tree.children) {
|
||||||
const choices = tree.choices.map(x => this.draw_tree(x));
|
const childTrees = tree.children.map((c) =>this._draw_tree(c));
|
||||||
const maxHeight = choices.reduce((a,i) => Math.max(a, i.height), 0);
|
height += childTrees.reduce((a,i) => Math.max(a, i.height), 0);
|
||||||
const sep = SIZE + DIST;
|
width = childTrees.reduce((a,i) => a+i.width, 0) + this.nodeSeparation*(tree.children.length - 1);
|
||||||
const totWidth = choices.reduce((a,i) => a+i.width, 0)+DIST*(choices.length-1);
|
const offsets = childTrees.map((sum => value => sum += value.width + this.nodeSeparation)(0));
|
||||||
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`
|
|
||||||
<g transform="translate(
|
|
||||||
${-totWidth/2+idx*DIST + (idx?offset[idx-1]:0) + choice.width/2}
|
|
||||||
${SIZE + DIST + R + DIST})">
|
|
||||||
${choice.svg}
|
|
||||||
</g>
|
|
||||||
`)}
|
|
||||||
`,
|
|
||||||
height: SIZE + DIST + R + DIST + maxHeight + DIST + SIZE + DIST,
|
|
||||||
width: totWidth,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
let bottomConnectors = false;
|
||||||
svg: this._draw_node(0, 0, tree.type, tree.idx),
|
|
||||||
height: SIZE,
|
for (const [idx, child] of childTrees.entries()) {
|
||||||
width: SIZE,
|
const x = -width/2 + (idx? offsets[idx-1] : 0) + child.width/2;
|
||||||
}
|
// Draw top connectors
|
||||||
}
|
pieces.push(this._draw_connector(
|
||||||
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,
|
0,
|
||||||
height-DIST,
|
this.nodeSize/2,
|
||||||
0,
|
x,
|
||||||
height+DIST
|
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;
|
||||||
}
|
}
|
||||||
nodes.push(svg`<g transform="translate(0 ${height})">${n.svg}</g>`);
|
|
||||||
height += n.height+DIST;
|
// Draw child tree
|
||||||
width = Math.max(width, n.width);
|
pieces.push(svg`
|
||||||
|
<g class="a" transform="translate(${x} ${this.nodeSize + this.nodeSeparation})">
|
||||||
|
${child.svg}
|
||||||
|
</g>
|
||||||
|
`);
|
||||||
}
|
}
|
||||||
height = height-DIST;
|
if(bottomConnectors)
|
||||||
return {
|
height += this.nodeSize + this.nodeSeparation;
|
||||||
svg: svg`${nodes.map((node, idx) => node)}`,
|
|
||||||
height,
|
|
||||||
width,
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
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`
|
||||||
|
<g class="b" transform="translate(0, ${height})">
|
||||||
|
${node.svg}
|
||||||
|
</g>
|
||||||
|
`);
|
||||||
|
height += node.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {svg: pieces, width, height};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let processed_tree = this.draw_tree(this.tree);
|
let tree = this._draw_tree(this.tree);
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
|
:host {
|
||||||
|
--stroke-clr: var(--stroke-color, rgb(3, 169, 244));
|
||||||
|
--hover-clr: var(--hover-color, rgb(255, 152, 0));
|
||||||
|
}
|
||||||
circle, line {
|
circle, line {
|
||||||
stroke: rgb(3, 169, 244);
|
stroke: var(--stroke-clr);
|
||||||
|
stroke-width: 5;
|
||||||
|
fill: white;
|
||||||
}
|
}
|
||||||
circle.selected {
|
.newnode:hover {
|
||||||
stroke: rgb(255, 152, 0);
|
stroke: var(--hover-clr);
|
||||||
}
|
|
||||||
svg {
|
|
||||||
font-family: Roboto, Noto, sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<svg width=${processed_tree.width + SIZE} height=${processed_tree.height + BORDER}>
|
<svg width=${tree.width + 32} height=${tree.height + 32}>
|
||||||
<g transform="translate(${processed_tree.width/2 + BORDER/2} ${BORDER/2})">
|
<g transform="translate(${tree.width/2 + 16} 16)">
|
||||||
${processed_tree.svg}
|
${tree.svg}
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
`;
|
`;
|
||||||
@ -289,4 +200,5 @@ class ScriptGraph extends LitElement {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define("script-graph", ScriptGraph);
|
customElements.define("script-graph", ScriptGraph2);
|
||||||
|
|
||||||
|
@ -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`
|
|
||||||
<circle
|
|
||||||
cx="${x}"
|
|
||||||
cy="${y + this.nodeSize/2}"
|
|
||||||
r="${this.nodeSize/2}"
|
|
||||||
class="node"
|
|
||||||
@click=${node.clickCallback}
|
|
||||||
style=${node.styles}
|
|
||||||
/>
|
|
||||||
<g style="pointer-events: none" transform="translate(${x - 12} ${y + this.nodeSize/2 - 12})">
|
|
||||||
<path d="${node.icon}"/>
|
|
||||||
</g>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
private _draw_new_node(x, y, node) {
|
|
||||||
return svg`
|
|
||||||
<circle
|
|
||||||
cx="${x}"
|
|
||||||
cy="${y + this.nodeSize/4}"
|
|
||||||
r="${this.nodeSize/4}"
|
|
||||||
class="newnode"
|
|
||||||
@click=${node.addCallback}
|
|
||||||
/>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private _draw_connector(x1, y1, x2, y2) {
|
|
||||||
return svg`
|
|
||||||
<line
|
|
||||||
x1=${x1}
|
|
||||||
y1=${y1}
|
|
||||||
x2=${x2}
|
|
||||||
y2=${y2}
|
|
||||||
/>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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`
|
|
||||||
<g class="a" transform="translate(${x} ${this.nodeSize + this.nodeSeparation})">
|
|
||||||
${child.svg}
|
|
||||||
</g>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
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`
|
|
||||||
<g class="b" transform="translate(0, ${height})">
|
|
||||||
${node.svg}
|
|
||||||
</g>
|
|
||||||
`);
|
|
||||||
height += node.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO TEMPORARY
|
|
||||||
return {svg: pieces, width, height};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let tree = this._draw_tree(this.tree);
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
--stroke-clr: var(--stroke-color, rgb(3, 169, 244));
|
|
||||||
--hover-clr: var(--hover-color, rgb(255, 152, 0));
|
|
||||||
}
|
|
||||||
circle, line {
|
|
||||||
stroke: var(--stroke-clr);
|
|
||||||
stroke-width: 5;
|
|
||||||
fill: white;
|
|
||||||
}
|
|
||||||
.newnode:hover {
|
|
||||||
stroke: var(--hover-clr);
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<svg width=${tree.width + 32} height=${tree.height + 32}>
|
|
||||||
<g transform="translate(${tree.width/2 + 16} 16)">
|
|
||||||
${tree.svg}
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define("script-graph2", ScriptGraph2);
|
|
||||||
|
|
@ -101,16 +101,12 @@ const SPECIAL = {
|
|||||||
|
|
||||||
let def = action.default || [{}];
|
let def = action.default || [{}];
|
||||||
const defaultHandler = new ActionHandler(def);
|
const defaultHandler = new ActionHandler(def);
|
||||||
console.log(selected)
|
|
||||||
if(selected[0] === -2)
|
if(selected[0] === -2)
|
||||||
defaultHandler.selected = selected.slice(1);
|
defaultHandler.selected = selected.slice(1);
|
||||||
defaultHandler.selectCallback = (i, a, u) => {
|
defaultHandler.selectCallback = (i, a, u) => {
|
||||||
select( [-2].concat(i), a, u);
|
select( [-2].concat(i), a, u);
|
||||||
};
|
};
|
||||||
defaultHandler.updateCallback = (a) => {
|
defaultHandler.updateCallback = (a) => {
|
||||||
console.log("UPDATE");
|
|
||||||
console.log(defaultHandler.actions);
|
|
||||||
console.log(a);
|
|
||||||
action.default = defaultHandler.actions;
|
action.default = defaultHandler.actions;
|
||||||
update(action);
|
update(action);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user