@@ -2,43 +2,27 @@ import { updateSelectedNodes } from "../tabular";
22import { getGraphData } from "../model" ;
33import { updateSelection , setLastSelectedNode } from "../selection" ;
44
5- export function update ( ) {
6-
7- var graph = getGraphData ( ) ;
8-
9- var shiftKey , ctrlKey ,
10- width = window . innerWidth ,
11- height = window . innerHeight ;
12-
13- var zoomer = d3 . zoom ( )
14- . scaleExtent ( [ 1 / 4 , 40 ] )
5+ let shiftKey , ctrlKey ,
6+ width = window . innerWidth ,
7+ height = window . innerHeight ,
8+ foreverUniq = 0 ;
9+
10+ let svg = null ,
11+ brush = null ,
12+ node ,
13+ link ,
14+ links ,
15+ nodes ,
16+ zoomer = d3 . zoom ( )
17+ . scaleExtent ( [ 1 / 4 , 100 ] )
1518 . on ( "zoom" , ( ) => {
1619 view . attr ( "transform" , d3 . event . transform ) ;
17- } ) ;
18-
19- var dragger = d3 . drag ( )
20+ } ) ,
21+ dragger = d3 . drag ( )
2022 . on ( "start" , dragstarted )
2123 . on ( "drag" , dragged )
22- . on ( "end" , dragended ) ;
23-
24- d3 . select ( window )
25- . on ( "keydown" , keyDown )
26- . on ( "keyup" , keyUp ) ;
27-
28- var svg = d3 . select ( "#graph" )
29- . call ( zoomer ) ;
30-
31- var view = svg
32- . append ( "g" )
33- . attr ( "class" , "view" ) ;
34-
35- var brush = view . append ( "g" )
36- . datum ( ( ) => { return { selected : false , previouslySelected : false } ; } )
37- . attr ( "class" , "brush" ) ;
38-
39- // var color = d3.scaleOrdinal(d3.schemeCategory20);
40-
41- var simulation = d3 . forceSimulation ( )
24+ . on ( "end" , dragended ) ,
25+ simulation = d3 . forceSimulation ( )
4226 . force ( "link" ,
4327 d3 . forceLink ( )
4428 . distance ( d => 50 + ( d . source . radius + d . target . radius ) * 2 )
@@ -48,25 +32,125 @@ export function update () {
4832 d3 . forceManyBody ( )
4933 . strength ( d => { return - 10 * d . radius ; } )
5034 )
51- . force ( "center" , d3 . forceCenter ( width / 2 , height / 2 ) ) ;
35+ . force ( "center" , d3 . forceCenter ( width / 2 , height / 2 ) ) ,
36+ brusher = d3 . brush ( )
37+ . extent ( [ [ - 9999999 , - 9999999 ] , [ 9999999 , 9999999 ] ] )
38+ . on ( "start.brush" , ( ) => {
39+ if ( ! d3 . event . sourceEvent ) return ;
40+ node . each ( ( d ) => {
41+ d . previouslySelected = ctrlKey && d . selected ;
42+ } ) ;
43+ } )
44+ . on ( "brush.brush" , ( ) => {
45+ if ( ! d3 . event . sourceEvent ) return ;
46+ let extent = d3 . event . selection ;
47+ if ( ! extent )
48+ return ;
49+ node . classed ( "selected" , ( d ) => {
50+ let selected = ( extent [ 0 ] [ 0 ] <= d . x && d . x < extent [ 1 ] [ 0 ]
51+ && extent [ 0 ] [ 1 ] <= d . y && d . y < extent [ 1 ] [ 1 ] ) ;
52+ if ( selected ) setLastSelectedNode ( d ) ;
53+ return d . selected = d . previouslySelected ^ selected ;
54+ } ) ;
55+ } )
56+ . on ( "end.brush" , ( ) => {
57+ if ( ! d3 . event . sourceEvent ) return ;
58+ setTimeout ( ( ) => {
59+ brush . call ( brusher . move , null ) ;
60+ updateSelection ( ) ;
61+ } , 25 ) ;
62+ } ) ,
63+ view = null ;
64+
65+ function ticked ( ) {
66+ link
67+ . attr ( "x1" , d => d . source . x )
68+ . attr ( "y1" , d => d . source . y )
69+ . attr ( "x2" , d => d . target . x )
70+ . attr ( "y2" , d => d . target . y ) ;
71+ node
72+ . attr ( "transform" , ( d ) => `translate(${ d . x } ,${ d . y } )` )
73+ }
74+
75+ function dragstarted ( d ) {
76+ if ( ! d3 . event . active ) simulation . alphaTarget ( 0.3 ) . restart ( ) ;
77+ d . fx = d . x ;
78+ d . fy = d . y ;
79+ }
80+
81+ function dragged ( d ) {
82+ d . fx = d3 . event . x ;
83+ d . fy = d3 . event . y ;
84+ }
85+
86+ function dragended ( d ) {
87+ if ( ! d3 . event . active ) simulation . alphaTarget ( 0 ) ;
88+ d . fx = null ;
89+ d . fy = null ;
90+ }
91+
92+ function keyDown ( ) {
93+ shiftKey = d3 . event . shiftKey || d3 . event . metaKey ;
94+ ctrlKey = d3 . event . ctrlKey ;
95+
96+ if ( d3 . event . keyCode == 67 ) { // the 'c' key
97+ // do stuff
98+ }
99+
100+ if ( ctrlKey ) {
101+ brush . select ( '.overlay' ) . style ( 'cursor' , 'crosshair' ) ;
102+ brush . call ( brusher ) ;
103+ d3 . event . preventDefault ( ) ;
104+ }
105+ }
106+
107+ function keyUp ( ) {
108+ shiftKey = d3 . event . shiftKey || d3 . event . metaKey ;
109+ ctrlKey = d3 . event . ctrlKey ;
52110
53- var link = view . append ( "g" )
54- . attr ( "class" , "links" )
55- . selectAll ( "line" )
56- . data ( graph . edges )
57- . enter ( ) . append ( "line" )
111+ brush . call ( brusher )
112+ . on ( ".brush" , null ) ;
113+
114+ brush . select ( '.overlay' ) . style ( 'cursor' , 'auto' ) ;
115+ }
116+
117+ export function init ( ) {
118+ svg = d3 . select ( "#graph" )
119+ . call ( zoomer ) ;
120+ view = svg
121+ . append ( "g" )
122+ . attr ( "class" , "view" ) ;
123+ brush = view . append ( "g" )
124+ . datum ( ( ) => { return { selected : false , previouslySelected : false } ; } )
125+ . attr ( "class" , "brush" ) ;
126+ links = view . append ( "g" ) . attr ( "class" , "links" ) ;
127+ nodes = view . append ( "g" ) . attr ( "class" , "nodes" ) ;
128+ link = links . selectAll ( "line" ) ;
129+ node = nodes . selectAll ( ".node" ) ;
130+ d3 . select ( window )
131+ . on ( "keydown" , keyDown )
132+ . on ( "keyup" , keyUp ) ;
133+ }
134+
135+ export function update ( ) {
136+
137+ let graph = getGraphData ( ) ;
138+
139+ link = link
140+ . data ( graph . edges , ( d ) => foreverUniq ++ ) ;
141+ link . exit ( ) . remove ( ) ;
142+ link = link . enter ( ) . append ( "line" )
58143 . attr ( "class" , d => d . type === "similar"
59144 ? "similar"
60145 : d . type === "related"
61146 ? "related"
62147 : "other"
63148 ) ;
64149
65- var node = view . append ( "g" )
66- . attr ( "class" , "nodes" )
67- . selectAll ( ".node" )
68- . data ( graph . nodes )
69- . enter ( ) . append ( "g" )
150+ node = node
151+ . data ( graph . nodes , ( d ) => foreverUniq ++ ) ;
152+ node . exit ( ) . remove ( ) ;
153+ node = node . enter ( ) . append ( "g" )
70154 . attr ( "class" , "node" )
71155 . call ( dragger )
72156 . on ( "dblclick" , ( ) => d3 . event . stopPropagation ( ) )
@@ -80,106 +164,31 @@ export function update () {
80164 updateSelection ( ) ;
81165 } ) ;
82166
83- var circle = node . append ( "circle" )
167+ node . append ( "circle" )
84168 . attr ( "r" , d => d . radius ) ;
85169
86170 node . append ( "text" )
87171 . attr ( "dy" , ".3em" )
88172 . attr ( "style" , d => `font-size:${ Math . round ( d . radius / 2 ) } px` )
89173 . text ( d => d . label ) ;
90174
175+ node . exit ( ) . remove ( ) ;
176+ link . exit ( ) . remove ( ) ;
177+
91178 simulation
92179 . nodes ( graph . nodes )
93180 . on ( "tick" , ticked ) ;
94181
95182 simulation . force ( "link" )
96183 . links ( graph . edges ) ;
97184
98- var brusher = d3 . brush ( )
99- . extent ( [ [ - 9999999 , - 9999999 ] , [ 9999999 , 9999999 ] ] )
100- . on ( "start.brush" , ( ) => {
101- if ( ! d3 . event . sourceEvent ) return ;
102- node . each ( ( d ) => {
103- d . previouslySelected = ctrlKey && d . selected ;
104- } ) ;
105- } )
106- . on ( "brush.brush" , ( ) => {
107- if ( ! d3 . event . sourceEvent ) return ;
108- var extent = d3 . event . selection ;
109- if ( ! extent )
110- return ;
111- node . classed ( "selected" , ( d ) => {
112- let selected = ( extent [ 0 ] [ 0 ] <= d . x && d . x < extent [ 1 ] [ 0 ]
113- && extent [ 0 ] [ 1 ] <= d . y && d . y < extent [ 1 ] [ 1 ] ) ;
114- if ( selected ) setLastSelectedNode ( d ) ;
115- return d . selected = d . previouslySelected ^ selected ;
116- } ) ;
117- } )
118- . on ( "end.brush" , ( ) => {
119- if ( ! d3 . event . sourceEvent ) return ;
120- setTimeout ( ( ) => {
121- brush . call ( brusher . move , null ) ;
122- updateSelection ( ) ;
123- } , 25 ) ;
124- } ) ;
185+ simulation . restart ( ) ;
125186
126187 brush . call ( brusher )
127188 . on ( ".brush" , null ) ;
128189
129190 brush . select ( '.overlay' ) . style ( 'cursor' , 'auto' ) ;
130191
131- for ( var i = 100 ; i > 0 ; -- i ) simulation . tick ( ) ;
132-
133- function ticked ( ) {
134- link
135- . attr ( "x1" , d => d . source . x )
136- . attr ( "y1" , d => d . source . y )
137- . attr ( "x2" , d => d . target . x )
138- . attr ( "y2" , d => d . target . y ) ;
139- node
140- . attr ( "transform" , ( d ) => `translate(${ d . x } ,${ d . y } )` )
141- }
142-
143- function dragstarted ( d ) {
144- if ( ! d3 . event . active ) simulation . alphaTarget ( 0.3 ) . restart ( ) ;
145- d . fx = d . x ;
146- d . fy = d . y ;
147- }
148-
149- function dragged ( d ) {
150- d . fx = d3 . event . x ;
151- d . fy = d3 . event . y ;
152- }
153-
154- function dragended ( d ) {
155- if ( ! d3 . event . active ) simulation . alphaTarget ( 0 ) ;
156- d . fx = null ;
157- d . fy = null ;
158- }
159-
160- function keyDown ( ) {
161- shiftKey = d3 . event . shiftKey || d3 . event . metaKey ;
162- ctrlKey = d3 . event . ctrlKey ;
163-
164- if ( d3 . event . keyCode == 67 ) { // the 'c' key
165- // do stuff
166- }
167-
168- if ( ctrlKey ) {
169- brush . select ( '.overlay' ) . style ( 'cursor' , 'crosshair' ) ;
170- brush . call ( brusher ) ;
171- d3 . event . preventDefault ( ) ;
172- }
173- }
174-
175- function keyUp ( ) {
176- shiftKey = d3 . event . shiftKey || d3 . event . metaKey ;
177- ctrlKey = d3 . event . ctrlKey ;
178-
179- brush . call ( brusher )
180- . on ( ".brush" , null ) ;
181-
182- brush . select ( '.overlay' ) . style ( 'cursor' , 'auto' ) ;
183- }
192+ for ( let i = 100 ; i > 0 ; -- i ) simulation . tick ( ) ;
184193
185194}
0 commit comments