Some work on a more DOM-centered tree

This commit is contained in:
2021-03-26 11:51:52 +01:00
parent 65d391e050
commit 865fdce8f5
4 changed files with 447 additions and 53 deletions

View File

@@ -13,8 +13,8 @@ let nodes = [];
window.onload = () => {
const graph2 = document.createElement("script-graph3");
document.querySelector("#graph2").appendChild(graph2);
//const graph2 = document.createElement("script-graph3");
//document.querySelector("#graph2").appendChild(graph2);
let src = demoConfig;

View File

@@ -7,9 +7,35 @@ import {
TemplateResult
} from "lit-element";
import { mdiAsterisk } from "@mdi/js";
import {
mdiCallSplit,
mdiAbTesting,
mdiCheck,
mdiClose,
mdiChevronRight,
mdiExclamation,
mdiTimerOutline,
mdiTrafficLight,
mdiRefresh,
mdiArrowUp,
mdiCodeJson,
mdiCheckBoxOutline,
mdiCheckboxBlankOutline,
mdiAsterisk,
mdiCircleOutline,
} from "@mdi/js";
const SIZE = 35;
const ICONS = {
"call-split": mdiCallSplit,
"ab-testing": mdiAbTesting,
"check": mdiCheck,
"close": mdiClose,
"chevron-right": mdiChevronRight,
"exclamation": mdiExclamation,
"asterisk": mdiAsterisk,
};
const SIZE = 24;
const DIST = 20;
interface GraphNode extends LitElement{
@@ -20,27 +46,145 @@ interface GraphNode extends LitElement{
class ScriptGraphNode extends LitElement {
@property() icon = mdiAsterisk;
@property() icon = "chevron-right";
get width() {
return SIZE;
return SIZE + 5;
}
get height() {
return SIZE + DIST;
return SIZE + 5;
}
render_svg() {
render() {
return svg`
<svg width="${this.width}" height="${this.height}" viewBox="${-this.width/2} 0 ${this.width} ${this.height}">
<circle
cx="0"
cy="${this.width/2}"
r="${SIZE/2}"
/>
<g style="pointer-events: none" transform="translate(-12, ${this.width/2-12})">
<g style="pointer-events: none" transform="translate(${- 12} ${this.width/2 - 12})">
${ICONS[this.icon] ?
svg`
<path d="${ICONS[this.icon]}"/>
`
: ""}
</g>
</svg>
`
}
static get styles() {
return css`
:host {
display: flex;
--stroke-clr: var(--stroke-color, rgb(3, 169, 244));
--hover-clr: var(--hover-color, rgb(255, 152, 0));
}
circle {
stroke: var(--stroke-clr);
stroke-width: 2;
fill: white;
}
circle:hover {
stroke: var(--hover-clr);
}
`;
}
}
class ScriptGraphBranch extends LitElement {
@property() _num_items = 0;
get width() {
let w = 0;
for(const c of this.children) {
w += (c as any).width ?? 0;
}
return w;
}
get height() {
let h = 0;
for(const c of this.children) {
h = Math.max(h, (c as any).height ?? 0);
}
return h + 40;
}
async updateChildren() {
this._num_items = this.children.length;
}
render() {
let xs = [];
let x1 = 0;
for (const c of Array.from(this.children)) {
const rect = c.getBoundingClientRect();
xs.push(rect.width/2+x1);
x1 += rect.width;
}
return html`
<svg width="${this.width}" height="${this.height}">
<rect x=0 y=0 width="${this.width}" height="${this.height}" fill="white" />
${xs.map((x) => {
return svg`
<path
class="line"
d="
M ${this.width/2} 0
C ${this.width/2} 10 ${x} 10 ${x} 20
L ${x} ${this.height-20}
C ${x} ${this.height-5} ${this.width/2} ${this.height-15} ${this.width/2} ${this.height}
"
/>
`
})}
</svg>
<script-graph-node
id="head"
.icon=${"call-split"}
>
</script-graph-node>
<div id="branches">
<slot
@slotchange=${this.updateChildren}
></slot>
</div>
`
}
static get styles() {
return css`
:host {
position: relative;
display: flex;
--stroke-clr: var(--stroke-color, rgb(3, 169, 244));
--hover-clr: var(--hover-color, rgb(255, 152, 0));
}
#head {
position: Absolute;
top: 5px;
left: 50%;
transform: translate(-50%, -50%);
}
#branches {
position: absolute;
top: 20px;
left: 0;
display: flex;
flex-direction: row;
}
path.line {
stroke: var(--stroke-clr);
stroke-width: 2;
fill: white;
}
`;
}
}
class ScriptGraph3 extends LitElement {
@@ -49,62 +193,80 @@ class ScriptGraph3 extends LitElement {
@property() _width = 0;
@property() _height = 0;
connectedCallback() {
super.connectedCallback();
console.log(this.querySelectorAll('*'))
}
async updateChildren() {
this.content = [];
let y = 0;
let w = 0;
for (const e of this.querySelectorAll('*') as NodeListOf<GraphNode>) {
this.content.push({
svg: e.render_svg(),
offset_y: y,
});
y += e.height;
w = Math.max(w, e.width);
}
this._width = w;
this._height = y;
this.requestUpdate();
return;
}
childrenChangedCallback() {
console.log("Children changed");
}
render() {
let y = 0;
let nodes = [];
for (const e of this.content) {
get height() {
let h = 0;
for(const c of this.children) {
h += (c as any).height ?? 0;
h += 10;
}
return h + 10;
}
get width() {
let w = 0;
for(const c of this.children) {
w = Math.max(w, (c as any).width ?? 0);
}
return w;
}
render() {
return html`
<svg width=500 height=500>
${this.content.map(e =>
svg`
<g transform="translate(${this._width/2} ${e.offset_y})">
${e.svg}
</g>
`)}
<svg width="${this.width}" height="${this.height}">
<rect x=0 y=0 width="${this.width}" height="${this.height}" fill="white" />
<path
class="line"
d="
M ${this.width/2} 0
L ${this.width/2} ${this.height}
"
/>
</svg>
<slot
@slotchange=${this.updateChildren}
></slot>
<style>
slot {
display: none;
}
</style>
<div id="nodes">
<slot
@slotchange=${this.updateChildren}
></slot>
</div>
`
}
static get styles() {
return css`
:host {
position: relative;
display: flex;
--stroke-clr: var(--stroke-color, rgb(3, 169, 244));
--hover-clr: var(--hover-color, rgb(255, 152, 0));
}
#nodes {
position: absolute;
top: 10px;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
}
::slotted(*) {
padding-bottom: 10px;
}
path.line {
stroke: var(--stroke-clr);
stroke-width: 2;
fill: white;
}
`;
}
}
customElements.define("script-graph3", ScriptGraph3);
customElements.define("script-graph-node", ScriptGraphNode);
customElements.define("script-graph-branch", ScriptGraphBranch);