Skip to content

Commit 4fc9fe4

Browse files
committed
initial linear tree vis prototype
1 parent 9595dc4 commit 4fc9fe4

File tree

5 files changed

+428
-337
lines changed

5 files changed

+428
-337
lines changed

css/style.css

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
body {
2+
margin:0;
3+
-moz-osx-font-smoothing:grayscale;
4+
-webkit-font-smoothing:antialiased;
5+
font-family: BrownPro, Brown, futura, helvetica, arial, sans-serif;
6+
font-size: 11px;
7+
}
8+
9+
svg text {
10+
cursor: default;
11+
-webkit-user-select: none;
12+
-moz-user-select: none;
13+
-ms-user-select: none;
14+
user-select: none;
15+
}
16+
17+
#header {
18+
position:absolute;
19+
top:0;
20+
left:0;
21+
background:#333;
22+
color:white;
23+
width:calc( 100% - 20px );
24+
padding:10px;
25+
}
26+
27+
#drawing {
28+
margin-top:30px;
29+
margin-bottom: 230px;
30+
}
31+
32+
button {
33+
position:absolute;
34+
background:white;
35+
border:none;
36+
outline:none;
37+
cursor:pointer;
38+
}
39+
40+
.node { cursor: pointer; }
41+
42+
#graph {
43+
width:100%;
44+
height:220px;
45+
border-top: 1px solid #ccc;
46+
background:#fff;
47+
position:fixed;
48+
bottom:0;
49+
left:0;
50+
overflow:hidden;
51+
}

index.html

Lines changed: 103 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,12 @@
11
<html>
22
<head>
3-
4-
<!-- turns off text selection for svg canvas -->
5-
<style>
6-
body {
7-
margin:0;
8-
-moz-osx-font-smoothing:grayscale;
9-
-webkit-font-smoothing:antialiased;
10-
}
11-
12-
svg text {
13-
cursor: default;
14-
-webkit-user-select: none;
15-
-moz-user-select: none;
16-
-ms-user-select: none;
17-
user-select: none;
18-
}
19-
20-
#header {
21-
position:absolute;
22-
top:0;
23-
left:0;
24-
background:#333;
25-
color:white;
26-
width:calc( 100% - 20px );
27-
padding:10px;
28-
}
29-
30-
#drawing {
31-
margin-top:30px;
32-
}
33-
34-
button {
35-
background:white;
36-
border:none;
37-
outline:none;
38-
}
39-
40-
button.active {
41-
background:#ff8;
42-
}
43-
44-
.split-left {width:66.5%; overflow:hidden;}
45-
.split-right {transform:translateX(0) !important;}
46-
.node { cursor: pointer; }
47-
#graph {
48-
transition:transform 200ms ease;
49-
transform:translateX(100%);
50-
width:33%;
51-
height:100%;
52-
background:#fafaea;
53-
position:fixed;
54-
top:0;
55-
right:0;
56-
}
57-
58-
</style>
59-
3+
<meta charset="utf-8">
4+
<link href="css/style.css" rel="stylesheet">
605
</head>
616

627
<body>
638

649
<div id="header">
65-
<button id="random">random graph</button>
6610
<select id="dataset">
6711
<option>-- select dataset --</option>
6812
<option>data1</option>
@@ -73,7 +17,9 @@
7317
</div>
7418

7519
<div id="drawing">
76-
20+
</div>
21+
<div id="graph">
22+
<button>(Reset)</button>
7723
</div>
7824

7925

@@ -136,136 +82,121 @@
13682
var prevWidth = Config.svgWidth;
13783
function svgResize() {
13884
var widthPercChange;
139-
if (Panel.isOpen) {
140-
Config.svgWidth = (window.innerWidth - 16) * 0.665;
141-
}
142-
else {
143-
Config.svgWidth = (window.innerWidth - 16)
144-
}
85+
Config.svgWidth = (window.innerWidth - 16);
14586
changeSizeOfSVGPanel(Config.svgWidth, draw.height());
14687
widthPercChange = Config.svgWidth / prevWidth;
14788
prevWidth = Config.svgWidth;
14889
recalculateRows(widthPercChange); //makes sure that the words fit in the current width, else makes new rows
14990
}
15091

151-
function handleKeyDown(e) {
152-
var key = e.keyCode || e.which;
153-
// console.log('keycode',key);
154-
switch(key) {
155-
case 37: // left arrow
156-
if (Panel.isOpen) {
157-
Panel.close();
158-
svgResize();
159-
}
160-
break;
161-
case 39: // right arrow
162-
if (!Panel.isOpen) {
163-
Panel.open();
164-
svgResize();
165-
}
166-
Panel.graph(wordObjs.filter(word => word.isSelected));
167-
break;
168-
default:
169-
break;
92+
draw.on('wordSelected', function() {
93+
Panel.graph(wordObjs.filter(word => word.isSelected));
94+
});
95+
96+
document.querySelector('#graph>button').onclick = function() {
97+
let words = wordObjs.filter(word => word.isSelected);
98+
if (words.length > 0) {
99+
Panel.graph(words);
100+
}
101+
else {
102+
Panel.clear();
170103
}
171104
};
172105

173-
function changeDataset() {
174-
Config.redraw = 0;
175-
if (this.selectedIndex > 0) {
176-
parser.readJson(`./data/data${this.selectedIndex}.json`, function() {
106+
function changeDataset(index = 1) {
107+
parser.readJson(`./data/data${index}.json`, function() {
108+
Panel.clear();
177109

178-
// construct word objects and tags from tokens, entities, and triggers
179-
const words = parser.tokens.map((token, i) => new Word(token, i));
110+
// construct word objects and tags from tokens, entities, and triggers
111+
const words = parser.tokens.map((token, i) => new Word(token, i));
180112

181-
[].concat(parser.data.entities, parser.data.triggers).forEach(el => {
182-
if (words[el.tokenIndex]) {
183-
words[el.tokenIndex].tag = el.type;
184-
words[el.tokenIndex].eventId = el.id;
113+
[].concat(parser.data.entities, parser.data.triggers).forEach(el => {
114+
if (words[el.tokenIndex]) {
115+
words[el.tokenIndex].tag = el.type;
116+
words[el.tokenIndex].eventId = el.id;
117+
}
118+
});
119+
wordObjs = words;
120+
121+
// construct links from events and relations
122+
const links = [];
123+
parser.data.events.forEach(evt => {
124+
const trigger = words.find(word => word.eventId === evt.trigger);
125+
126+
// create a link between the trigger and each of its arguments
127+
evt.arguments.map(arg => {
128+
let anchor;
129+
switch (arg.id.charAt(0)) {
130+
case 'E':
131+
anchor = links.find(link => link.eventId === arg.id);
132+
break;
133+
case 'T':
134+
anchor = words.find(word => word.eventId === arg.id);
135+
break;
136+
default:
137+
console.log('unhandled argument type', arg);
138+
break;
185139
}
186-
});
187-
wordObjs = words;
188-
189-
// construct links from events and relations
190-
const links = [];
191-
parser.data.events.forEach(evt => {
192-
const trigger = words.find(word => word.eventId === evt.trigger);
193-
194-
// create a link between the trigger and each of its arguments
195-
evt.arguments.map(arg => {
196-
let anchor;
197-
switch (arg.id.charAt(0)) {
198-
case 'E':
199-
anchor = links.find(link => link.eventId === arg.id);
200-
break;
201-
case 'T':
202-
anchor = words.find(word => word.eventId === arg.id);
203-
break;
204-
default:
205-
console.log('unhandled argument type', arg);
206-
break;
207-
}
208-
209-
// style the arrow
210-
const ltr = arg.type === 'Controlled';
211-
const direction = ltr ? [1, -1] : [-1, 1];
212-
const arrowType = arg.type === 'Theme' ? styles.simpleLine : ltr ? styles.gradientLine1 : styles.gradientLine1r;
213-
214-
// create link
215-
const link = new Link(
216-
[trigger, anchor],
217-
direction,
218-
arrowType,
219-
arg.type,
220-
texts.linkText
221-
);
222-
link.eventId = evt.id;
223-
224-
// push link to link array
225-
links.push(link);
226-
createLink(link);
227-
228-
});//evt.argument.map
229-
});//parser.data.events.forEach
230-
231-
parser.data.relations.forEach(rel => {
232-
let ltr = true;
233-
const arguments = rel.arguments.map((arg, i) => {
234-
let anchor;
235-
switch (arg.id.charAt(0)) {
236-
case 'E':
237-
anchor = links.find(link => link.eventId === arg.id);
238-
break;
239-
case 'T':
240-
anchor = words.find(word => word.eventId === arg.id);
241-
break;
242-
default:
243-
console.log('unhandled argument type', arg);
244-
break;
245-
}
246-
if (arg.type === 'Controlled' && i > 0) {
247-
ltr = false;
248-
}
249-
return anchor;
250-
});
140+
141+
// style the arrow
142+
const ltr = arg.type !== 'Controller';
143+
const direction = ltr ? [1, -1] : [-1, 1];
144+
const arrowType = arg.type === 'Theme' ? styles.simpleLine : ltr ? styles.gradientLine1 : styles.gradientLine1r;
251145

252146
// create link
253147
const link = new Link(
254-
arguments,
255-
ltr ? [-1, 1] : [1, -1],
256-
ltr ? styles.gradientLine2 : styles.gradientLine2r,
257-
rel.type,
148+
[trigger, anchor],
149+
direction,
150+
arrowType,
151+
arg.type,
258152
texts.linkText
259153
);
154+
link.eventId = evt.id;
260155

261156
// push link to link array
262157
links.push(link);
263158
createLink(link);
159+
160+
});//evt.argument.map
161+
});//parser.data.events.forEach
162+
163+
parser.data.relations.forEach(rel => {
164+
let ltr = true;
165+
const arguments = rel.arguments.map((arg, i) => {
166+
let anchor;
167+
switch (arg.id.charAt(0)) {
168+
case 'E':
169+
anchor = links.find(link => link.eventId === arg.id);
170+
break;
171+
case 'T':
172+
anchor = words.find(word => word.eventId === arg.id);
173+
break;
174+
default:
175+
console.log('unhandled argument type', arg);
176+
break;
177+
}
178+
if (arg.type === 'Controlled' && i > 0) {
179+
ltr = false;
180+
}
181+
return anchor;
264182
});
265183

266-
resetDrawing(words, links);
184+
// create link
185+
const link = new Link(
186+
arguments,
187+
ltr ? [-1, 1] : [1, -1],
188+
ltr ? styles.gradientLine2 : styles.gradientLine2r,
189+
rel.type,
190+
texts.linkText
191+
);
192+
193+
// push link to link array
194+
links.push(link);
195+
createLink(link);
267196
});
268-
}
197+
198+
resetDrawing(words, links);
199+
});
269200
};
270201

271202
function resetDrawing(words, links) {
@@ -297,11 +228,15 @@
297228
Panel.resize();
298229
}
299230

300-
document.addEventListener('keydown', handleKeyDown, false);
301-
document.getElementById('random').onclick = resetDrawing.bind(this, null, null);
302-
document.getElementById('dataset').onchange = changeDataset;
231+
document.getElementById('dataset').onchange = function() {
232+
Config.redraw = 0;
233+
if (this.selectedIndex > 0) {
234+
changeDataset(this.selectedIndex);
235+
}
236+
};
303237
window.onresize = _.debounce(resize, 300);
304238

239+
changeDataset();
305240
};
306241

307242
</script>

0 commit comments

Comments
 (0)