Skip to content

Commit fa7d3f5

Browse files
committed
adjust default arrow layout... performance cost (sort every time)
1 parent 789d6ac commit fa7d3f5

File tree

2 files changed

+59
-79
lines changed

2 files changed

+59
-79
lines changed

js/components/link.js

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,18 @@ class Link {
4747

4848
// init handles
4949
// get location of trigger
50-
const offset_multiplier = 8;
5150
if (this.trigger) {
52-
let offset = this.trigger.links.filter(l => l.top == this.top).indexOf(this) * offset_multiplier;
53-
if (this.trigger.idx > this.endpoints[0].idx) { offset *= -1; }
54-
let x = this.trigger.cx + offset;
51+
let x = this.trigger.cx;
5552
let y = this.top ? this.trigger.absoluteY : this.trigger.absoluteDescent;
56-
this.handles.push({ anchor: this.trigger, x, y, offset });
53+
this.handles.push({ anchor: this.trigger, x, y, offset: null });
5754
}
5855

5956
// draw arguments
6057
this.arguments.forEach(arg => {
6158
// get location of the argument
62-
let offset = arg.anchor.links.filter(l => l.top == this.top).indexOf(this) * offset_multiplier;
63-
if (arg.anchor.idx > this.endpoints[0].idx) { offset *= -1; }
64-
let x = arg.anchor.cx + offset;
59+
let x = arg.anchor.cx;
6560
let y = this.top ? arg.anchor.absoluteY : arg.anchor.absoluteDescent;
66-
this.handles.push({ anchor: arg.anchor, x, y, offset });
61+
this.handles.push({ anchor: arg.anchor, x, y, offset: null });
6762

6863
// draw svgText for each trigger-argument relation
6964
if (this.trigger) {
@@ -109,19 +104,10 @@ class Link {
109104
draggedHandle.offset += dx;
110105
let anchor = draggedHandle.anchor;
111106
if (anchor instanceof Link) {
112-
if (anchor.trigger) {
113-
if (anchor.trigger.idx > anchor.endpoints[0].idx) {
114-
console.log('hey');
115-
}
116-
}
107+
let handles = anchor.handles.map(h => h.x).sort();
108+
let cx = draggedHandle.anchor.cx;
117109

118-
// let l = draggedHandle.anchor;
119-
// let boundaries = l.handles
120-
// // .filter(h => !l.trigger || h.anchor.row === l.trigger.row)
121-
// .map(h => h.x);
122-
// if (l.trigger) { console.log(l.trigger.row); }
123-
// console.log(boundaries);
124-
// // console.log(draggedHandle.anchor.cx, draggedHandle.anchor.endpoints);
110+
draggedHandle.offset = Math.min(handles[handles.length - 1] - cx, Math.max(handles[0] - cx, draggedHandle.offset));
125111
}
126112
else {
127113
let halfWidth = anchor.boxWidth / 2;
@@ -161,11 +147,32 @@ class Link {
161147
}
162148

163149
draw(anchor) {
164-
// redraw handles if word or link was moved
165-
let h = this.handles.find(h => (anchor === h.anchor));
166-
if (h) {
167-
h.x = anchor.cx + h.offset;
168-
h.y = this.top ? anchor.absoluteY : anchor.absoluteDescent;
150+
if (!anchor) {
151+
// initialize offsets
152+
this.handles.forEach(h => {
153+
if (h.offset === null) {
154+
let l = h.anchor.links
155+
.sort((a,b) => a.slot - b.slot)
156+
.filter(link => link.top == this.top);
157+
158+
if (l.length > 1) {
159+
l = l.filter(link => h.anchor.idx > link.endpoints[0].idx == h.anchor.idx > this.endpoints[0].idx);
160+
let w = 10; // magic number => TODO: resize this to tag width?
161+
h.offset = (l.indexOf(this) + 0.5) / l.length * (h.anchor.idx > this.endpoints[0].idx ? -w : w);
162+
}
163+
else {
164+
h.offset = 0;
165+
}
166+
}
167+
});
168+
}
169+
else {
170+
// redraw handles if word or link was moved
171+
let h = this.handles.find(h => (anchor === h.anchor));
172+
if (h) {
173+
h.x = anchor.cx + h.offset;
174+
h.y = this.top ? anchor.absoluteY : anchor.absoluteDescent;
175+
}
169176
}
170177

171178
if (!this.visible) { return; }
@@ -282,15 +289,22 @@ class Link {
282289
let avg;
283290

284291
if (this.handles[0].anchor.row.idx === endHandle.anchor.row.idx) {
285-
avg = this.arguments.reduce((acc, a) => acc + a.anchor.cx, 0) / this.arguments.length;
286-
d = 'M' + [this.handles[0].x, this.handles[0].y]
287-
+ 'C' + [this.handles[0].x, y, this.handles[0].x, y, this.handles[0].x + 5, y]
288-
+ 'L' + [avg - textlen / 2, y]
289-
+ 'm' + [textlen, 0]
290-
+ 'L' + [endHandle.x - 5, y]
291-
+ 'C' + [endHandle.x, y, endHandle.x, y, endHandle.x, endHandle.y]
292-
+ this.arrowhead(this.handles[0])
293-
+ this.arrowhead(endHandle);
292+
avg = this.handles.reduce((acc, h) => acc + h.x, 0) / this.arguments.length;
293+
let textLeft = avg - textlen / 2;
294+
295+
d = 'M' + [this.handles[0].x, this.handles[0].y] +
296+
(textLeft < this.handles[0].x
297+
? ('L' + [this.handles[0].x, y]
298+
+ 'M' + [endHandle.x, y]
299+
+ 'L' + [endHandle.x, endHandle.y] )
300+
: ('C' + [this.handles[0].x, y, this.handles[0].x, y, Math.min(textLeft, this.handles[0].x + 5), y]
301+
+ 'L' + [textLeft, y]
302+
+ 'm' + [textlen, 0]
303+
+ 'L' + [Math.max(textLeft + textlen, endHandle.x - 5), y]
304+
+ 'C' + [endHandle.x, y, endHandle.x, y, endHandle.x, endHandle.y] )
305+
)
306+
+ this.arrowhead(this.handles[0])
307+
+ this.arrowhead(endHandle);
294308
}
295309
else {
296310
avg = (this.handles[0].x + width) / 2;

js/components/wordcluster.js

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -101,62 +101,28 @@ class WordCluster {
101101
let lOffset = -this.endpoints[0].boxWidth / 2;
102102
let rOffset = this.endpoints[1].boxWidth / 2;
103103

104-
let dblheight = this.svgs[0].y() !== this.tagOffset;
105-
106104
if (this.endpoints[0].row === this.endpoints[1].row) {
107105
// draw left side of the brace and align text
108106
let center = (-left + right) / 2;
109107
this.x = center + lOffset;
110108
this.svgText.x(center + lOffset);
111-
if (dblheight && !this.endpoints[0].tag) {
112-
this.lines[0].plot('M' + lOffset + ',59l0,-5c0,-34,' + [center,-21,center,-29]);
113-
}
114-
else {
115-
this.lines[0].plot('M' + lOffset + ',33c0,-10,' + [center,0,center,-8]);
116-
}
117-
118-
// draw right side of the brace
119-
if (dblheight && !this.endpoints[1].tag) {
120-
this.lines[1].plot('M' + rOffset + ',59l0,-5c0,-34,' + [-center,-21,-center,-29]);
121-
}
122-
else {
123-
this.lines[1].plot('M' + rOffset + ',33c0,-10,' + [-center,0,-center,-8]);
124-
}
109+
this.lines[0].plot('M' + lOffset + ',33c0,-10,' + [center,0,center,-8]);
110+
this.lines[1].plot('M' + rOffset + ',33c0,-10,' + [-center,0,-center,-8]);
125111
}
126112
else {
127113
// draw right side of brace extending to end of row and align text
128114
let center = (-left + this.endpoints[0].row.rw) / 2 + 10;
129115
this.x = center + lOffset;
130116
this.svgText.x(center + lOffset);
131117

132-
if (dblheight && !this.endpoints[0].tag) {
133-
this.lines[0].plot('M' + lOffset + ',59l0,-5c0,-34,' + [center,-21,center,-29]);
134-
this.lines[0].plot('M' + lOffset
135-
+ ',59l0,-5c0,-34,' + [center,-21,center,-29]
136-
+ 'c0,10,' + [center,0,center,8]
137-
);
138-
}
139-
else {
140-
this.lines[0].plot('M' + lOffset
141-
+ ',33c0,-10,' + [center,0,center,-8]
142-
+ 'c0,10,' + [center,0,center,8]
143-
);
144-
}
145-
146-
// draw right side of the brace on the next row
147-
148-
if (dblheight && !this.endpoints[1].tag) {
149-
this.lines[1].plot('M' + rOffset
150-
+ ',59l0,-5c0,-34,' + [-right + 8, -21, -right + 8, -29]
151-
+ 'c0,10,' + [-right + 8, 0, -right + 8, 8]
152-
);
153-
}
154-
else {
155-
this.lines[1].plot('M' + rOffset
156-
+ ',33c0,-10,' + [-right + 8, 0, -right + 8, -8]
157-
+ 'c0,10,' + [-right + 8, 0, -right + 8, 8]
158-
);
159-
}
118+
this.lines[0].plot('M' + lOffset
119+
+ ',33c0,-10,' + [center,0,center,-8]
120+
+ 'c0,10,' + [center,0,center,8]
121+
);
122+
this.lines[1].plot('M' + rOffset
123+
+ ',33c0,-10,' + [-right + 8, 0, -right + 8, -8]
124+
+ 'c0,10,' + [-right + 8, 0, -right + 8, 8]
125+
);
160126
}
161127

162128
// propagate draw command to parent links

0 commit comments

Comments
 (0)