From 78436cd98c3a25ba33d147d1714109bceab62c38 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Wed, 10 Jul 2019 20:03:05 +0000 Subject: [PATCH] Link labels --- Architype.js | 14 ++++++++++++++ Layout.js | 4 +++- LayoutLink.js | 44 +++++++++++++++++++++++++++++++++++++++++++- architype.css | 13 ++++++++++++- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/Architype.js b/Architype.js index da176a3..3bb603f 100644 --- a/Architype.js +++ b/Architype.js @@ -129,6 +129,10 @@ class Architype { this.drawLine(step.pos, step.cls); break; + case 'linkLabel': + this.drawLinkLabel(step.pos, step.label); + break; + case 'node': this.drawNode(step.label, step.pos); break; @@ -188,6 +192,16 @@ class Architype { use.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#' + cls); } + drawLinkLabel(pos, label) { + let elem = document.createElement('div'); + elem.classList.add('gridLinkLabel'); + this.grid_.appendChild(elem); + elem.innerText = label; + elem.style.gridColumn = pos[0] + 1; + elem.style.gridRow = pos[1] + 1; + this.toSize_.push(elem); + } + drawNode(label, pos) { let node = document.createElement('div'); node.classList.add('gridNode'); diff --git a/Layout.js b/Layout.js index f8cfb51..e26ab6b 100644 --- a/Layout.js +++ b/Layout.js @@ -7,6 +7,7 @@ class Layout { this.nodesByPos_ = new StringMap(); this.nodesByGraphNode_ = new Map(); this.linksByPos_ = new StringMap(); + this.labelsByPos_ = new StringMap(); this.links_ = []; this.setInitialPositions(); @@ -229,7 +230,8 @@ class Layout { for (let link of links) { this.links_.push( new LayoutLink(link.from, link.to, link.label, - this.nodesByPos_, this.linksByPos_)); + this.nodesByPos_, this.linksByPos_, + this.labelsByPos_)); } for (let link of this.links_) { diff --git a/LayoutLink.js b/LayoutLink.js index 91e0374..00c6194 100644 --- a/LayoutLink.js +++ b/LayoutLink.js @@ -1,10 +1,11 @@ class LayoutLink { - constructor(from, to, label, nodesByPos, linksByPos) { + constructor(from, to, label, nodesByPos, linksByPos, labelsByPos) { this.from_ = from; this.to_ = to; this.label_ = label; this.nodesByPos_ = nodesByPos; this.linksByPos_ = linksByPos; + this.labelsByPos_ = labelsByPos; this.bfs(); } @@ -180,6 +181,39 @@ class LayoutLink { } drawLabel() { + if (this.label_ == null || this.label_ == '') { + return; + } + + let minScore = Number.POSITIVE_INFINITY; + let labelPos = null; + + for (let i = 1; i < this.path.length - 1; ++i) { + let pos = this.path[i]; + let score = 0; + + if (this.nodesByPos_.has(pos)) { + // Never overlap nodes + continue; + } + + if (this.labelsByPos_.get(pos) == this.label_) { + // Already labeled by another link + return; + } + + // TODO: cheaper if we overlap with other links with the same label? + + if (score < minScore) { + minScore = score; + labelPos = pos; + } + } + + if (labelPos) { + this.labelPos_ = labelPos; + this.labelsByPos_.set(this.labelPos_, this.label_); + } } getSteps() { @@ -216,6 +250,14 @@ class LayoutLink { cls: 'a' + endInPoint, }); + if (this.labelPos_) { + steps.push({ + type: 'linkLabel', + pos: this.labelPos_, + label: this.label_, + }); + } + return steps; } } diff --git a/architype.css b/architype.css index 07d24f2..f15275d 100644 --- a/architype.css +++ b/architype.css @@ -12,6 +12,7 @@ --grid-background: #202020; --group-background: rgba(0,0,0,0.5); --node-background: #000000; + --link-label-background: rgba(0,0,0,0.8); --input: rgba(255,255,255,0.2); --input-focus: rgba(255,0,0,0.2); } @@ -139,7 +140,7 @@ body { padding: 10px; } -.gridNode, .gridGroup, .gridGroupLabel { +.gridNode, .gridGroup, .gridGroupLabel, .gridLinkLabel { display: flex; flex-direction: column; align-items: center; @@ -188,6 +189,16 @@ body { --line-color: white; } +.gridLinkLabel { + max-width: 80%; + max-height: 80%; + font-size: 16px; + background: var(--link-label-background); + z-index: 3; + border-radius: 4px; + padding: 3px; +} + .gridArrow { width: 100%; height: 100%;