11const Main = ( function ( ) {
22 // classes
3- let parser , lm , rm ;
3+ let parser , lm , rm , tm ;
44
55 // main svg element
66 let svg ;
@@ -12,7 +12,7 @@ const Main = (function() {
1212
1313 // other html elements
1414 let tooltip = { } ;
15- let tl = { } ;
15+ let tree = { } ;
1616
1717 //--------------------------------
1818 // public functions
@@ -30,7 +30,8 @@ const Main = (function() {
3030 parser = new Parser ( ) ;
3131 rm = new RowManager ( svg ) ;
3232 lm = new LabelManager ( svg ) ;
33- tl = new TreeLayout ( document . querySelector ( '#tree > svg' ) ) ;
33+ tm = new Taxonomy ( 'taxonomy' ) ;
34+ tree = new TreeLayout ( document . querySelector ( '#tree > svg' ) ) ;
3435
3536 // load and render initial dataset by default
3637 changeDataset ( 2 ) ;
@@ -59,7 +60,7 @@ const Main = (function() {
5960
6061 svg . on ( 'build-tree' , function ( e ) {
6162 setActiveTab ( 'tree' ) ;
62- tl . graph ( e . detail . object ) ;
63+ tree . graph ( e . detail . object ) ;
6364 } ) ;
6465
6566 // window event listeners
@@ -162,73 +163,11 @@ const Main = (function() {
162163 clear ( ) ;
163164 ymlToJson . convert ( 'taxonomy.yml.txt' , function ( taxonomy ) {
164165 [ words , links , clusters ] = buildWordsAndLinks ( ) ;
165-
166- //FIXME
167- console . log ( words . filter ( x => x . val === 'Silencing' ) . map ( x => x . links ) ) ;
168- // turn taxonomy into a proper tree
169- let tree = ( function ( ) {
170-
171- let flat = [ ] ;
172-
173- function createLinks ( val , i , n , parent ) {
174- let index = { i, n } ;
175- let obj = {
176- val,
177- parent,
178- index : parent ? parent . index . concat ( index ) : [ index ] ,
179- depth : parent ? parent . depth + 1 : 0 ,
180- ancestor : parent ? parent . ancestor : null ,
181- children : null
182- } ;
183- if ( ! obj . ancestor ) {
184- obj . ancestor = obj ;
185- obj . descendantCount = 0 ;
186- }
187- ++ obj . ancestor . descendantCount ;
188-
189- flat . push ( obj ) ;
190-
191- if ( ! ( typeof val === 'string' || val instanceof String ) ) {
192- let key = Object . keys ( val ) [ 0 ] ;
193- obj . val = key ;
194- obj . children = val [ key ] . map ( ( v , i ) => createLinks ( v , i , val [ key ] . length , obj ) ) ;
195- }
196- return obj ;
197- }
198-
199- let hierarchy = taxonomy . map ( ( val , i ) => createLinks ( val , i , taxonomy . length , null ) ) ;
200-
201- return {
202- hierarchy,
203- flat
204- }
205- } ) ( ) ;
206-
207- let tagTypes = { } ;
208- words . forEach ( word => {
209- if ( word . tag ) {
210- if ( tagTypes [ word . tag ] ) {
211- tagTypes [ word . tag ] . push ( word ) ;
212- }
213- else {
214- tagTypes [ word . tag ] = [ word ] ;
215- }
216- }
217- if ( word . clusters . length > 0 ) {
218- word . clusters . forEach ( cluster => {
219- if ( tagTypes [ cluster . val ] ) {
220- tagTypes [ cluster . val ] . push ( cluster ) ;
221- }
222- else {
223- tagTypes [ cluster . val ] = [ cluster ] ;
224- }
225- } ) ;
226- }
227- } ) ;
228-
229166 draw ( ) ;
230167
231- populateTaxonomy ( tree , tagTypes ) ;
168+ tm . buildTree ( taxonomy ) ;
169+ tm . buildTagTypes ( words ) ;
170+ tm . populateTaxonomy ( ) ;
232171 } ) ;
233172 } ) ;
234173 } ;
@@ -353,128 +292,6 @@ const Main = (function() {
353292 return [ words , links , clusters ] ;
354293 }
355294
356- function populateTaxonomy ( tree , tagTypes ) {
357- colors = [
358- '#3fa1d1' ,
359- '#ed852a' ,
360- '#2ca02c' ,
361- '#c34a1d' ,
362- '#a048b3' ,
363- '#e377c2' ,
364- '#bcbd22' ,
365- '#17becf' ,
366- '#e7298a' ,
367- '#e6ab02' ,
368- '#7570b3' ,
369- '#a6761d' ,
370- '#7f7f7f'
371- ] ;
372-
373-
374- function updateColor ( word , color ) {
375- if ( word instanceof Word ) {
376- word . tag . svgText . node . style . fill = color ;
377- }
378- else {
379- word . svgText . node . style . fill = color ;
380- }
381- } ;
382-
383- // populate taxonomy
384- let div = document . getElementById ( 'taxonomy' ) ;
385- div . innerHTML = '' ;
386- let ul = document . createElement ( 'ul' ) ;
387- div . appendChild ( ul ) ;
388-
389- function createLi ( el , ul ) {
390- let li = document . createElement ( 'li' ) ;
391- el . el = li ;
392-
393- // create checkbox
394- let cbox = document . createElement ( 'input' ) ;
395- cbox . setAttribute ( 'type' , 'checkbox' ) ;
396- li . appendChild ( cbox ) ;
397-
398- // text span
399- li . appendChild ( document . createTextNode ( el . val ) ) ;
400-
401- // create color picker input
402- let picker = document . createElement ( 'input' ) ;
403- picker . className = 'jscolor' ;
404-
405- // set initial value
406- let i = Object . keys ( tagTypes ) . indexOf ( el . val ) ;
407- if ( i > - 1 ) {
408- cbox . checked = true ;
409- picker . value = colors [ i ] || '#000000' ;
410-
411- // propagate color to colorless ancestors
412- let parent = el . parent ;
413- while ( parent && parent . el && ! parent . el . querySelector ( 'input.jscolor' ) . value ) {
414- parent . el . querySelector ( 'input.jscolor' ) . value = picker . value ;
415- parent = parent . parent ;
416- }
417- }
418- picker . setAttribute ( 'disabled' , ! cbox . checked ) ;
419- li . appendChild ( picker ) ;
420-
421- // recursively update picker colors
422- function updateChildColors ( ) {
423- let color = this . value ;
424- console . log ( 'color' , color ) ;
425- function recurse ( el ) {
426- if ( tagTypes [ el . val ] ) {
427- tagTypes [ el . val ] . forEach ( word => updateColor ( word , color ) ) ;
428- }
429- if ( el . children ) {
430- el . children . forEach ( recurse ) ;
431- }
432- }
433- recurse ( el ) ;
434- }
435-
436- // attach listeners
437- cbox . onclick = function ( ) {
438- // TODO: update children colors on click
439- if ( this . checked ) {
440- // enable current picker and disable children inputs
441- picker . removeAttribute ( 'disabled' ) ;
442- li . querySelectorAll ( 'input' ) . forEach ( input => {
443- if ( input . parentNode !== li ) {
444- input . setAttribute ( 'disabled' , true ) ;
445- }
446- } ) ;
447- updateChildColors . bind ( picker ) ;
448- }
449- else {
450- // enable children inputs
451- picker . setAttribute ( 'disabled' , true ) ;
452- let checkboxes = li . querySelectorAll ( 'input[type="checkbox"]' ) ;
453- let pickers = li . querySelectorAll ( 'input.jscolor' ) ;
454- checkboxes . forEach ( ( cbox , i ) => {
455- cbox . removeAttribute ( 'disabled' ) ;
456- pickers [ i ] . setAttribute ( 'disabled' , ! cbox . checked ) ;
457- } ) ;
458- updateChildColors ( ) ;
459- }
460- }
461- picker . onchange = updateChildColors ;
462-
463- if ( el . children ) {
464- let childUl = document . createElement ( 'ul' ) ;
465- li . appendChild ( childUl ) ;
466- el . children . forEach ( child => createLi ( child , childUl ) ) ;
467- }
468- ul . appendChild ( li ) ;
469- }
470- tree . hierarchy . forEach ( el => createLi ( el , ul ) ) ;
471- jscolor . installByClassName ( 'jscolor' ) ;
472-
473- Object . keys ( tagTypes ) . forEach ( ( tag , i ) => {
474- tagTypes [ tag ] . forEach ( word => updateColor ( word , colors [ i ] ) ) ;
475- } ) ;
476- }
477-
478295 // function populateOptions() {
479296 // document.querySelector('.reach').onclick = toggleEdgeVisibility;
480297 // document.querySelector('.pos').onclick = toggleEdgeVisibility;
0 commit comments