Skip to content

Commit c7e9c06

Browse files
committed
style changes and selectable links
1 parent 5b8f8bb commit c7e9c06

File tree

6 files changed

+193
-295
lines changed

6 files changed

+193
-295
lines changed

css/style.css

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,38 @@ button {
4848
bottom:0;
4949
left:0;
5050
overflow:hidden;
51+
}
52+
53+
54+
/* svg classes */
55+
#drawing text, .link--labels text {
56+
pointer-events: none;
57+
}
58+
59+
.row--0, .link--label {
60+
fill: #f6f6f6;
61+
}
62+
.row--1, .link--label.odd {
63+
fill: #d5d5d5;
64+
}
65+
66+
.word--underneath {
67+
fill:white;
68+
}
69+
70+
.selected .word--underneath, .link--label.selected {
71+
fill:white;
72+
stroke:teal;
73+
}
74+
.hovered .word--underneath, .link--label.hovered {
75+
fill:white;
76+
stroke:cyan;
77+
}
78+
79+
.word--handle {
80+
fill: rgb(255, 204, 204);
81+
opacity: 0;
82+
}
83+
.word:hover .word--handle {
84+
opacity: 0.7;
5185
}

index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,16 @@
9090
recalculateRows(widthPercChange); //makes sure that the words fit in the current width, else makes new rows
9191
}
9292

93+
function getSelectedObjects() {
94+
return wordObjs.concat(linkObjs).filter(obj => obj.isSelected);
95+
}
96+
9397
draw.on('wordSelected', function() {
94-
Panel.graph(wordObjs.filter(word => word.isSelected));
98+
Panel.graph(getSelectedObjects());
9599
});
96100

97101
document.querySelector('#graph>button').onclick = function() {
98-
let words = wordObjs.filter(word => word.isSelected);
102+
let words = getSelectedObjects();
99103
if (words.length > 0) {
100104
Panel.graph(words);
101105
}

js/GraphLayout.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class GraphLayout {
6666
}
6767
graph(words) {
6868
if (words.length === 0 || this.words.length === words.length &&
69-
this.words.every((w,i) => words[i] === w)) { return; }
69+
this.words.every((w,i) => words.indexOf(w) > -1)) { return; }
7070
else { this.words = words; }
7171

7272
const maxDepth = this.maxDepth;
@@ -219,17 +219,21 @@ class GraphLayout {
219219
}
220220
drawNodes(root, i, el) {
221221
function handleNodeClick(d) {
222+
unhoverNode(d);
222223
let newArray = this.words.slice();
223224
let word = newArray.splice(i, 1, d.node)[0];
224-
if (word instanceof Word) {
225-
word.toggleHighlight(false);
226-
}
227-
if (d.node instanceof Word) {
228-
d.node.toggleHighlight(true);
229-
}
225+
word.toggleHighlight(false);
226+
d.node.toggleHighlight(true);
230227
this.graph(newArray);
231228
}
232229

230+
function hoverNode(d) {
231+
d.node.hover();
232+
}
233+
function unhoverNode(d) {
234+
d.node.unhover();
235+
}
236+
233237
let node = el.selectAll('.node')
234238
.data(root.descendants());
235239

@@ -265,6 +269,8 @@ class GraphLayout {
265269
.attr('transform', (d) => d.data.receivesArrow && d.data.type === 'Word' ? 'rotate(-30)' : 'rotate(45)')
266270
.attr('stroke', 'grey')
267271
.attr('fill', (d) => d.data.type === 'Word' ? 'black' : 'white')
272+
.on('mouseover', (d) => hoverNode.bind(this)(d.data))
273+
.on('mouseout', (d) => unhoverNode.bind(this)(d.data))
268274
.on('click', (d) => handleNodeClick.bind(this)(d.data));
269275

270276
nodeMerge.select('text')
@@ -313,9 +319,9 @@ class GraphLayout {
313319
.style('text-anchor','end');
314320

315321
let inMerge = inEnter.merge(incoming)
316-
.attr('transform', (d, i) => 'translate(-30,' + (-20 * i - 20) + ')');
317-
318-
inMerge.select('circle')
322+
.attr('transform', (d, i) => 'translate(-30,' + (-20 * i - 20) + ')')
323+
.on('mouseover', (d) => hoverNode.bind(this)(d))
324+
.on('mouseout', (d) => unhoverNode.bind(this)(d))
319325
.on('click', (d) => handleNodeClick.bind(this)(d));
320326

321327
inMerge.select('path')

js/annotate.js

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,6 @@ class Link {
9999
this.labelTextSVG = null;
100100
}
101101

102-
//KLEE's function..
103-
removeSVGs() {
104-
this.polylineSVGs.forEach(svg => svg.remove());
105-
this.labelRectSVGs.forEach(svg => svg.remove());
106-
this.labelTextSVGs.forEach(svg => svg.remove());
107-
this.arrow1Style.path.remove();
108-
this.arrow2Style.path.remove();
109-
}
110-
//end KLEE
111-
112102
get parents() {
113103
return [].concat(this.parentsL, this.parentsC, this.parentsR);
114104
}
@@ -117,6 +107,24 @@ class Link {
117107
return this.id;
118108
}
119109

110+
toggleHighlight(select) {
111+
// default value
112+
if (select === undefined) {
113+
this.isSelected = !this.isSelected;
114+
}
115+
else {
116+
this.isSelected = select;
117+
}
118+
119+
this.labelRectSVGs.forEach(rect => rect.toggleClass('selected', this.isSelected));
120+
}
121+
122+
hover(label) {
123+
this.labelRectSVGs.forEach(rect => rect.addClass('hovered'));
124+
}
125+
unhover(label) {
126+
this.labelRectSVGs.forEach(rect => rect.removeClass('hovered'));
127+
}
120128

121129
setStartAndEnd() {
122130

@@ -160,9 +168,8 @@ class Row {
160168

161169
//svg elements
162170
this.rect = null;
163-
this.lineTop = null;
164171
this.lineBottom = null
165-
this.dragRect = null;
172+
this.dragRect = null;
166173
}
167174

168175

@@ -207,22 +214,21 @@ class Word {
207214
this.parentsR = []; //who connects to me and is attached to my right side
208215
this.parentsC = []; //who connects to me and is attached to the center (ie, for multilinks)
209216

210-
211-
212-
//this.lines = []; //don't this is used, double check then remove!
213-
214217
this.tw = 0; //width of text part of word, used also to determine minimum size of word rect
215218
this.th = 0;
216219

217220
this.percPos = 0.0; //this is used to indicate where along the row the word is positioned, used when resizing the browser's width, or when popping open a right panel.
218221

219222
this.isSelected = false;
220-
this.isHovered = false;
221223
this.isDragging = false;
222224

223225
//variables created in first render...
226+
224227
this.row = null; //this is a row object, for row num do: this.row.idx
225-
this.aboveRect = null; //the top level, clickable rect
228+
229+
this.svg = null; // group element within which rect, text, and handles are nested
230+
// TODO: transform this.svg instead of individual children
231+
226232
this.bbox = null; //the bbox of the clickable rect
227233
this.underneathRect = null; //solid rect on which other word parts are placed (text, handles, clickable rect)
228234
this.text = null; //the svg text
@@ -247,13 +253,11 @@ class Word {
247253
update() {
248254

249255
//// console.log("\n***\nin update X = " + this.tempX + ", Y = " + this.tempY + ", W = " + this.tempW );
250-
this.aboveRect.x(this.tempX);
251-
this.aboveRect.width(this.tempW);
252256

253257
this.underneathRect.x(this.tempX);
254258
this.underneathRect.width(this.tempW);
255259

256-
this.bbox = this.aboveRect.bbox();
260+
this.bbox = this.underneathRect.bbox();
257261

258262
this.text.x(this.tempX + (this.tempW/2) - (this.text.bbox().w / 2) );
259263

@@ -296,14 +300,14 @@ class Word {
296300
this.isSelected = select;
297301
}
298302

299-
let style;
300-
if (this.isSelected) {
301-
style = this.isHovered ? "hoverAndSelect" : "select";
302-
}
303-
else {
304-
style = this.isHovered ? "hover" : "style";
305-
}
306-
this.underneathRect.style(styles.wordFill[style]);
303+
this.svg.toggleClass('selected', this.isSelected);
304+
}
305+
306+
hover() {
307+
this.svg.addClass('hovered');
308+
}
309+
unhover() {
310+
this.svg.removeClass('hovered');
307311
}
308312

309313
toString() {

0 commit comments

Comments
 (0)