From 806baf004397dcdf4634bbfbf3ee162f92ed50ba Mon Sep 17 00:00:00 2001 From: jusax23 Date: Thu, 22 Jun 2023 12:41:11 +0200 Subject: [PATCH] init --- graphics.js | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 91 ++++++++++++++++++++++++++++ main.js | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 417 insertions(+) create mode 100644 graphics.js create mode 100644 index.html create mode 100644 main.js diff --git a/graphics.js b/graphics.js new file mode 100644 index 0000000..608b82e --- /dev/null +++ b/graphics.js @@ -0,0 +1,166 @@ +class Tragable { + initTrag(element, cb) { + let selected = false; + element.addEventListener('mousedown', () => { + selected = true; + }); + svg.addEventListener('mousemove', event => { + if (selected) cb(event.x, event.y); + }); + svg.addEventListener('mouseup', () => { + selected = false; + }); + svg.addEventListener('mouseleave', event => { + selected = false; + }); + } +} + + +class SVGNode extends Tragable { + group; + circle; + circleText; + aboveText; + constructor(node) { + super(); + // Create the group element + this.group = document.createElementNS(svgNamespace, 'g'); + this.group.classList.add("PNode"); + this.group.setAttribute('transform', `translate(${node.x}, ${node.y})`); + + // Create the circle + this.circle = document.createElementNS(svgNamespace, 'circle'); + this.circle.setAttribute('cx', '0'); + this.circle.setAttribute('cy', '0'); + this.circle.setAttribute('r', '25'); + + // Create the text inside the circle + this.circleText = document.createElementNS(svgNamespace, 'text'); + this.circleText.classList.add("circleText"); + this.circleText.setAttribute('x', '0'); + this.circleText.setAttribute('y', '5'); + this.circleText.textContent = '0/1'; + + // Create the text above the circle + this.aboveText = document.createElementNS(svgNamespace, 'text'); + this.aboveText.classList.add("aboveText"); + this.aboveText.setAttribute('x', '0'); + this.aboveText.setAttribute('y', '-35'); + this.aboveText.textContent = node.name; + + // Append the circle and texts to the group + this.group.appendChild(this.circle); + this.group.appendChild(this.circleText); + this.group.appendChild(this.aboveText); + + this.initTrag(this.group, (x, y) => node.updatePosition(x, y)); + } + + appendIt(svg) { + svg.appendChild(this.group); + } + + translate(x, y) { + this.group.setAttribute('transform', `translate(${x}, ${y})`); + } + setName(name) { + this.aboveText.textContent = name; + } + setMarks(amount, max) { + this.circleText.textContent = `${amount}/${max}`; + } +} + +class SVGTRansition extends Tragable { + group; + rect; + rectText; + constructor(trans) { + super(); + // Create the group element + this.group = document.createElementNS(svgNamespace, 'g'); + this.group.classList.add("PTransition"); + this.group.setAttribute('transform', `translate(${trans.x}, ${trans.y})`); + + // Create the circle + this.rect = document.createElementNS(svgNamespace, 'rect'); + this.rect.setAttribute('x', '-12.5'); + this.rect.setAttribute('y', '-25'); + this.rect.setAttribute('height', '50'); + this.rect.setAttribute('width', '25'); + + // Create the text inside the circle + this.rectText = document.createElementNS(svgNamespace, 'text'); + this.rectText.classList.add("rectText"); + this.rectText.setAttribute('x', '-5'); + this.rectText.setAttribute('y', '-35'); + this.rectText.textContent = trans.name; + + // Append the circle and texts to the group + this.group.appendChild(this.rect); + this.group.appendChild(this.rectText); + this.initTrag(this.group, (x, y) => trans.updatePosition(x, y)); + } + + appendIt(svg) { + svg.appendChild(this.group); + } + + translate(x, y) { + this.group.setAttribute('transform', `translate(${x}, ${y})`); + } + setName(name) { + this.aboveText.textContent = name; + } + + setCanFire(can){ + if (can)this.group.classList.add("canFire"); + else this.group.classList.remove("canFire"); + } +} + +class SVGArrow { + group; + lineText; + line; + from; + to; + constructor(from, to) { + this.from = from; + this.to = to; + this.group = document.createElementNS(svgNamespace, 'g'); + this.group.classList.add("PEdge"); + + this.line = document.createElementNS(svgNamespace, 'line'); + this.line.setAttribute('marker-end', "url(#arrowhead)"); + this.group.setAttribute('transform', `translate(0, 0)`); + + // Create the text inside the circle + this.lineText = document.createElementNS(svgNamespace, 'text'); + this.lineText.classList.add("lineText"); + this.lineText.setAttribute('x', '0'); + this.lineText.setAttribute('y', '0'); + this.lineText.textContent = ""; + + this.group.appendChild(this.line); + this.group.appendChild(this.lineText); + + this.updatePosition(); + } + updatePosition() { + let dx = this.to.x - this.from.x; + let dy = this.to.y - this.from.y; + let l = Math.sqrt(dx * dx + dy * dy); + dx /= l; + dy /= l; + this.line.setAttribute('x1', this.from.x + dx * 30); + this.line.setAttribute('y1', this.from.y + dy * 30); + this.line.setAttribute('x2', this.to.x - dx * 40); + this.line.setAttribute('y2', this.to.y - dy * 40); + } + appendIt(svg) { + svg.appendChild(this.group); + } + +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..c95495c --- /dev/null +++ b/index.html @@ -0,0 +1,91 @@ + + + + + + + Document + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..3c89425 --- /dev/null +++ b/main.js @@ -0,0 +1,160 @@ + +let svg = document.querySelector("svg"); + +let nods = document.createElementNS(svgNamespace, 'g'); +let arrows = document.createElementNS(svgNamespace, 'g'); + +svg.appendChild(arrows); +svg.appendChild(nods); + +class Edge { + renderedElement; + end; + trans; + inEdge; + dimension = 1; + constructor(end, trans, inEdge = true) { + this.end = end; + this.trans = trans; + this.inEdge = inEdge; + this.renderedElement = inEdge ? new SVGArrow(end, trans) : new SVGArrow(trans, end); + this.renderedElement.appendIt(arrows); + end.updateList.push(this); + } + canSuck() { + return this.end.marks >= this.dimension; + } + suck() { + this.end.marks -= this.dimension; + this.end.updatePoints(); + } + canPush() { + return this.end.capacity >= this.end.marks + this.dimension; + } + push() { + this.end.marks += this.dimension; + this.end.updatePoints(); + } + updatePosition() { + this.renderedElement.updatePosition(); + } +} + +class Node { + renderedElement; + x = 0; + y = 0; + name; + capacity = 1; + marks = 0; + + updateList = []; + + constructor(name, x, y) { + this.name = name; + this.x = x; + this.y = y; + this.renderedElement = new SVGNode(this); + this.renderedElement.appendIt(nods); + } + + updatePoints() { + this.renderedElement.setMarks(this.marks, this.capacity); + } + + updatePosition(x, y) { + this.x = x; + this.y = y; + this.renderedElement.translate(x, y); + for (const elem of this.updateList) { + elem.updatePosition(); + } + } +} + +class Transition { + renderedElement; + name = "noname"; + inEdges = []; + outEdges = []; + x; + y; + constructor(name, x, y) { + this.name = name; + this.x = x; + this.y = y; + this.renderedElement = new SVGTRansition(this); + this.renderedElement.appendIt(nods); + } + canFire() { + for (const inE of this.inEdges) { + if (!inE.canSuck()) { + this.renderedElement.setCanFire(false); + return false; + } + } + for (const outE of this.outEdges) { + if (!outE.canPush()) { + this.renderedElement.setCanFire(false); + return false; + } + } + this.renderedElement.setCanFire(true); + return true; + } + fire() { + if (!this.canFire()) return false; + for (const inE of this.inEdges) { + inE.suck(); + } + for (const outE of this.outEdges) { + outE.push(); + } + return true; + } + updatePosition(x, y) { + this.x = x; + this.y = y; + this.renderedElement.translate(x, y); + for (const inE of this.inEdges) { + inE.updatePosition(); + } + for (const outE of this.outEdges) { + outE.updatePosition(); + } + } +} + +let transitions = []; +let nodes = []; + +function loop() { + for (const trans of transitions) { + console.log(trans.name, trans.fire()); + } + update(); +} + +function update() { + for (const nod of nodes) { + nod.updatePoints(); + } + for (const trans of transitions) { + trans.canFire(); + } +} + +window.onresize = () => { + svg.setAttribute("viewBox", `0 0 ${window.innerWidth} ${window.innerHeight}`); +} +window.onresize(); + + +let n1 = new Node("n1", 100, 100); +let n2 = new Node("n2", 100, 300); +let t1 = new Transition("t1", 100, 200); +t1.inEdges.push(new Edge(n1, t1, true)) +t1.outEdges.push(new Edge(n2, t1, false)); + +nodes.push(n1, n2); +transitions.push(t1); \ No newline at end of file