More generalized version of tree
This commit is contained in:
parent
8378b34263
commit
b6cbc975cb
@ -15,6 +15,7 @@
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
font-family: Roboto, Noto, sans-serif;
|
font-family: Roboto, Noto, sans-serif;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
code {
|
code {
|
||||||
display: block;
|
display: block;
|
||||||
@ -34,6 +35,8 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="card" id="graph">
|
<div class="card" id="graph">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="card" id="graph2">
|
||||||
|
</div>
|
||||||
<div class="card" id="code">
|
<div class="card" id="code">
|
||||||
<code>
|
<code>
|
||||||
</code>
|
</code>
|
||||||
|
72
src/main.js
72
src/main.js
@ -2,6 +2,9 @@ import {demoConfig} from "./demo-config";
|
|||||||
import "@vanillawc/wc-codemirror";
|
import "@vanillawc/wc-codemirror";
|
||||||
|
|
||||||
import "./script-graph";
|
import "./script-graph";
|
||||||
|
import "./script-graph2";
|
||||||
|
|
||||||
|
import { mdiAsterisk, mdiArrowUp, mdiArrowDown } from "@mdi/js";
|
||||||
|
|
||||||
let index_counter = 0;
|
let index_counter = 0;
|
||||||
let nodes = [];
|
let nodes = [];
|
||||||
@ -47,6 +50,70 @@ const structure_tree = (inp) => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const structure_tree2 = () => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number 1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number 2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number 3"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number 4"),
|
||||||
|
children: [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number A1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number A2"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number B"),
|
||||||
|
end: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number B"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number B"),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number 4"),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
icon: mdiArrowUp,
|
||||||
|
clickCallback: () => console.log("Return"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiArrowDown,
|
||||||
|
clickCallback: () => console.log("Return"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: mdiAsterisk,
|
||||||
|
clickCallback: () => console.log("Number 1"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
window.onload = () => {
|
window.onload = () => {
|
||||||
|
|
||||||
let src = demoConfig;
|
let src = demoConfig;
|
||||||
@ -65,6 +132,11 @@ window.onload = () => {
|
|||||||
|
|
||||||
const graph = document.createElement("script-graph");
|
const graph = document.createElement("script-graph");
|
||||||
graph.tree = structure_tree(src);
|
graph.tree = structure_tree(src);
|
||||||
|
|
||||||
|
const graph2 = document.createElement("script-graph2");
|
||||||
|
graph2.tree = structure_tree2(src);
|
||||||
|
document.querySelector("#graph2").appendChild(graph2);
|
||||||
|
|
||||||
graph.addEventListener("selected", (ev) => {
|
graph.addEventListener("selected", (ev) => {
|
||||||
const idx = ev.detail;
|
const idx = ev.detail;
|
||||||
const code = document.querySelector("code");
|
const code = document.querySelector("code");
|
||||||
|
@ -50,6 +50,7 @@ class ScriptGraph extends LitElement {
|
|||||||
* Tree Node Structure
|
* Tree Node Structure
|
||||||
* {
|
* {
|
||||||
* icon: svg,
|
* icon: svg,
|
||||||
|
* styles:
|
||||||
* end: false
|
* end: false
|
||||||
* children: [[TreeNode],...]
|
* children: [[TreeNode],...]
|
||||||
* click: callback,undefined
|
* click: callback,undefined
|
||||||
|
169
src/script-graph2.ts
Normal file
169
src/script-graph2.ts
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
import {
|
||||||
|
LitElement,
|
||||||
|
html,
|
||||||
|
css,
|
||||||
|
svg,
|
||||||
|
property
|
||||||
|
} from "lit-element";
|
||||||
|
|
||||||
|
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}
|
||||||
|
/>
|
||||||
|
<g style="pointer-events: none" transform="translate(${x - 12} ${y + this.nodeSize/2 - 12})">
|
||||||
|
<path d="${node.icon}"/>
|
||||||
|
</g>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.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>
|
||||||
|
circle, line {
|
||||||
|
stroke: rgb(3, 169, 244);
|
||||||
|
stroke-width: 5;
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
</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);
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user