Skip to content

Commit 87bd8fd

Browse files
committed
load external files
1 parent a99db24 commit 87bd8fd

File tree

5 files changed

+148
-17
lines changed

5 files changed

+148
-17
lines changed

css/style.css

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ header > button:hover {
7373
padding:5px;
7474
font-size:15px;
7575
}
76-
76+
label[for="file-input"] {
77+
padding:15px;
78+
cursor:pointer;
79+
background:steelblue;
80+
color:white;
81+
margin:10px 0;
82+
display:inline-block;
83+
border-radius:5px;
84+
}
7785

7886
/* modal */
7987
.modal {

index.html

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
<div id="brat-input" class="modal">
3131
<div>
3232
<header>
33-
<span class="tab active">Load file</span>
33+
<span class="tab active">Custom annotation</span>
3434
</header>
3535
<div class="page active">
36-
<div>
37-
<button><label for="file-input">Upload</label></button>
38-
<input type="file" id="file-input" style="display:none;">
39-
</div>
40-
<textarea></textarea>
36+
<form id="form">
37+
<label for="file-input">Upload file(s)</label>
38+
<input type="file" id="file-input" style="display:none;" multiple>
39+
</form>
40+
<textarea id="text-input"></textarea>
4141
<div id="error-message"></div>
4242
</div>
4343
</div>

js/ann-parser.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ const parseAnn = (function() {
105105
}
106106
}
107107

108-
function parse(input) {
108+
function parse(textInput, annInput) {
109109

110110
var output = {
111111
texts: [],
@@ -118,9 +118,17 @@ const parseAnn = (function() {
118118
mentions: {}
119119
}
120120

121-
let lines = input.split('\n');
121+
let text, lines;
122+
123+
if (!annInput) {
124+
let splitLines = textInput.split('\n');
125+
text = splitLines[0];
126+
lines = splitLines.slice(1);
127+
} else {
128+
text = textInput;
129+
lines = annInput.split('\n');
130+
}
122131

123-
let text = lines[0];
124132
if (!text) {
125133
output.unparsedLines = lines;
126134
return output;
@@ -130,7 +138,7 @@ const parseAnn = (function() {
130138
let unparsedLines = [];
131139
let mentions = {};
132140

133-
for (let i = 1; i < lines.length; ++i) {
141+
for (let i = 0; i < lines.length; ++i) {
134142
const line = lines[i].trim();
135143
if (!line) { continue; }
136144

js/main.js

Lines changed: 117 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,8 @@ const Main = (function() {
2525
/**
2626
* init: set up singleton classes and create initial drawing
2727
*/
28-
let _initialized = false;
2928
function init() {
3029
// setup
31-
if (_initialized) { return; }
32-
_initialized = true;
3330
body = document.body.getBoundingClientRect();
3431
svg = SVG('main')
3532
.size(body.width, window.innerHeight - body.top - 10);
@@ -44,6 +41,12 @@ const Main = (function() {
4441
// load and render initial dataset by default
4542
changeDataset();
4643

44+
setupSVGListeners();
45+
setupUIListeners();
46+
} // end init
47+
48+
49+
function setupSVGListeners() {
4750
// svg event listeners
4851
svg.on('row-resize', function(e) {
4952
lm.stopEditing();
@@ -104,7 +107,9 @@ const Main = (function() {
104107
tree.resize();
105108
}
106109
});
110+
}
107111

112+
function setupUIListeners() {
108113
// window event listeners
109114
// resize function
110115
function resizeWindow() {
@@ -215,7 +220,114 @@ const Main = (function() {
215220
e.target.classList.remove('open');
216221
}
217222
});
223+
224+
document.getElementById('file-input').onchange = loadFile;
225+
}
226+
227+
function printErrorMessage(text) {
228+
document.getElementById('error-message').textContent = text;
218229
}
230+
function clearErrorMessage() {
231+
document.getElementById('error-message').textContent = '';
232+
}
233+
function clearFile() {
234+
document.getElementById('form').reset();
235+
document.getElementById('text-input') = '';
236+
}
237+
238+
/**
239+
* loadFile: read file
240+
*/
241+
function loadFile(e) {
242+
let files = e.target.files;
243+
console.log(files);
244+
245+
// get extension
246+
if (files.length === 1) {
247+
const file = files[0];
248+
let fr = new FileReader();
249+
fr.readAsText(file);
250+
fr.onload = parseFile;
251+
252+
function parseFile() {
253+
clearErrorMessage();
254+
const text = fr.result;
255+
256+
// try to coerce it into an accepted format
257+
try {
258+
let w, l, c;
259+
if (file.type === 'application/json') {
260+
// reach json
261+
parser.parseJson(JSON.parse(text));
262+
[w, l, c] = buildWordsAndLinks();
263+
} else if (!file.type) {
264+
// brat standoff
265+
[w, l, c] = buildWordsLinksAnn(text);
266+
} else {
267+
printErrorMessage("Could not read file type: " + file.type);
268+
}
269+
270+
if (w && l && c) {
271+
clear();
272+
[words, links, clusters] = [w, l, c];
273+
setSyntaxVisibility();
274+
draw();
275+
document.getElementById('text-input').textContent = text;
276+
}
277+
} catch(e) {
278+
console.log(fr.result, e);
279+
printErrorMessage("See error in console");
280+
}
281+
}
282+
}
283+
else if (files.length > 1) {
284+
// search for matching .ann and .txt file
285+
286+
// sort by name
287+
let sortedFiles = [].slice.call(files).sort((a,b) => a.name.localeCompare(b.name));
288+
289+
let prev = 0;
290+
291+
for (let i = 1; i < sortedFiles.length; ++i) {
292+
let f1 = sortedFiles[prev].name.toLowerCase(),
293+
f2 = sortedFiles[i].name.toLowerCase();
294+
let prefixesMatch = f1.slice(0, f1.lastIndexOf('.')) === f2.slice(0, f2.lastIndexOf('.'));
295+
let typesMatch = f1.endsWith('.ann') || f2.endsWith('.ann');
296+
if (prefixesMatch && typesMatch && f1 !== f2) {
297+
// matching files found
298+
let fr = new FileReader();
299+
fr.readAsText(sortedFiles[prev]);
300+
fr.onload = function() {
301+
let f1Text = fr.result;
302+
fr.readAsText(sortedFiles[i]);
303+
fr.onload = function() {
304+
let w, l, c, text;
305+
if (f1.endsWith('.ann')) {
306+
text = fr.result;
307+
[w, l, c] = buildWordsLinksAnn(fr.result, f1Text);
308+
}
309+
else {
310+
text = f1Text;
311+
[w, l, c] = buildWordsLinksAnn(f1Text, fr.result);
312+
}
313+
314+
if (w && l && c) {
315+
clear();
316+
[words, links, clusters] = [w, l, c];
317+
setSyntaxVisibility();
318+
draw();
319+
document.getElementById('text-input').textContent = text;
320+
}
321+
}
322+
};
323+
break;
324+
} else {
325+
prev = i;
326+
}
327+
}
328+
}
329+
}
330+
219331

220332
/**
221333
* changeDataset: read and parse data from a json file in the /data folder
@@ -327,7 +439,6 @@ const Main = (function() {
327439
w.setSyntaxId(token.id);
328440
return w;
329441
});
330-
console.log('words',words);
331442
const clusters = [];
332443

333444
[].concat(parser.data.entities, parser.data.triggers).forEach(el => {
@@ -407,8 +518,8 @@ const Main = (function() {
407518
return [ words, links, clusters ];
408519
}
409520

410-
function buildWordsLinksAnn(text) {
411-
let data = parseAnn(text);
521+
function buildWordsLinksAnn(text, ann) {
522+
let data = parseAnn(text, ann);
412523
let mentions = {};
413524

414525
// build words

js/parser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ const Parser = (function() {
111111
})
112112
}
113113

114+
parseJson(json) {
115+
parseData(json);
116+
}
117+
114118
get tokens() { return _tokens; }
115119
get text() { return _text; }
116120
get data() { return _data; }

0 commit comments

Comments
 (0)