@@ -25,7 +25,7 @@ class GraphLayout {
2525
2626 // selected words to generate graph around
2727 this . words = [ ] ;
28- this . distanceFromRoot = 30 ; // default value for max dist from root
28+ this . maxDepth = 30 ; // default value for max dist from root
2929 this . data = {
3030 flat : { } ,
3131 anchors : [ ] ,
@@ -34,14 +34,6 @@ class GraphLayout {
3434
3535 // force simulation
3636 this . simulation = d3 . forceSimulation ( )
37- . force ( 'link' , d3 . forceLink ( ) . id ( d => d . id ) )
38- . force ( 'collision' , d3 . forceCollide ( d => {
39- return d . role === "link-anchor" ? 0 : 20 ;
40- } ) )
41- . force ( 'charge' , d3 . forceManyBody ( )
42- . strength ( d => d . role === "link-anchor" ? 0 : - 30 )
43- . distanceMax ( 100 )
44- )
4537 . force ( 'center' , d3 . forceCenter ( 0 , 0 ) ) ;
4638 }
4739
@@ -75,10 +67,11 @@ class GraphLayout {
7567 if ( this . words . length === words . length &&
7668 this . words . every ( ( w , i ) => words [ i ] === w ) ) { return ; }
7769 else { this . words = words ; }
78-
7970 this . generateData ( ) ;
8071 console . log ( 'data' , this . data ) ;
8172
73+ return ;
74+
8275 // draw nodes
8376 this . drawNodes ( ) ;
8477
@@ -90,102 +83,57 @@ class GraphLayout {
9083 }
9184
9285 generateData ( ) {
93- // flatten nodes/links within a given distance of selected words
94- var d = this . data . flat = { } ;
86+ console . log ( this . words ) ;
87+ const d = this . data . flat = { } ;
88+ const maxDepth = this . maxDepth ;
9589 this . words . forEach ( root => {
96- var maxDepth = this . distanceFromRoot ;
9790 function addToDataset ( node , depth ) {
9891 if ( depth > maxDepth ) { return ; } // done
9992 if ( d [ node . id ] && d [ node . id ] . depth <= depth ) { // skip
10093 return ;
10194 }
10295
103- if ( node . type === "WORD" ) {
96+ if ( node instanceof Word ) {
10497 d [ node . id ] = {
10598 id : node . id ,
10699 depth : depth ,
107100 data : node
108101 }
109102 }
110- else if ( node . type === "LINK" ) {
103+ else if ( node instanceof Link ) {
111104 d [ node . id ] = {
112105 id : node . id ,
113106 depth : depth ,
114107 data : node
115108 }
116109 // recurse to start/endpoint
117- if ( node . s ) { addToDataset ( node . s , depth + 1 ) ; }
118- if ( node . e ) { addToDataset ( node . e , depth + 1 ) ; }
110+ if ( node . words ) {
111+ node . words . forEach ( anchor => addToDataset ( anchor , depth + 1 ) ) ;
112+ }
119113 }
120114 // recurse to adjacent links
121- var links = [ ] . concat ( node . parentsL , node . parentsR ) ;
115+ var links = [ ] . concat ( node . parentsL , node . parentsC , node . parentsR ) ;
122116 links . forEach ( l => addToDataset ( l , depth + 1 ) ) ;
123117 }
124118 addToDataset ( root , 0 ) ;
125119 } ) ;
126120
127121 // sort flat data into nodes and links
128- var a = this . data . anchors = [ ] ;
129- var l = this . data . links = [ ] ;
122+ const a = this . data . anchors = [ ] ;
123+ const l = this . data . links = [ ] ;
130124
131- for ( var i in d ) {
132- if ( d [ i ] . data . type === "WORD" ) {
133- d [ i ] . role = "word" ;
134- a . push ( d [ i ] ) ;
125+ for ( var datum in d ) {
126+ if ( d [ datum ] . data instanceof Word ) {
127+ a . push ( d [ datum ] ) ;
135128 }
136129 else {
137- d [ i ] . stops = [ ] ;
138- d [ i ] . role = "link" ;
139- l . push ( d [ i ] ) ;
130+ l . push ( d [ datum ] ) ;
140131 }
141132 }
142133
143- // identify anchors (endpoints of links): can be words or other links
144- function getAnchorPoint ( node ) {
145- if ( d [ node . id ] ) {
146- if ( d [ node . id ] . role === "word" ) {
147- return d [ node . id ] ;
148- }
149- else {
150- // create anchor point along link
151- var linkAnchor = {
152- id : node . id ,
153- data : node ,
154- role : "link-anchor" ,
155- link : d [ node . id ]
156- } ;
157- linkAnchor . link . stops . push ( linkAnchor ) ; // circular ref
158- a . push ( linkAnchor ) ;
159- return linkAnchor ;
160- }
161- }
162- else {
163- // endpoint not in range of data
164- var emptyNode = {
165- id : node . id ,
166- data :node ,
167- role : "nil"
168- } ;
169- a . push ( emptyNode ) ;
170- return emptyNode ;
171- }
172- }
134+ console . log ( a , l ) ;
173135
174- l . forEach ( link => {
175- var s = link . data . s ,
176- e = link . data . e ;
177-
178- link . source = getAnchorPoint ( s ) ;
179- link . target = getAnchorPoint ( e ) ;
180- } ) ;
181136
182- // evenly space stops on initialization
183- l . forEach ( link => {
184- var tmax = link . stops . length + 1 ;
185- link . stops . forEach ( ( stop , i ) => {
186- stop . t = ( i + 1 ) / tmax ;
187- } )
188- } )
189137 } //end generateData()
190138
191139 drawNodes ( ) {
@@ -202,126 +150,18 @@ class GraphLayout {
202150 d . fy = d . y ;
203151 } )
204152 . on ( 'drag' , function ( d ) {
205- if ( d . role !== "link-anchor" ) {
206- d . fx += d3 . event . dx ,
207- d . fy += d3 . event . dy ;
208- }
209- else {
210- // get distance to source/target
211- var nsDx = d . link . source . x - d . x ,
212- nsDy = d . link . source . y - d . y ,
213- ntDx = d . link . target . x - d . x ,
214- ntDy = d . link . target . y - d . y ,
215-
216- esDx = d . link . source . x - d3 . event . x ,
217- esDy = d . link . source . y - d3 . event . y ,
218- etDx = d . link . target . x - d3 . event . x ,
219- etDy = d . link . target . y - d3 . event . y ;
220-
221- var nodeDistanceToSource = nsDx * nsDx + nsDy * nsDy ,
222- nodeDistanceToTarget = ntDx * ntDx + ntDy * ntDy ,
223- dragDistanceToSource = esDx * esDx + esDy * esDy ,
224- dragDistanceToTarget = etDx * etDx + etDy * etDy ;
225-
226- var direction = 0 ;
227- if ( dragDistanceToSource < nodeDistanceToSource ) {
228- direction = - 0.01 ;
229- }
230- else if ( dragDistanceToTarget < nodeDistanceToTarget ) {
231- direction = 0.01 ;
232- }
233- else {
234- direction = dragDistanceToSource < dragDistanceToTarget ?
235- - 0.01 : 0.01 ;
236- }
237- d . t = Math . max ( Math . min ( d . t + direction , 0.9 ) , 0.1 ) ;
238- }
153+ d . fx += d3 . event . dx ,
154+ d . fy += d3 . event . dy ;
239155 } )
240156 . on ( 'end' , ( d ) => {
241157 if ( ! d3 . event . active ) {
242158 sim . alphaTarget ( 0 ) ;
243159 }
244- if ( d . role !== "link-anchor" ) {
245- d . fx = d . fy = null ;
246- }
247160 } ) ;
248161
249162 // data entry/merge
250- var nodeGroup = this . nodes . selectAll ( '.node-group' )
251- . data ( this . data . anchors ) ;
252-
253- nodeGroup . exit ( ) . remove ( ) ;
254- var nodeEnter = nodeGroup . enter ( ) . append ( 'g' )
255- . attr ( 'class' , 'node-group' )
256- . attr ( "transform" , ( ) => {
257- return 'translate(' + this . bounds . width / 2 + ',' + this . bounds . height / 2 + ')' ;
258- } ) ;
259-
260- nodeEnter . append ( 'circle' )
261- . attr ( 'class' , 'node' ) ;
262- var label = nodeEnter . append ( 'g' )
263- . attr ( 'class' , 'node-label' )
264- . attr ( 'pointer-events' , 'none' )
265- . attr ( 'transform' , 'translate(10,-5)' ) ;
266- label . append ( 'text' )
267- . style ( 'font-size' , '0.8em' )
268- . attr ( 'text-anchor' , 'start' ) ;
269- label . append ( 'rect' )
270- . attr ( 'rx' , 1 )
271- . attr ( 'ry' , 1 )
272- . attr ( 'fill' , '#fafaea' )
273- . attr ( 'stroke' , '#cacabc' ) ;
274-
275- nodeGroup = nodeGroup . merge ( nodeEnter ) ;
276- nodeGroup
277- . classed ( 'node-word' , d => d . role === 'word' )
278- . on ( 'mouseover' , ( d ) => {
279- function mouseoverWord ( word ) {
280- // TODO: link back to word in "drawing" svg
281-
282- }
283- if ( d . role === "word" ) { mouseoverWord ( d . data ) ; }
284- console . log ( 'moused over' , d )
285- } )
286- . on ( 'mouseout' , ( d ) => {
287- function mouseoutWord ( word ) {
288-
289- }
290- } )
291- . call ( drag ) ;
292-
293- // draw circle
294- var node = nodeGroup . selectAll ( '.node' )
295- . data ( d => [ d ] )
296- . attr ( 'r' , ( d ) => d . role === 'word' ? 7 : 4 )
297- . attr ( 'stroke' , 'rgba(0,0,0,0.2)' )
298- . attr ( 'fill' , ( d ) => {
299- if ( d . role !== 'word' ) {
300- return 'transparent' ;
301- }
302- else {
303- return colors ( ( d . depth + 2 ) / 10 ) ;
304- }
305- } ) ;
306-
307- // draw text label
308- label = nodeGroup . selectAll ( '.node-label' )
309- . raise ( )
310- . data ( d => [ d ] ) ;
311-
312- label . select ( 'text' )
313- . text ( d => d . role === "word" ? d . data . val : '' )
314- . attr ( 'x' , 5 ) ;
315- label . select ( 'rect' )
316- . style ( 'display' , d => d . role === "word" ? "block" : "none" )
317- . attr ( 'width' , function ( ) {
318- return this . parentNode . getElementsByTagName ( 'text' ) [ 0 ] . getBBox ( ) . width + 10 ;
319- } )
320- . attr ( 'height' , '1.5em' )
321- . attr ( 'y' , '-1em' )
322- . lower ( ) ;
323-
324- this . nodes . selectAll ( '.node-word' ) . raise ( ) ;
163+ // var nodeGroup = this.nodes.selectAll('.node-group')
164+ // .data(this.data.anchors);
325165 }
326166
327167 drawLinks ( ) {
@@ -354,38 +194,9 @@ class GraphLayout {
354194
355195 function tick ( ) {
356196 node
357- . datum ( d => {
358- if ( d . role === "link-anchor" ) {
359- // get position of link-anchor on line
360- var target = d . link . target ,
361- source = d . link . source ;
362-
363- var dx = target . x - source . x ,
364- dy = target . y - source . y ,
365- dr = Math . sqrt ( dx * dx + dy * dy ) ;
366-
367- if ( dr === 0 ) {
368- d . fx = target . x ,
369- d . fy = target . y ;
370- return d ;
371- }
372-
373- var sin60 = Math . sqrt ( 3 ) / 2 ;
374- var cx = source . x + dx * 0.5 - dy * sin60 ,
375- cy = source . y + dy * 0.5 + dx * sin60 ;
376-
377- var acos = Math . acos ( ( source . x - cx ) / dr ) ,
378- asin = Math . asin ( ( source . y - cy ) / dr ) ;
379-
380- var theta = ( asin < 0 ) ? - acos : acos ;
381-
382- d . fx = cx + dr * Math . cos ( theta + Math . PI / 3 * d . t ) ,
383- d . fy = cy + dr * Math . sin ( theta + Math . PI / 3 * d . t ) ;
384- }
385- else {
386- d . x = clampX ( d . x ) ;
387- d . y = clampY ( d . y ) ;
388- }
197+ . datum ( d => {
198+ d . x = clampX ( d . x ) ;
199+ d . y = clampY ( d . y ) ;
389200 return d ;
390201 } )
391202 . attr ( "transform" , ( d ) => {
@@ -395,7 +206,6 @@ class GraphLayout {
395206 link
396207 . attr ( 'd' , arrowPath ) ;
397208
398-
399209 function arrowPath ( d , i ) {
400210 var target = d . target ,
401211 source = d . source ;
@@ -404,10 +214,6 @@ class GraphLayout {
404214 dy = target . y - source . y ,
405215 dr = Math . sqrt ( dx * dx + dy * dy ) ;
406216
407- // if (target.role === "link-anchor" || source.role === "link-anchor") {
408- // dr /= 2;
409- // }
410-
411217 return "M" + source . x + "," + source . y +
412218 "A" + dr + "," + dr + " 0 0,1 " +
413219 target . x + "," + target . y ;
@@ -418,8 +224,6 @@ class GraphLayout {
418224 . nodes ( this . data . anchors )
419225 . on ( 'tick' , tick ) ;
420226
421- // this.simulation.force('link').links(this.data.links);
422-
423227 if ( this . simulation . alpha ( ) < 0.1 ) {
424228 this . simulation . alpha ( 0.3 ) . restart ( ) ;
425229 }
0 commit comments