Show More
This diff has been collapsed as it changes many lines, (579 lines changed) Show them Hide them | |||||
@@ -11,114 +11,35 b'' | |||||
11 | "cell_type": "code", |
|
11 | "cell_type": "code", | |
12 | "collapsed": false, |
|
12 | "collapsed": false, | |
13 | "input": [ |
|
13 | "input": [ | |
14 | "from __future__ import print_function # py 2.7 compat" |
|
14 | "from __future__ import print_function # py 2.7 compat\n", | |
15 | ], |
|
|||
16 | "language": "python", |
|
|||
17 | "metadata": {}, |
|
|||
18 | "outputs": [], |
|
|||
19 | "prompt_number": 1 |
|
|||
20 | }, |
|
|||
21 | { |
|
|||
22 | "cell_type": "heading", |
|
|||
23 | "level": 1, |
|
|||
24 | "metadata": {}, |
|
|||
25 | "source": [ |
|
|||
26 | "Validate NetworkX version" |
|
|||
27 | ] |
|
|||
28 | }, |
|
|||
29 | { |
|
|||
30 | "cell_type": "code", |
|
|||
31 | "collapsed": false, |
|
|||
32 | "input": [ |
|
|||
33 | "import networkx as nx\n", |
|
|||
34 | "version = float('.'.join(nx.__version__.split('.')[0:2]))\n", |
|
|||
35 | "if version < 1.8:\n", |
|
|||
36 | " raise Exception('This notebook requires networkx version 1.8 or later. Version %s is installed on this machine.' % nx.__version__)" |
|
|||
37 | ], |
|
|||
38 | "language": "python", |
|
|||
39 | "metadata": {}, |
|
|||
40 | "outputs": [], |
|
|||
41 | "prompt_number": 2 |
|
|||
42 | }, |
|
|||
43 | { |
|
|||
44 | "cell_type": "heading", |
|
|||
45 | "level": 1, |
|
|||
46 | "metadata": {}, |
|
|||
47 | "source": [ |
|
|||
48 | "Simple Output Test" |
|
|||
49 | ] |
|
|||
50 | }, |
|
|||
51 | { |
|
|||
52 | "cell_type": "code", |
|
|||
53 | "collapsed": false, |
|
|||
54 | "input": [ |
|
|||
55 | "from networkx.readwrite import json_graph\n", |
|
|||
56 | "import json\n", |
|
|||
57 | "\n", |
|
15 | "\n", | |
58 | "def to_d3_json(graph):\n", |
|
16 | "import networkx as nx" | |
59 | " data = json_graph.node_link_data(graph)\n", |
|
|||
60 | " return json.dumps(data)" |
|
|||
61 | ], |
|
17 | ], | |
62 | "language": "python", |
|
18 | "language": "python", | |
63 | "metadata": {}, |
|
19 | "metadata": {}, | |
64 | "outputs": [], |
|
20 | "outputs": [], | |
65 | "prompt_number": 3 |
|
|||
66 | }, |
|
|||
67 | { |
|
|||
68 | "cell_type": "code", |
|
|||
69 | "collapsed": false, |
|
|||
70 | "input": [ |
|
|||
71 | "G = nx.Graph([(1,2)])\n", |
|
|||
72 | "to_d3_json(G)" |
|
|||
73 | ], |
|
|||
74 | "language": "python", |
|
|||
75 | "metadata": {}, |
|
|||
76 | "outputs": [ |
|
|||
77 | { |
|
|||
78 | "metadata": {}, |
|
|||
79 | "output_type": "pyout", |
|
|||
80 | "prompt_number": 4, |
|
|||
81 | "text": [ |
|
|||
82 | "'{\"multigraph\": false, \"directed\": false, \"links\": [{\"target\": 1, \"source\": 0}], \"graph\": [], \"nodes\": [{\"id\": 1}, {\"id\": 2}]}'" |
|
|||
83 | ] |
|
|||
84 | } |
|
|||
85 | ], |
|
|||
86 | "prompt_number": 4 |
|
21 | "prompt_number": 4 | |
87 | }, |
|
22 | }, | |
88 | { |
|
23 | { | |
89 |
"cell_type": " |
|
24 | "cell_type": "markdown", | |
90 | "collapsed": false, |
|
|||
91 | "input": [ |
|
|||
92 | "G.add_node('test')\n", |
|
|||
93 | "to_d3_json(G)" |
|
|||
94 | ], |
|
|||
95 | "language": "python", |
|
|||
96 | "metadata": {}, |
|
25 | "metadata": {}, | |
97 |
" |
|
26 | "source": [ | |
98 | { |
|
27 | "This notebook demonstrates how NetworkX and D3 can be married using custom widget code." | |
99 | "metadata": {}, |
|
28 | ] | |
100 | "output_type": "pyout", |
|
|||
101 | "prompt_number": 5, |
|
|||
102 | "text": [ |
|
|||
103 | "'{\"multigraph\": false, \"directed\": false, \"links\": [{\"target\": 1, \"source\": 0}], \"graph\": [], \"nodes\": [{\"id\": 1}, {\"id\": 2}, {\"id\": \"test\"}]}'" |
|
|||
104 | ] |
|
|||
105 | } |
|
|||
106 | ], |
|
|||
107 | "prompt_number": 5 |
|
|||
108 | }, |
|
29 | }, | |
109 | { |
|
30 | { | |
110 | "cell_type": "heading", |
|
31 | "cell_type": "heading", | |
111 | "level": 1, |
|
32 | "level": 1, | |
112 | "metadata": {}, |
|
33 | "metadata": {}, | |
113 | "source": [ |
|
34 | "source": [ | |
114 | "Listen To Graph Changes" |
|
35 | "Hooking NetworkX Graphs" | |
115 | ] |
|
36 | ] | |
116 | }, |
|
37 | }, | |
117 | { |
|
38 | { | |
118 | "cell_type": "markdown", |
|
39 | "cell_type": "markdown", | |
119 | "metadata": {}, |
|
40 | "metadata": {}, | |
120 | "source": [ |
|
41 | "source": [ | |
121 | "Create a simple eventfull dictionary." |
|
42 | "NetworkX graphs do not have events that can be listened to. In order to watch the NetworkX graph object for changes a custom eventful graph object must be created. The custom eventful graph object will inherit from the base graph object and use special eventful dictionaries instead of standard Python dict instances. Because NetworkX nests dictionaries inside dictionaries, it's important that the eventful dictionary is capable of recognizing when a dictionary value is set to another dictionary instance. When this happens, the eventful dictionary needs to also make the new dictionary an eventful dictionary. This allows the eventful dictionary to listen to changes made to dictionaries within dictionaries." | |
122 | ] |
|
43 | ] | |
123 | }, |
|
44 | }, | |
124 | { |
|
45 | { | |
@@ -212,255 +133,12 b'' | |||||
212 | " \n", |
|
133 | " \n", | |
213 | " def clear(self):\n", |
|
134 | " def clear(self):\n", | |
214 | " for key in list(self.keys()):\n", |
|
135 | " for key in list(self.keys()):\n", | |
215 |
" del self[key] |
|
136 | " del self[key]" | |
216 | ], |
|
137 | ], | |
217 | "language": "python", |
|
138 | "language": "python", | |
218 | "metadata": {}, |
|
139 | "metadata": {}, | |
219 | "outputs": [], |
|
140 | "outputs": [], | |
220 |
"prompt_number": |
|
141 | "prompt_number": 5 | |
221 | }, |
|
|||
222 | { |
|
|||
223 | "cell_type": "markdown", |
|
|||
224 | "metadata": {}, |
|
|||
225 | "source": [ |
|
|||
226 | "Test the eventful dictionary." |
|
|||
227 | ] |
|
|||
228 | }, |
|
|||
229 | { |
|
|||
230 | "cell_type": "code", |
|
|||
231 | "collapsed": false, |
|
|||
232 | "input": [ |
|
|||
233 | "a = EventfulDict()" |
|
|||
234 | ], |
|
|||
235 | "language": "python", |
|
|||
236 | "metadata": {}, |
|
|||
237 | "outputs": [], |
|
|||
238 | "prompt_number": 7 |
|
|||
239 | }, |
|
|||
240 | { |
|
|||
241 | "cell_type": "code", |
|
|||
242 | "collapsed": false, |
|
|||
243 | "input": [ |
|
|||
244 | "def echo_dict_events(eventful_dict, prefix=''):\n", |
|
|||
245 | " def key_add(key, value):\n", |
|
|||
246 | " print(prefix + 'add (%s, %s)' % (key, str(value)))\n", |
|
|||
247 | " def key_set(key, value):\n", |
|
|||
248 | " print(prefix + 'set (%s, %s)' % (key, str(value)))\n", |
|
|||
249 | " def key_del(key):\n", |
|
|||
250 | " print(prefix + 'del %s' % key)\n", |
|
|||
251 | " eventful_dict.on_add(key_add)\n", |
|
|||
252 | " eventful_dict.on_set(key_set)\n", |
|
|||
253 | " eventful_dict.on_del(key_del)\n", |
|
|||
254 | " \n", |
|
|||
255 | "echo_dict_events(a)" |
|
|||
256 | ], |
|
|||
257 | "language": "python", |
|
|||
258 | "metadata": {}, |
|
|||
259 | "outputs": [], |
|
|||
260 | "prompt_number": 8 |
|
|||
261 | }, |
|
|||
262 | { |
|
|||
263 | "cell_type": "code", |
|
|||
264 | "collapsed": false, |
|
|||
265 | "input": [ |
|
|||
266 | "a['a'] = 'hello'" |
|
|||
267 | ], |
|
|||
268 | "language": "python", |
|
|||
269 | "metadata": {}, |
|
|||
270 | "outputs": [ |
|
|||
271 | { |
|
|||
272 | "output_type": "stream", |
|
|||
273 | "stream": "stdout", |
|
|||
274 | "text": [ |
|
|||
275 | "add (a, hello)\n" |
|
|||
276 | ] |
|
|||
277 | } |
|
|||
278 | ], |
|
|||
279 | "prompt_number": 9 |
|
|||
280 | }, |
|
|||
281 | { |
|
|||
282 | "cell_type": "code", |
|
|||
283 | "collapsed": false, |
|
|||
284 | "input": [ |
|
|||
285 | "a['a'] = 'goodbye'" |
|
|||
286 | ], |
|
|||
287 | "language": "python", |
|
|||
288 | "metadata": {}, |
|
|||
289 | "outputs": [ |
|
|||
290 | { |
|
|||
291 | "output_type": "stream", |
|
|||
292 | "stream": "stdout", |
|
|||
293 | "text": [ |
|
|||
294 | "set (a, goodbye)\n" |
|
|||
295 | ] |
|
|||
296 | } |
|
|||
297 | ], |
|
|||
298 | "prompt_number": 10 |
|
|||
299 | }, |
|
|||
300 | { |
|
|||
301 | "cell_type": "code", |
|
|||
302 | "collapsed": false, |
|
|||
303 | "input": [ |
|
|||
304 | "b = {'c': 'yay', 'd': 'no'}\n", |
|
|||
305 | "a.update(b)" |
|
|||
306 | ], |
|
|||
307 | "language": "python", |
|
|||
308 | "metadata": {}, |
|
|||
309 | "outputs": [ |
|
|||
310 | { |
|
|||
311 | "output_type": "stream", |
|
|||
312 | "stream": "stdout", |
|
|||
313 | "text": [ |
|
|||
314 | "add (c, yay)\n", |
|
|||
315 | "add (d, no)\n" |
|
|||
316 | ] |
|
|||
317 | } |
|
|||
318 | ], |
|
|||
319 | "prompt_number": 11 |
|
|||
320 | }, |
|
|||
321 | { |
|
|||
322 | "cell_type": "code", |
|
|||
323 | "collapsed": false, |
|
|||
324 | "input": [ |
|
|||
325 | "a" |
|
|||
326 | ], |
|
|||
327 | "language": "python", |
|
|||
328 | "metadata": {}, |
|
|||
329 | "outputs": [ |
|
|||
330 | { |
|
|||
331 | "metadata": {}, |
|
|||
332 | "output_type": "pyout", |
|
|||
333 | "prompt_number": 12, |
|
|||
334 | "text": [ |
|
|||
335 | "{'a': 'goodbye', 'c': 'yay', 'd': 'no'}" |
|
|||
336 | ] |
|
|||
337 | } |
|
|||
338 | ], |
|
|||
339 | "prompt_number": 12 |
|
|||
340 | }, |
|
|||
341 | { |
|
|||
342 | "cell_type": "code", |
|
|||
343 | "collapsed": false, |
|
|||
344 | "input": [ |
|
|||
345 | "a.pop('a')" |
|
|||
346 | ], |
|
|||
347 | "language": "python", |
|
|||
348 | "metadata": {}, |
|
|||
349 | "outputs": [ |
|
|||
350 | { |
|
|||
351 | "metadata": {}, |
|
|||
352 | "output_type": "pyout", |
|
|||
353 | "prompt_number": 13, |
|
|||
354 | "text": [ |
|
|||
355 | "'goodbye'" |
|
|||
356 | ] |
|
|||
357 | } |
|
|||
358 | ], |
|
|||
359 | "prompt_number": 13 |
|
|||
360 | }, |
|
|||
361 | { |
|
|||
362 | "cell_type": "code", |
|
|||
363 | "collapsed": false, |
|
|||
364 | "input": [ |
|
|||
365 | "a.popitem()" |
|
|||
366 | ], |
|
|||
367 | "language": "python", |
|
|||
368 | "metadata": {}, |
|
|||
369 | "outputs": [ |
|
|||
370 | { |
|
|||
371 | "output_type": "stream", |
|
|||
372 | "stream": "stdout", |
|
|||
373 | "text": [ |
|
|||
374 | "del c\n" |
|
|||
375 | ] |
|
|||
376 | }, |
|
|||
377 | { |
|
|||
378 | "metadata": {}, |
|
|||
379 | "output_type": "pyout", |
|
|||
380 | "prompt_number": 14, |
|
|||
381 | "text": [ |
|
|||
382 | "('c', 'yay')" |
|
|||
383 | ] |
|
|||
384 | } |
|
|||
385 | ], |
|
|||
386 | "prompt_number": 14 |
|
|||
387 | }, |
|
|||
388 | { |
|
|||
389 | "cell_type": "code", |
|
|||
390 | "collapsed": false, |
|
|||
391 | "input": [ |
|
|||
392 | "a['e'] = {}" |
|
|||
393 | ], |
|
|||
394 | "language": "python", |
|
|||
395 | "metadata": {}, |
|
|||
396 | "outputs": [ |
|
|||
397 | { |
|
|||
398 | "output_type": "stream", |
|
|||
399 | "stream": "stdout", |
|
|||
400 | "text": [ |
|
|||
401 | "add (e, {})\n" |
|
|||
402 | ] |
|
|||
403 | } |
|
|||
404 | ], |
|
|||
405 | "prompt_number": 15 |
|
|||
406 | }, |
|
|||
407 | { |
|
|||
408 | "cell_type": "code", |
|
|||
409 | "collapsed": false, |
|
|||
410 | "input": [ |
|
|||
411 | "a['e']['a'] = 0" |
|
|||
412 | ], |
|
|||
413 | "language": "python", |
|
|||
414 | "metadata": {}, |
|
|||
415 | "outputs": [ |
|
|||
416 | { |
|
|||
417 | "output_type": "stream", |
|
|||
418 | "stream": "stdout", |
|
|||
419 | "text": [ |
|
|||
420 | "set (e, {'a': 0})\n" |
|
|||
421 | ] |
|
|||
422 | } |
|
|||
423 | ], |
|
|||
424 | "prompt_number": 16 |
|
|||
425 | }, |
|
|||
426 | { |
|
|||
427 | "cell_type": "code", |
|
|||
428 | "collapsed": false, |
|
|||
429 | "input": [ |
|
|||
430 | "a['e']['b'] = 1" |
|
|||
431 | ], |
|
|||
432 | "language": "python", |
|
|||
433 | "metadata": {}, |
|
|||
434 | "outputs": [ |
|
|||
435 | { |
|
|||
436 | "output_type": "stream", |
|
|||
437 | "stream": "stdout", |
|
|||
438 | "text": [ |
|
|||
439 | "set (e, {'a': 0, 'b': 1})\n" |
|
|||
440 | ] |
|
|||
441 | } |
|
|||
442 | ], |
|
|||
443 | "prompt_number": 17 |
|
|||
444 | }, |
|
|||
445 | { |
|
|||
446 | "cell_type": "code", |
|
|||
447 | "collapsed": false, |
|
|||
448 | "input": [ |
|
|||
449 | "a.clear()" |
|
|||
450 | ], |
|
|||
451 | "language": "python", |
|
|||
452 | "metadata": {}, |
|
|||
453 | "outputs": [ |
|
|||
454 | { |
|
|||
455 | "output_type": "stream", |
|
|||
456 | "stream": "stdout", |
|
|||
457 | "text": [ |
|
|||
458 | "del e\n", |
|
|||
459 | "del d\n" |
|
|||
460 | ] |
|
|||
461 | } |
|
|||
462 | ], |
|
|||
463 | "prompt_number": 18 |
|
|||
464 | }, |
|
142 | }, | |
465 | { |
|
143 | { | |
466 | "cell_type": "markdown", |
|
144 | "cell_type": "markdown", | |
@@ -487,12 +165,30 b'' | |||||
487 | "language": "python", |
|
165 | "language": "python", | |
488 | "metadata": {}, |
|
166 | "metadata": {}, | |
489 | "outputs": [], |
|
167 | "outputs": [], | |
490 |
"prompt_number": |
|
168 | "prompt_number": 6 | |
|
169 | }, | |||
|
170 | { | |||
|
171 | "cell_type": "markdown", | |||
|
172 | "metadata": {}, | |||
|
173 | "source": [ | |||
|
174 | "To make sure that the eventful graph works, create a new graph and log the dictionary events raised." | |||
|
175 | ] | |||
491 | }, |
|
176 | }, | |
492 | { |
|
177 | { | |
493 | "cell_type": "code", |
|
178 | "cell_type": "code", | |
494 | "collapsed": false, |
|
179 | "collapsed": false, | |
495 | "input": [ |
|
180 | "input": [ | |
|
181 | "def echo_dict_events(eventful_dict, prefix=''):\n", | |||
|
182 | " def key_add(key, value):\n", | |||
|
183 | " print(prefix + 'add (%s, %s)' % (key, str(value)))\n", | |||
|
184 | " def key_set(key, value):\n", | |||
|
185 | " print(prefix + 'set (%s, %s)' % (key, str(value)))\n", | |||
|
186 | " def key_del(key):\n", | |||
|
187 | " print(prefix + 'del %s' % key)\n", | |||
|
188 | " eventful_dict.on_add(key_add)\n", | |||
|
189 | " eventful_dict.on_set(key_set)\n", | |||
|
190 | " eventful_dict.on_del(key_del)\n", | |||
|
191 | " \n", | |||
496 | "def echo_graph_events(eventful_graph):\n", |
|
192 | "def echo_graph_events(eventful_graph):\n", | |
497 | " for key in ['graph', 'node', 'adj']:\n", |
|
193 | " for key in ['graph', 'node', 'adj']:\n", | |
498 | " echo_dict_events(getattr(eventful_graph, key), prefix=key+' ')" |
|
194 | " echo_dict_events(getattr(eventful_graph, key), prefix=key+' ')" | |
@@ -500,48 +196,18 b'' | |||||
500 | "language": "python", |
|
196 | "language": "python", | |
501 | "metadata": {}, |
|
197 | "metadata": {}, | |
502 | "outputs": [], |
|
198 | "outputs": [], | |
503 |
"prompt_number": |
|
199 | "prompt_number": 7 | |
504 | }, |
|
200 | }, | |
505 | { |
|
201 | { | |
506 | "cell_type": "code", |
|
202 | "cell_type": "code", | |
507 | "collapsed": false, |
|
203 | "collapsed": false, | |
508 | "input": [ |
|
204 | "input": [ | |
509 | "G = EventfulGraph()\n", |
|
205 | "G = EventfulGraph()\n", | |
510 | "echo_graph_events(G)" |
|
206 | "echo_graph_events(G)\n", | |
511 |
|
|
207 | "\n", | |
512 | "language": "python", |
|
|||
513 | "metadata": {}, |
|
|||
514 | "outputs": [], |
|
|||
515 | "prompt_number": 21 |
|
|||
516 | }, |
|
|||
517 | { |
|
|||
518 | "cell_type": "code", |
|
|||
519 | "collapsed": false, |
|
|||
520 | "input": [ |
|
|||
521 | "to_d3_json(G)" |
|
|||
522 | ], |
|
|||
523 | "language": "python", |
|
|||
524 | "metadata": {}, |
|
|||
525 | "outputs": [ |
|
|||
526 | { |
|
|||
527 | "metadata": {}, |
|
|||
528 | "output_type": "pyout", |
|
|||
529 | "prompt_number": 22, |
|
|||
530 | "text": [ |
|
|||
531 | "'{\"multigraph\": false, \"directed\": false, \"links\": [], \"graph\": [], \"nodes\": []}'" |
|
|||
532 | ] |
|
|||
533 | } |
|
|||
534 | ], |
|
|||
535 | "prompt_number": 22 |
|
|||
536 | }, |
|
|||
537 | { |
|
|||
538 | "cell_type": "code", |
|
|||
539 | "collapsed": false, |
|
|||
540 | "input": [ |
|
|||
541 | "G.add_node('hello')\n", |
|
208 | "G.add_node('hello')\n", | |
542 | "G.add_node('goodbye')\n", |
|
209 | "G.add_node('goodbye')\n", | |
543 |
"G.add_edges_from([(1,2),(1,3)]) |
|
210 | "G.add_edges_from([(1,2),(1,3)])" | |
544 | "to_d3_json(G)" |
|
|||
545 | ], |
|
211 | ], | |
546 | "language": "python", |
|
212 | "language": "python", | |
547 | "metadata": {}, |
|
213 | "metadata": {}, | |
@@ -565,17 +231,9 b'' | |||||
565 | "adj set (1, {2: {}, 3: {}})\n", |
|
231 | "adj set (1, {2: {}, 3: {}})\n", | |
566 | "adj set (3, {1: {}})\n" |
|
232 | "adj set (3, {1: {}})\n" | |
567 | ] |
|
233 | ] | |
568 | }, |
|
|||
569 | { |
|
|||
570 | "metadata": {}, |
|
|||
571 | "output_type": "pyout", |
|
|||
572 | "prompt_number": 23, |
|
|||
573 | "text": [ |
|
|||
574 | "'{\"multigraph\": false, \"directed\": false, \"links\": [{\"target\": 1, \"source\": 0}, {\"target\": 3, \"source\": 1}], \"graph\": [], \"nodes\": [{\"id\": 3}, {\"id\": 1}, {\"id\": \"goodbye\"}, {\"id\": 2}, {\"id\": \"hello\"}]}'" |
|
|||
575 | ] |
|
|||
576 | } |
|
234 | } | |
577 | ], |
|
235 | ], | |
578 |
"prompt_number": |
|
236 | "prompt_number": 8 | |
579 | }, |
|
237 | }, | |
580 | { |
|
238 | { | |
581 | "cell_type": "code", |
|
239 | "cell_type": "code", | |
@@ -589,13 +247,13 b'' | |||||
589 | { |
|
247 | { | |
590 | "metadata": {}, |
|
248 | "metadata": {}, | |
591 | "output_type": "pyout", |
|
249 | "output_type": "pyout", | |
592 |
"prompt_number": |
|
250 | "prompt_number": 9, | |
593 | "text": [ |
|
251 | "text": [ | |
594 |
"{3: {1: {}}, 1: {2: {}, 3: {}}, ' |
|
252 | "{3: {1: {}}, 1: {2: {}, 3: {}}, 'hello': {}, 2: {1: {}}, 'goodbye': {}}" | |
595 | ] |
|
253 | ] | |
596 | } |
|
254 | } | |
597 | ], |
|
255 | ], | |
598 |
"prompt_number": |
|
256 | "prompt_number": 9 | |
599 | }, |
|
257 | }, | |
600 | { |
|
258 | { | |
601 | "cell_type": "code", |
|
259 | "cell_type": "code", | |
@@ -609,70 +267,33 b'' | |||||
609 | { |
|
267 | { | |
610 | "metadata": {}, |
|
268 | "metadata": {}, | |
611 | "output_type": "pyout", |
|
269 | "output_type": "pyout", | |
612 |
"prompt_number": |
|
270 | "prompt_number": 10, | |
613 | "text": [ |
|
271 | "text": [ | |
614 |
"{3: {}, 1: {}, ' |
|
272 | "{3: {}, 1: {}, 'hello': {}, 2: {}, 'goodbye': {}}" | |
615 | ] |
|
273 | ] | |
616 | } |
|
274 | } | |
617 | ], |
|
275 | ], | |
618 |
"prompt_number": |
|
276 | "prompt_number": 10 | |
619 | }, |
|
277 | }, | |
620 | { |
|
278 | { | |
621 | "cell_type": "heading", |
|
279 | "cell_type": "heading", | |
622 | "level": 1, |
|
280 | "level": 1, | |
623 | "metadata": {}, |
|
281 | "metadata": {}, | |
624 | "source": [ |
|
282 | "source": [ | |
625 |
" |
|
283 | "D3 Widget" | |
626 | ] |
|
284 | ] | |
627 | }, |
|
285 | }, | |
628 | { |
|
286 | { | |
629 | "cell_type": "code", |
|
287 | "cell_type": "code", | |
630 | "collapsed": false, |
|
288 | "collapsed": false, | |
631 | "input": [ |
|
289 | "input": [ | |
632 | "%%html\n", |
|
|||
633 | "<div id=\"d3loadindicator\" style=\"background: red; color: white;\"><center>Loading D3...<center></div>\n", |
|
|||
634 | "<script>\n", |
|
|||
635 | " $.getScript('http://d3js.org/d3.v3.min.js', function(){\n", |
|
|||
636 | " $('#d3loadindicator')\n", |
|
|||
637 | " .css('background', 'green')\n", |
|
|||
638 | " .html('<center>D3 Loaded Successfully</center>');\n", |
|
|||
639 | " });\n", |
|
|||
640 | "</script>" |
|
|||
641 | ], |
|
|||
642 | "language": "python", |
|
|||
643 | "metadata": {}, |
|
|||
644 | "outputs": [ |
|
|||
645 | { |
|
|||
646 | "html": [ |
|
|||
647 | "<div id=\"d3loadindicator\" style=\"background: red; color: white;\"><center>Loading D3...<center></div>\n", |
|
|||
648 | "<script>\n", |
|
|||
649 | " $.getScript('http://d3js.org/d3.v3.min.js', function(){\n", |
|
|||
650 | " $('#d3loadindicator')\n", |
|
|||
651 | " .css('background', 'green')\n", |
|
|||
652 | " .html('<center>D3 Loaded Successfully</center>');\n", |
|
|||
653 | " });\n", |
|
|||
654 | "</script>" |
|
|||
655 | ], |
|
|||
656 | "metadata": {}, |
|
|||
657 | "output_type": "display_data", |
|
|||
658 | "text": [ |
|
|||
659 | "<IPython.core.display.HTML at 0x7fa801877d90>" |
|
|||
660 | ] |
|
|||
661 | } |
|
|||
662 | ], |
|
|||
663 | "prompt_number": 26 |
|
|||
664 | }, |
|
|||
665 | { |
|
|||
666 | "cell_type": "code", |
|
|||
667 | "collapsed": false, |
|
|||
668 | "input": [ |
|
|||
669 | "from IPython.html import widgets # Widget definitions\n", |
|
290 | "from IPython.html import widgets # Widget definitions\n", | |
670 | "from IPython.display import display # Used to display widgets in the notebook" |
|
291 | "from IPython.display import display # Used to display widgets in the notebook" | |
671 | ], |
|
292 | ], | |
672 | "language": "python", |
|
293 | "language": "python", | |
673 | "metadata": {}, |
|
294 | "metadata": {}, | |
674 | "outputs": [], |
|
295 | "outputs": [], | |
675 |
"prompt_number": |
|
296 | "prompt_number": 11 | |
676 | }, |
|
297 | }, | |
677 | { |
|
298 | { | |
678 | "cell_type": "code", |
|
299 | "cell_type": "code", | |
@@ -687,9 +308,6 b'' | |||||
687 | " target_name = Unicode('ForceDirectedGraphModel')\n", |
|
308 | " target_name = Unicode('ForceDirectedGraphModel')\n", | |
688 | " default_view_name = Unicode('D3ForceDirectedGraphView')\n", |
|
309 | " default_view_name = Unicode('D3ForceDirectedGraphView')\n", | |
689 | " \n", |
|
310 | " \n", | |
690 | " _keys = ['initial_json']\n", |
|
|||
691 | " initial_json = Unicode()\n", |
|
|||
692 | " \n", |
|
|||
693 | " def __init__(self, eventful_graph, *pargs, **kwargs):\n", |
|
311 | " def __init__(self, eventful_graph, *pargs, **kwargs):\n", | |
694 | " Widget.__init__(self, *pargs, **kwargs)\n", |
|
312 | " Widget.__init__(self, *pargs, **kwargs)\n", | |
695 | " \n", |
|
313 | " \n", | |
@@ -700,8 +318,15 b'' | |||||
700 | " \n", |
|
318 | " \n", | |
701 | " \n", |
|
319 | " \n", | |
702 | " def _repr_widget_(self, *pargs, **kwargs):\n", |
|
320 | " def _repr_widget_(self, *pargs, **kwargs):\n", | |
703 | " self.initial_json = to_d3_json(self._eventful_graph)\n", |
|
321 | " \n", | |
|
322 | " # Show the widget, then send the current state\n", | |||
704 | " Widget._repr_widget_(self, *pargs, **kwargs)\n", |
|
323 | " Widget._repr_widget_(self, *pargs, **kwargs)\n", | |
|
324 | " for (key, value) in self._eventful_graph.graph.items():\n", | |||
|
325 | " self.send({'dict': 'graph', 'action': 'add', 'key': key, 'value': value})\n", | |||
|
326 | " for (key, value) in self._eventful_graph.node.items():\n", | |||
|
327 | " self.send({'dict': 'node', 'action': 'add', 'key': key, 'value': value})\n", | |||
|
328 | " for (key, value) in self._eventful_graph.adj.items():\n", | |||
|
329 | " self.send({'dict': 'adj', 'action': 'add', 'key': key, 'value': value})\n", | |||
705 | " \n", |
|
330 | " \n", | |
706 | " \n", |
|
331 | " \n", | |
707 | " def _send_dict_changes(self, eventful_dict, dict_name):\n", |
|
332 | " def _send_dict_changes(self, eventful_dict, dict_name):\n", | |
@@ -719,7 +344,7 b'' | |||||
719 | "language": "python", |
|
344 | "language": "python", | |
720 | "metadata": {}, |
|
345 | "metadata": {}, | |
721 | "outputs": [], |
|
346 | "outputs": [], | |
722 |
"prompt_number": 2 |
|
347 | "prompt_number": 20 | |
723 | }, |
|
348 | }, | |
724 | { |
|
349 | { | |
725 | "cell_type": "code", |
|
350 | "cell_type": "code", | |
@@ -727,7 +352,7 b'' | |||||
727 | "input": [ |
|
352 | "input": [ | |
728 | "%%javascript\n", |
|
353 | "%%javascript\n", | |
729 | "\n", |
|
354 | "\n", | |
730 | "require([\"notebook/js/widget\"], function(){\n", |
|
355 | "require([\"http://d3js.org/d3.v3.min.js\", \"notebook/js/widget\"], function(){\n", | |
731 | " \n", |
|
356 | " \n", | |
732 | " // Define the ForceDirectedGraphModel and register it with the widget manager.\n", |
|
357 | " // Define the ForceDirectedGraphModel and register it with the widget manager.\n", | |
733 | " var ForceDirectedGraphModel = IPython.WidgetModel.extend({});\n", |
|
358 | " var ForceDirectedGraphModel = IPython.WidgetModel.extend({});\n", | |
@@ -740,6 +365,7 b'' | |||||
740 | " this.guid = 'd3force' + IPython.utils.uuid();\n", |
|
365 | " this.guid = 'd3force' + IPython.utils.uuid();\n", | |
741 | " this.setElement($('<div />', {id: this.guid}));\n", |
|
366 | " this.setElement($('<div />', {id: this.guid}));\n", | |
742 | " this.model.on_msg($.proxy(this.handle_msg, this));\n", |
|
367 | " this.model.on_msg($.proxy(this.handle_msg, this));\n", | |
|
368 | " this.has_drawn = false;\n", | |||
743 | " },\n", |
|
369 | " },\n", | |
744 | " \n", |
|
370 | " \n", | |
745 | " add_node: function(id){\n", |
|
371 | " add_node: function(id){\n", | |
@@ -860,34 +486,28 b'' | |||||
860 | " },\n", |
|
486 | " },\n", | |
861 | " \n", |
|
487 | " \n", | |
862 | " update: function(){\n", |
|
488 | " update: function(){\n", | |
863 | " var initial_json = this.model.get('initial_json');\n", |
|
489 | " if (! this.has_drawn) {\n", | |
864 |
" |
|
490 | " this.has_drawn = true;\n", | |
865 | " this.initial_json = initial_json;\n", |
|
|||
866 | " \n", |
|
491 | " \n", | |
867 |
" var width = |
|
492 | " var width = 400,\n", | |
868 |
" height = |
|
493 | " height = 300;\n", | |
869 | " \n", |
|
494 | " \n", | |
870 | " this.color = d3.scale.category20();\n", |
|
495 | " this.color = d3.scale.category20();\n", | |
871 | " \n", |
|
496 | " \n", | |
872 | " var graph = JSON.parse(initial_json);\n", |
|
|||
873 | " this.nodes = [];\n", |
|
497 | " this.nodes = [];\n", | |
874 | " $.extend(this.nodes, graph.nodes);\n", |
|
|||
875 | " this.links = [];\n", |
|
498 | " this.links = [];\n", | |
876 | " $.extend(this.links, graph.links);\n", |
|
|||
877 | " \n", |
|
499 | " \n", | |
878 |
" |
|
500 | " this.force = d3.layout.force()\n", | |
879 | " .nodes(this.nodes)\n", |
|
501 | " .nodes(this.nodes)\n", | |
880 | " .links(this.links)\n", |
|
502 | " .links(this.links)\n", | |
881 | " .charge(-120)\n", |
|
503 | " .charge(-120)\n", | |
882 | " .linkDistance(30)\n", |
|
504 | " .linkDistance(30)\n", | |
883 | " .size([width, height])\n", |
|
505 | " .size([width, height])\n", | |
884 | " .on(\"tick\", $.proxy(this.tick, this));\n", |
|
506 | " .on(\"tick\", $.proxy(this.tick, this));\n", | |
885 | " this.force = force;\n", |
|
|||
886 | " \n", |
|
507 | " \n", | |
887 |
" |
|
508 | " this.svg = d3.select(\"#\" + this.guid).append(\"svg\")\n", | |
888 | " .attr(\"width\", width)\n", |
|
509 | " .attr(\"width\", width)\n", | |
889 | " .attr(\"height\", height);\n", |
|
510 | " .attr(\"height\", height);\n", | |
890 | " this.svg = svg;\n", |
|
|||
891 | " \n", |
|
511 | " \n", | |
892 | " var that = this;\n", |
|
512 | " var that = this;\n", | |
893 | " setTimeout(function() {\n", |
|
513 | " setTimeout(function() {\n", | |
@@ -910,7 +530,7 b'' | |||||
910 | { |
|
530 | { | |
911 | "javascript": [ |
|
531 | "javascript": [ | |
912 | "\n", |
|
532 | "\n", | |
913 | "require([\"notebook/js/widget\"], function(){\n", |
|
533 | "require([\"http://d3js.org/d3.v3.min.js\", \"notebook/js/widget\"], function(){\n", | |
914 | " \n", |
|
534 | " \n", | |
915 | " // Define the ForceDirectedGraphModel and register it with the widget manager.\n", |
|
535 | " // Define the ForceDirectedGraphModel and register it with the widget manager.\n", | |
916 | " var ForceDirectedGraphModel = IPython.WidgetModel.extend({});\n", |
|
536 | " var ForceDirectedGraphModel = IPython.WidgetModel.extend({});\n", | |
@@ -923,6 +543,7 b'' | |||||
923 | " this.guid = 'd3force' + IPython.utils.uuid();\n", |
|
543 | " this.guid = 'd3force' + IPython.utils.uuid();\n", | |
924 | " this.setElement($('<div />', {id: this.guid}));\n", |
|
544 | " this.setElement($('<div />', {id: this.guid}));\n", | |
925 | " this.model.on_msg($.proxy(this.handle_msg, this));\n", |
|
545 | " this.model.on_msg($.proxy(this.handle_msg, this));\n", | |
|
546 | " this.has_drawn = false;\n", | |||
926 | " },\n", |
|
547 | " },\n", | |
927 | " \n", |
|
548 | " \n", | |
928 | " add_node: function(id){\n", |
|
549 | " add_node: function(id){\n", | |
@@ -1043,34 +664,28 b'' | |||||
1043 | " },\n", |
|
664 | " },\n", | |
1044 | " \n", |
|
665 | " \n", | |
1045 | " update: function(){\n", |
|
666 | " update: function(){\n", | |
1046 | " var initial_json = this.model.get('initial_json');\n", |
|
667 | " if (! this.has_drawn) {\n", | |
1047 |
" |
|
668 | " this.has_drawn = true;\n", | |
1048 | " this.initial_json = initial_json;\n", |
|
|||
1049 | " \n", |
|
669 | " \n", | |
1050 |
" var width = |
|
670 | " var width = 400,\n", | |
1051 |
" height = |
|
671 | " height = 300;\n", | |
1052 | " \n", |
|
672 | " \n", | |
1053 | " this.color = d3.scale.category20();\n", |
|
673 | " this.color = d3.scale.category20();\n", | |
1054 | " \n", |
|
674 | " \n", | |
1055 | " var graph = JSON.parse(initial_json);\n", |
|
|||
1056 | " this.nodes = [];\n", |
|
675 | " this.nodes = [];\n", | |
1057 | " $.extend(this.nodes, graph.nodes);\n", |
|
|||
1058 | " this.links = [];\n", |
|
676 | " this.links = [];\n", | |
1059 | " $.extend(this.links, graph.links);\n", |
|
|||
1060 | " \n", |
|
677 | " \n", | |
1061 |
" |
|
678 | " this.force = d3.layout.force()\n", | |
1062 | " .nodes(this.nodes)\n", |
|
679 | " .nodes(this.nodes)\n", | |
1063 | " .links(this.links)\n", |
|
680 | " .links(this.links)\n", | |
1064 | " .charge(-120)\n", |
|
681 | " .charge(-120)\n", | |
1065 | " .linkDistance(30)\n", |
|
682 | " .linkDistance(30)\n", | |
1066 | " .size([width, height])\n", |
|
683 | " .size([width, height])\n", | |
1067 | " .on(\"tick\", $.proxy(this.tick, this));\n", |
|
684 | " .on(\"tick\", $.proxy(this.tick, this));\n", | |
1068 | " this.force = force;\n", |
|
|||
1069 | " \n", |
|
685 | " \n", | |
1070 |
" |
|
686 | " this.svg = d3.select(\"#\" + this.guid).append(\"svg\")\n", | |
1071 | " .attr(\"width\", width)\n", |
|
687 | " .attr(\"width\", width)\n", | |
1072 | " .attr(\"height\", height);\n", |
|
688 | " .attr(\"height\", height);\n", | |
1073 | " this.svg = svg;\n", |
|
|||
1074 | " \n", |
|
689 | " \n", | |
1075 | " var that = this;\n", |
|
690 | " var that = this;\n", | |
1076 | " setTimeout(function() {\n", |
|
691 | " setTimeout(function() {\n", | |
@@ -1090,11 +705,19 b'' | |||||
1090 | "metadata": {}, |
|
705 | "metadata": {}, | |
1091 | "output_type": "display_data", |
|
706 | "output_type": "display_data", | |
1092 | "text": [ |
|
707 | "text": [ | |
1093 |
"<IPython.core.display.Javascript at 0x7f |
|
708 | "<IPython.core.display.Javascript at 0x7fdee9b02590>" | |
1094 | ] |
|
709 | ] | |
1095 | } |
|
710 | } | |
1096 | ], |
|
711 | ], | |
1097 |
"prompt_number": 2 |
|
712 | "prompt_number": 28 | |
|
713 | }, | |||
|
714 | { | |||
|
715 | "cell_type": "heading", | |||
|
716 | "level": 1, | |||
|
717 | "metadata": {}, | |||
|
718 | "source": [ | |||
|
719 | "Test" | |||
|
720 | ] | |||
1098 | }, |
|
721 | }, | |
1099 | { |
|
722 | { | |
1100 | "cell_type": "code", |
|
723 | "cell_type": "code", | |
@@ -1103,55 +726,25 b'' | |||||
1103 | "G = EventfulGraph()\n", |
|
726 | "G = EventfulGraph()\n", | |
1104 | "G.add_node('hello')\n", |
|
727 | "G.add_node('hello')\n", | |
1105 | "G.add_node('goodbye')\n", |
|
728 | "G.add_node('goodbye')\n", | |
1106 |
"G.add_edges_from([(1,2),(1,3)]) |
|
729 | "G.add_edges_from([(1,2),(1,3)])" | |
1107 | "to_d3_json(G)" |
|
|||
1108 | ], |
|
730 | ], | |
1109 | "language": "python", |
|
731 | "language": "python", | |
1110 | "metadata": {}, |
|
732 | "metadata": {}, | |
1111 | "outputs": [ |
|
733 | "outputs": [], | |
1112 | { |
|
734 | "prompt_number": 29 | |
1113 | "metadata": {}, |
|
|||
1114 | "output_type": "pyout", |
|
|||
1115 | "prompt_number": 36, |
|
|||
1116 | "text": [ |
|
|||
1117 | "'{\"multigraph\": false, \"directed\": false, \"links\": [{\"target\": 1, \"source\": 0}, {\"target\": 3, \"source\": 1}], \"graph\": [], \"nodes\": [{\"id\": 3}, {\"id\": 1}, {\"id\": \"goodbye\"}, {\"id\": 2}, {\"id\": \"hello\"}]}'" |
|
|||
1118 | ] |
|
|||
1119 | } |
|
|||
1120 | ], |
|
|||
1121 | "prompt_number": 36 |
|
|||
1122 | }, |
|
735 | }, | |
1123 | { |
|
736 | { | |
1124 | "cell_type": "code", |
|
737 | "cell_type": "code", | |
1125 | "collapsed": false, |
|
738 | "collapsed": false, | |
1126 | "input": [ |
|
739 | "input": [ | |
1127 | "floating_container = widgets.ContainerWidget()\n", |
|
740 | "floating_container = widgets.ContainerWidget(default_view_name='ModalView')\n", | |
1128 | "floating_container.set_css({\n", |
|
|||
1129 | " 'position': 'relative',\n", |
|
|||
1130 | " 'left': '0px',\n", |
|
|||
1131 | " 'top': '0px',\n", |
|
|||
1132 | " 'z-index': '999',\n", |
|
|||
1133 | " 'background': '#FFF',\n", |
|
|||
1134 | " 'opacity': '0.8'\n", |
|
|||
1135 | "})\n", |
|
|||
1136 | "\n", |
|
741 | "\n", | |
1137 | "d3 = ForceDirectedGraphWidget(G, parent=floating_container)\n", |
|
742 | "d3 = ForceDirectedGraphWidget(G, parent=floating_container)\n", | |
1138 |
"display(floating_container) |
|
743 | "display(floating_container)" | |
1139 | "\n", |
|
|||
1140 | "detach_button = widgets.ButtonWidget(description=\"Detach\")\n", |
|
|||
1141 | "def handle_detach(sender):\n", |
|
|||
1142 | " if sender.description == \"Detach\":\n", |
|
|||
1143 | " sender.description = \"Attach\"\n", |
|
|||
1144 | " floating_container.set_css('position', 'absolute')\n", |
|
|||
1145 | " else:\n", |
|
|||
1146 | " sender.description = \"Detach\"\n", |
|
|||
1147 | " floating_container.set_css('position', 'relative')\n", |
|
|||
1148 | "detach_button.on_click(handle_detach)\n", |
|
|||
1149 | "display(detach_button)" |
|
|||
1150 | ], |
|
744 | ], | |
1151 | "language": "python", |
|
745 | "language": "python", | |
1152 | "metadata": {}, |
|
746 | "metadata": {}, | |
1153 |
"outputs": [] |
|
747 | "outputs": [] | |
1154 | "prompt_number": 37 |
|
|||
1155 | }, |
|
748 | }, | |
1156 | { |
|
749 | { | |
1157 | "cell_type": "code", |
|
750 | "cell_type": "code", | |
@@ -1163,7 +756,7 b'' | |||||
1163 | "language": "python", |
|
756 | "language": "python", | |
1164 | "metadata": {}, |
|
757 | "metadata": {}, | |
1165 | "outputs": [], |
|
758 | "outputs": [], | |
1166 |
"prompt_number": |
|
759 | "prompt_number": 25 | |
1167 | }, |
|
760 | }, | |
1168 | { |
|
761 | { | |
1169 | "cell_type": "code", |
|
762 | "cell_type": "code", | |
@@ -1174,7 +767,7 b'' | |||||
1174 | "language": "python", |
|
767 | "language": "python", | |
1175 | "metadata": {}, |
|
768 | "metadata": {}, | |
1176 | "outputs": [], |
|
769 | "outputs": [], | |
1177 |
"prompt_number": |
|
770 | "prompt_number": 26 | |
1178 | }, |
|
771 | }, | |
1179 | { |
|
772 | { | |
1180 | "cell_type": "code", |
|
773 | "cell_type": "code", | |
@@ -1186,7 +779,7 b'' | |||||
1186 | "language": "python", |
|
779 | "language": "python", | |
1187 | "metadata": {}, |
|
780 | "metadata": {}, | |
1188 | "outputs": [], |
|
781 | "outputs": [], | |
1189 |
"prompt_number": |
|
782 | "prompt_number": 27 | |
1190 | }, |
|
783 | }, | |
1191 | { |
|
784 | { | |
1192 | "cell_type": "code", |
|
785 | "cell_type": "code", |
General Comments 0
You need to be logged in to leave comments.
Login now