-
-
Save Soupala/36686e84c7d5f3249f73 to your computer and use it in GitHub Desktop.
Revisions
-
nitaku revised this gist
May 28, 2015 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
nitaku revised this gist
May 27, 2015 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
nitaku revised this gist
Nov 18, 2013 . 2 changed files with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -260,7 +260,7 @@ window.main = (() -> .on('mousemove.add_link', ((d) -> ### check if there is a new link in creation ### if global.new_link_source? ### update the draggable link representation ### p = d3.mouse(global.vis.node()) global.drag_link .attr('x1', global.new_link_source.x) # source node can be in movement This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -312,7 +312,7 @@ */ var p; if (global.new_link_source != null) { /* update the draggable link representation */ p = d3.mouse(global.vis.node()); return global.drag_link.attr('x1', global.new_link_source.x).attr('y1', global.new_link_source.y).attr('x2', p[0]).attr('y2', p[1]); -
nitaku revised this gist
Nov 17, 2013 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,4 +8,8 @@ The example activates and deactivates d3.js's drag behavior on nodes by using a Mouse coordinates are used to move the representation of a new link. The coordinates are retrieved as in [this example](http://bl.ocks.org/nitaku/6901037); Please note that the container passed to `d3.mouse` has to be a DOM node, not a d3 selection. To obtain a DOM node from a selection, use the `selection.node()` method ([d3 wiki](https://github.com/mbostock/d3/wiki/Selections#wiki-node)). To make the text labels unselectable, `d3.event.preventDefault()` is used in the `mousedown` handler. For preventing the text to be ever selected at all (for example when dragging from the HTML node library), the CSS property `user-select` has been set to `none` (see [this link](http://stackoverflow.com/questions/69430/is-there-a-way-to-make-text-unselectable-on-an-html-page)). There is no support for adding links with touch gestures. The code is a real mess, and some questionable choices have been made because I ran out of time (like for example inlining the SVG for the tool buttons). -
nitaku revised this gist
Nov 17, 2013 . 2 changed files with 0 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -150,7 +150,6 @@ window.main = (() -> global.drag = global.force.drag().on('dragstart', (d) -> d.fixed = true) ### DELETION - pressing DEL deletes the selection ### d3.select(window) .on('keydown', () -> if d3.event.keyCode is 46 # DEL This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -276,8 +276,6 @@ }); /* DELETION - pressing DEL deletes the selection */ d3.select(window).on('keydown', function() { if (d3.event.keyCode === 46) { if (global.selection != null) { -
nitaku revised this gist
Nov 17, 2013 . 1 changed file with 4 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,4 +8,8 @@ The example activates and deactivates d3.js's drag behavior on nodes by using a Mouse coordinates are used to move the representation of a new link. The coordinates are retrieved as in [this example](http://bl.ocks.org/nitaku/6901037); Please note that the container passed to `d3.mouse` has to be a DOM node, not a d3 selection. To obtain a DOM node from a selection, use the `selection.node()` method ([d3 wiki](https://github.com/mbostock/d3/wiki/Selections#wiki-node)). To make the text labels unselectable, `d3.event.preventDefault()` is used in the `mousedown` handler. For preventing the text to be ever selected at all (for example when dragging from the HTML node library), the CSS property `user-select` has been set to `none` (see [this link](http://stackoverflow.com/questions/69430/is-there-a-way-to-make-text-unselectable-on-an-html-page)). There is no support for adding links with touch gestures. The code is a real mess, and some questionable choices have been made because I ran out of time (like for example inlining the SVG for the tool buttons). -
nitaku revised this gist
Nov 17, 2013 . 2 changed files with 13 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,11 @@ font-family: sans-serif; font-weight: bold; text-anchor: middle; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none; } .link, .drag_link { @@ -55,7 +60,7 @@ .library { border: 2px solid #a3a4c3; border-radius: 6px; background: rgba(255, 255, 255, 0.8); padding: 6px; margin-top: 10px; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -7,6 +7,13 @@ font-weight: bold text-anchor: middle // prevent text selection -webkit-user-select: none -moz-user-select: none -ms-user-select: none -o-user-select: none user-select: none // editing .link, .drag_link stroke-width: 6px -
nitaku revised this gist
Nov 17, 2013 . 1 changed file with 8 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,11 @@ Starting from [the previous example](http://bl.ocks.org/nitaku/7493693), this one implements a more complete graph editing tool. Select a tool to operate on the graph: The *pointer* only lets the user pan & zoom or drag nodes around. The *add node tool* opens up a library of node types; click one to add a node of that type to the graph. The *add link tool* lets the user connect two nodes with a drag gesture from the first to the second one. Clicking a node or a link always selects it regardless of the current tool. You can press `del` to remove the current selection. The example activates and deactivates d3.js's drag behavior on nodes by using a technique found in [this example](http://bl.ocks.org/rkirsling/5001347) by [Ross Kirsling](https://github.com/rkirsling): Everytime the behavior has to be deactivated, the underlying listeners (`mousedown.drag` and `touchstart.drag`) are cleared. Mouse coordinates are used to move the representation of a new link. The coordinates are retrieved as in [this example](http://bl.ocks.org/nitaku/6901037); Please note that the container passed to `d3.mouse` has to be a DOM node, not a d3 selection. To obtain a DOM node from a selection, use the `selection.node()` method ([d3 wiki](https://github.com/mbostock/d3/wiki/Selections#wiki-node)). The code is a real mess, and some questionable choices have been made because I ran out of time (like for example inlining the SVG for the tool buttons). -
nitaku revised this gist
Nov 17, 2013 . 1 changed file with 0 additions and 0 deletions.There are no files selected for viewing
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
nitaku revised this gist
Nov 17, 2013 . 1 changed file with 8 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,11 @@ Starting from [the previous example](http://bl.ocks.org/nitaku/7493693), this one implements a more complete graph editing tool. Select a tool to operate on the graph: The *pointer* only lets the user pan & zoom or drag nodes around. The *add node tool* opens up a library of node types; click one to add a node of that type to the graph. The *add link tool* lets the user connect two nodes with a drag gesture from the first to the second one. Clicking a node or a link always selects it regardless of the current tool. You can press `del` to remove the current selection. The example activates and deactivates d3.js's drag behavior on nodes by using a technique found in [this example](http://bl.ocks.org/rkirsling/5001347) by [Ross Kirsling](https://github.com/rkirsling): Everytime the behavior has to be deactivated, the underlying listeners (`mousedown.drag` and `touchstart.drag`) are cleared. Mouse coordinates are used to move the representation of a new link. The coordinates are retrieved as in [this example](http://bl.ocks.org/nitaku/6901037); Please note that the container passed to `d3.mouse` has to be a DOM node, not a d3 selection. To obtain a DOM node from a selection, use the `selection.node()` method ([d3 wiki](https://github.com/mbostock/d3/wiki/Selections#wiki-node)). The code is a real mess, and some questionable choices have been made because I ran out of time (like for example inlining the SVG for the tool buttons). -
nitaku revised this gist
Nov 17, 2013 . 5 changed files with 114 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -166,9 +166,69 @@ window.main = (() -> toolbar = $("<div class='toolbar'></div>") $('body').append(toolbar) toolbar.append($(""" <svg class='active tool' data-tool='pointer' xmlns='http://www.w3.org/2000/svg' version='1.1' width='32' height='32' viewBox='0 0 128 128'> <g transform='translate(881.10358,-356.22543)'> <g transform='matrix(0.8660254,-0.5,0.5,0.8660254,-266.51112,-215.31898)'> <path d='m -797.14902,212.29589 a 5.6610848,8.6573169 0 0 0 -4.61823,4.3125 l -28.3428,75.0625 a 5.6610848,8.6573169 0 0 0 4.90431,13 l 56.68561,0 a 5.6610848,8.6573169 0 0 0 4.9043,-13 l -28.3428,-75.0625 a 5.6610848,8.6573169 0 0 0 -5.19039,-4.3125 z m 0.28608,25.96875 18.53419,49.09375 -37.06838,0 18.53419,-49.09375 z' /> <path d='m -801.84375,290.40625 c -2.09434,2.1e-4 -3.99979,1.90566 -4,4 l 0,35.25 c 2.1e-4,2.09434 1.90566,3.99979 4,4 l 10,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-35.25 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 z' /> </g> </g> </svg> """)) toolbar.append($(""" <svg class='tool' data-tool='add_node' xmlns='http://www.w3.org/2000/svg' version='1.1' width='32' height='32' viewBox='0 0 128 128'> <g transform='translate(720.71649,-356.22543)'> <g transform='translate(-3.8571429,146.42857)'> <path d='m -658.27638,248.37149 c -1.95543,0.19978 -3.60373,2.03442 -3.59375,4 l 0,12.40625 -12.40625,0 c -2.09434,2.1e-4 -3.99979,1.90566 -4,4 l 0,10 c -0.007,0.1353 -0.007,0.27095 0,0.40625 0.19978,1.95543 2.03442,3.60373 4,3.59375 l 12.40625,0 0,12.4375 c 2.1e-4,2.09434 1.90566,3.99979 4,4 l 10,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-12.4375 12.4375,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-10 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -12.4375,0 0,-12.40625 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -10,0 c -0.1353,-0.007 -0.27095,-0.007 -0.40625,0 z' /> <path d='m -652.84375,213.9375 c -32.97528,0 -59.875,26.86847 -59.875,59.84375 0,32.97528 26.89972,59.875 59.875,59.875 32.97528,0 59.84375,-26.89972 59.84375,-59.875 0,-32.97528 -26.86847,-59.84375 -59.84375,-59.84375 z m 0,14 c 25.40911,0 45.84375,20.43464 45.84375,45.84375 0,25.40911 -20.43464,45.875 -45.84375,45.875 -25.40911,0 -45.875,-20.46589 -45.875,-45.875 0,-25.40911 20.46589,-45.84375 45.875,-45.84375 z' /> </g> </g> </svg> """)) toolbar.append($(""" <svg class='tool' data-tool='add_link' xmlns='http://www.w3.org/2000/svg' version='1.1' width='32' height='32' viewBox='0 0 128 128'> <g transform='translate(557.53125,-356.22543)'> <g transform='translate(20,0)'> <path d='m -480.84375,360 c -15.02602,0 -27.375,12.31773 -27.375,27.34375 0,4.24084 1.00221,8.28018 2.75,11.875 l -28.875,28.875 c -3.59505,-1.74807 -7.6338,-2.75 -11.875,-2.75 -15.02602,0 -27.34375,12.34898 -27.34375,27.375 0,15.02602 12.31773,27.34375 27.34375,27.34375 15.02602,0 27.375,-12.31773 27.375,-27.34375 0,-4.26067 -0.98685,-8.29868 -2.75,-11.90625 L -492.75,411.96875 c 3.60156,1.75589 7.65494,2.75 11.90625,2.75 15.02602,0 27.34375,-12.34898 27.34375,-27.375 C -453.5,372.31773 -465.81773,360 -480.84375,360 z m 0,14 c 7.45986,0 13.34375,5.88389 13.34375,13.34375 0,7.45986 -5.88389,13.375 -13.34375,13.375 -7.45986,0 -13.375,-5.91514 -13.375,-13.375 0,-7.45986 5.91514,-13.34375 13.375,-13.34375 z m -65.375,65.34375 c 7.45986,0 13.34375,5.91514 13.34375,13.375 0,7.45986 -5.88389,13.34375 -13.34375,13.34375 -7.45986,0 -13.34375,-5.88389 -13.34375,-13.34375 0,-7.45986 5.88389,-13.375 13.34375,-13.375 z' /> <path d='m -484.34375,429.25 c -1.95543,0.19978 -3.60373,2.03442 -3.59375,4 l 0,12.40625 -12.40625,0 c -2.09434,2.1e-4 -3.99979,1.90566 -4,4 l 0,10 c -0.007,0.1353 -0.007,0.27095 0,0.40625 0.19978,1.95543 2.03442,3.60373 4,3.59375 l 12.40625,0 0,12.4375 c 2.1e-4,2.09434 1.90566,3.99979 4,4 l 10,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-12.4375 12.4375,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-10 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -12.4375,0 0,-12.40625 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -10,0 c -0.1353,-0.007 -0.27095,-0.007 -0.40625,0 z' /> </g> </g> </svg> """)) library = $("<div class='library'></div></div>") toolbar.append(library) @@ -193,8 +253,8 @@ window.main = (() -> library.append(new_btn) library.hide() global.tool = 'pointer' global.new_link_source = null global.vis @@ -216,8 +276,11 @@ window.main = (() -> global.drag_link.remove() if global.drag_link? )) d3.selectAll('.tool').on 'click', () -> d3.selectAll('.tool').classed('active', false) d3.select(this).classed('active', true) new_tool = $(this).data('tool') nodes = global.vis.selectAll('.node') @@ -247,7 +310,6 @@ window.main = (() -> library.hide() global.tool = new_tool ) update = () -> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -12,7 +12,7 @@ .link, .drag_link { stroke-width: 6px; stroke: gray; opacity: 0.5; } .drag_link { @@ -37,13 +37,30 @@ left: 480px; width: 240px; margin-left: -120px; text-align: center; } .tool:not(:last-child) { margin-right: 10px; } .tool { fill: #a3a4c3; cursor: pointer; } .tool.active { fill: #b52d0c; } .library { border: 2px solid #a3a4c3; border-radius: 6px; background: rgba(255, 255, 255, 0.7); padding: 6px; margin-top: 10px; } .library svg { cursor: pointer; } .library svg:not(:last-child) { padding-right: 6px; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -292,9 +292,9 @@ */ toolbar = $("<div class='toolbar'></div>"); $('body').append(toolbar); toolbar.append($("<svg\n class='active tool'\n data-tool='pointer'\n xmlns='http://www.w3.org/2000/svg'\n version='1.1'\n width='32'\n height='32'\n viewBox='0 0 128 128'>\n <g transform='translate(881.10358,-356.22543)'>\n <g transform='matrix(0.8660254,-0.5,0.5,0.8660254,-266.51112,-215.31898)'>\n <path\n d='m -797.14902,212.29589 a 5.6610848,8.6573169 0 0 0 -4.61823,4.3125 l -28.3428,75.0625 a 5.6610848,8.6573169 0 0 0 4.90431,13 l 56.68561,0 a 5.6610848,8.6573169 0 0 0 4.9043,-13 l -28.3428,-75.0625 a 5.6610848,8.6573169 0 0 0 -5.19039,-4.3125 z m 0.28608,25.96875 18.53419,49.09375 -37.06838,0 18.53419,-49.09375 z'\n />\n <path\n d='m -801.84375,290.40625 c -2.09434,2.1e-4 -3.99979,1.90566 -4,4 l 0,35.25 c 2.1e-4,2.09434 1.90566,3.99979 4,4 l 10,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-35.25 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 z'\n />\n </g>\n </g>\n</svg>")); toolbar.append($("<svg\n class='tool'\n data-tool='add_node'\n xmlns='http://www.w3.org/2000/svg'\n version='1.1'\n width='32'\n height='32'\n viewBox='0 0 128 128'>\n <g transform='translate(720.71649,-356.22543)'>\n <g transform='translate(-3.8571429,146.42857)'>\n <path\n d='m -658.27638,248.37149 c -1.95543,0.19978 -3.60373,2.03442 -3.59375,4 l 0,12.40625 -12.40625,0 c -2.09434,2.1e-4 -3.99979,1.90566 -4,4 l 0,10 c -0.007,0.1353 -0.007,0.27095 0,0.40625 0.19978,1.95543 2.03442,3.60373 4,3.59375 l 12.40625,0 0,12.4375 c 2.1e-4,2.09434 1.90566,3.99979 4,4 l 10,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-12.4375 12.4375,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-10 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -12.4375,0 0,-12.40625 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -10,0 c -0.1353,-0.007 -0.27095,-0.007 -0.40625,0 z'\n />\n <path\n d='m -652.84375,213.9375 c -32.97528,0 -59.875,26.86847 -59.875,59.84375 0,32.97528 26.89972,59.875 59.875,59.875 32.97528,0 59.84375,-26.89972 59.84375,-59.875 0,-32.97528 -26.86847,-59.84375 -59.84375,-59.84375 z m 0,14 c 25.40911,0 45.84375,20.43464 45.84375,45.84375 0,25.40911 -20.43464,45.875 -45.84375,45.875 -25.40911,0 -45.875,-20.46589 -45.875,-45.875 0,-25.40911 20.46589,-45.84375 45.875,-45.84375 z'\n />\n </g>\n </g>\n</svg>")); toolbar.append($("<svg\n class='tool'\n data-tool='add_link'\n xmlns='http://www.w3.org/2000/svg'\n version='1.1'\n width='32'\n height='32'\n viewBox='0 0 128 128'>\n<g transform='translate(557.53125,-356.22543)'>\n <g transform='translate(20,0)'>\n <path\n d='m -480.84375,360 c -15.02602,0 -27.375,12.31773 -27.375,27.34375 0,4.24084 1.00221,8.28018 2.75,11.875 l -28.875,28.875 c -3.59505,-1.74807 -7.6338,-2.75 -11.875,-2.75 -15.02602,0 -27.34375,12.34898 -27.34375,27.375 0,15.02602 12.31773,27.34375 27.34375,27.34375 15.02602,0 27.375,-12.31773 27.375,-27.34375 0,-4.26067 -0.98685,-8.29868 -2.75,-11.90625 L -492.75,411.96875 c 3.60156,1.75589 7.65494,2.75 11.90625,2.75 15.02602,0 27.34375,-12.34898 27.34375,-27.375 C -453.5,372.31773 -465.81773,360 -480.84375,360 z m 0,14 c 7.45986,0 13.34375,5.88389 13.34375,13.34375 0,7.45986 -5.88389,13.375 -13.34375,13.375 -7.45986,0 -13.375,-5.91514 -13.375,-13.375 0,-7.45986 5.91514,-13.34375 13.375,-13.34375 z m -65.375,65.34375 c 7.45986,0 13.34375,5.91514 13.34375,13.375 0,7.45986 -5.88389,13.34375 -13.34375,13.34375 -7.45986,0 -13.34375,-5.88389 -13.34375,-13.34375 0,-7.45986 5.88389,-13.375 13.34375,-13.375 z'\n />\n <path\n d='m -484.34375,429.25 c -1.95543,0.19978 -3.60373,2.03442 -3.59375,4 l 0,12.40625 -12.40625,0 c -2.09434,2.1e-4 -3.99979,1.90566 -4,4 l 0,10 c -0.007,0.1353 -0.007,0.27095 0,0.40625 0.19978,1.95543 2.03442,3.60373 4,3.59375 l 12.40625,0 0,12.4375 c 2.1e-4,2.09434 1.90566,3.99979 4,4 l 10,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-12.4375 12.4375,0 c 2.09434,-2.1e-4 3.99979,-1.90566 4,-4 l 0,-10 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -12.4375,0 0,-12.40625 c -2.1e-4,-2.09434 -1.90566,-3.99979 -4,-4 l -10,0 c -0.1353,-0.007 -0.27095,-0.007 -0.40625,0 z'\n />\n </g>\n </g>\n</svg>")); library = $("<div class='library'></div></div>"); toolbar.append(library); ['X', 'Y', 'Z', 'W'].forEach(function(type) { @@ -307,7 +307,7 @@ library.append(new_btn); return library.hide(); }); global.tool = 'pointer'; global.new_link_source = null; global.vis.on('mousemove.add_link', (function(d) { /* check if there is a new link in creation @@ -325,9 +325,11 @@ */ if (global.drag_link != null) return global.drag_link.remove(); })); return d3.selectAll('.tool').on('click', function() { var new_tool, nodes; d3.selectAll('.tool').classed('active', false); d3.select(this).classed('active', true); new_tool = $(this).data('tool'); nodes = global.vis.selectAll('.node'); if (new_tool === 'add_link' && global.tool !== 'add_link') { /* remove drag handlers from nodes This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,7 +11,7 @@ .link, .drag_link stroke-width: 6px stroke: gray opacity: 0.5 .drag_link stroke-linecap: round @@ -34,13 +34,27 @@ left: 480px width: 240px margin-left: -120px text-align: center .tool:not(:last-child) margin-right: 10px .tool fill: #A3A4C3 cursor: pointer &.active fill: #B52D0C .library border: 2px solid #A3A4C3 border-radius: 6px background: rgba(255,255,255,0.8) padding: 6px margin-top: 10px svg cursor: pointer svg:not(:last-child) padding-right: 6px
LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
nitaku revised this gist
Nov 17, 2013 . 6 changed files with 885 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,338 @@ width = 960 height = 500 ### SELECTION - store the selected node ### ### EDITING - store the drag mode (either 'drag' or 'add_link') ### global = { selection: null } ### create some fake data ### graph = { nodes: [ {id: 'A', x: 469, y: 410, type: 'X'}, {id: 'B', x: 493, y: 364, type: 'X'}, {id: 'C', x: 442, y: 365, type: 'X'}, {id: 'D', x: 467, y: 314, type: 'X'}, {id: 'E', x: 477, y: 248, type: 'Y'}, {id: 'F', x: 425, y: 207, type: 'Y'}, {id: 'G', x: 402, y: 155, type: 'Y'}, {id: 'H', x: 369, y: 196, type: 'Y'}, {id: 'I', x: 350, y: 148, type: 'Z'}, {id: 'J', x: 539, y: 222, type: 'Z'}, {id: 'K', x: 594, y: 235, type: 'Z'}, {id: 'L', x: 582, y: 185, type: 'Z'}, {id: 'M', x: 633, y: 200, type: 'Z'} ], links: [ {source: 'A', target: 'B'}, {source: 'B', target: 'C'}, {source: 'C', target: 'A'}, {source: 'B', target: 'D'}, {source: 'D', target: 'C'}, {source: 'D', target: 'E'}, {source: 'E', target: 'F'}, {source: 'F', target: 'G'}, {source: 'F', target: 'H'}, {source: 'G', target: 'H'}, {source: 'G', target: 'I'}, {source: 'H', target: 'I'}, {source: 'J', target: 'E'}, {source: 'J', target: 'L'}, {source: 'J', target: 'K'}, {source: 'K', target: 'L'}, {source: 'L', target: 'M'}, {source: 'M', target: 'K'} ], objectify: (() -> ### resolve node IDs (not optimized at all!) ### for l in graph.links for n in graph.nodes if l.source is n.id l.source = n continue if l.target is n.id l.target = n continue ), remove: ((condemned) -> ### remove the given node or link from the graph, also deleting dangling links if a node is removed ### if condemned in graph.nodes graph.nodes = graph.nodes.filter (n) -> n isnt condemned graph.links = graph.links.filter (l) -> l.source.id isnt condemned.id and l.target.id isnt condemned.id else if condemned in graph.links graph.links = graph.links.filter (l) -> l isnt condemned ), last_index: 0, add_node: ((type) -> n = { id: graph.last_index++, x: width/2, y: height/2, type: type } graph.nodes.push(n) return n ), add_link: ((source, target) -> ### avoid links to self ### return null if source is target ### avoid link duplicates ### for link in graph.links return null if link.source is source and link.target is target l = { source: source, target: target } graph.links.push(l) return l ) } graph.objectify() window.main = (() -> ### create the SVG ### svg = d3.select('body').append('svg') .attr('width', width) .attr('height', height) ### ZOOM and PAN ### ### create container elements ### container = svg.append('g') container.call(d3.behavior.zoom().scaleExtent([0.5, 8]).on('zoom', (() -> global.vis.attr('transform', "translate(#{d3.event.translate})scale(#{d3.event.scale})")))) global.vis = container.append('g') ### create a rectangular overlay to catch events ### ### WARNING rect size is huge but not infinite. this is a dirty hack ### global.vis.append('rect') .attr('class', 'overlay') .attr('x', -500000) .attr('y', -500000) .attr('width', 1000000) .attr('height', 1000000) .on('click', ((d) -> ### SELECTION ### global.selection = null d3.selectAll('.node').classed('selected', false) d3.selectAll('.link').classed('selected', false) )) ### END ZOOM and PAN ### global.colorify = d3.scale.category10() ### initialize the force layout ### global.force = d3.layout.force() .size([width, height]) .charge(-400) .linkDistance(60) .on('tick', (() -> ### update nodes and links ### global.vis.selectAll('.node') .attr('transform', (d) -> "translate(#{d.x},#{d.y})") global.vis.selectAll('.link') .attr('x1', (d) -> d.source.x) .attr('y1', (d) -> d.source.y) .attr('x2', (d) -> d.target.x) .attr('y2', (d) -> d.target.y) )) ### DRAG ### global.drag = global.force.drag().on('dragstart', (d) -> d.fixed = true) ### DELETION - pressing DEL deletes the selection ### ### CREATION - pressing N creates a new node ### d3.select(window) .on('keydown', () -> if d3.event.keyCode is 46 # DEL if global.selection? graph.remove global.selection global.selection = null update() ) update() ### TOOLBAR ### toolbar = $("<div class='toolbar'></div>") $('body').append(toolbar) toolbar.append($("<input type='radio' name='tool' value='pointer' checked='checked'>Pointer</input>")) toolbar.append($("<input type='radio' name='tool' value='add_node'>Add node</input>")) toolbar.append($("<input type='radio' name='tool' value='add_link'>Add link</input>")) library = $("<div class='library'></div></div>") toolbar.append(library) ['X','Y','Z','W'].forEach (type) -> new_btn = $(""" <svg width='42' height='42'> <g class='node'> <circle cx='21' cy='21' r='18' stroke='#{global.colorify(type)}' fill='#{d3.hcl(global.colorify(type)).brighter(3)}' /> </g> </svg> """) new_btn.bind 'click', () -> graph.add_node(type) update() library.append(new_btn) library.hide() global.tool = $("input[name='tool']:checked").val() global.new_link_source = null global.vis .on('mousemove.add_link', ((d) -> ### check if there is a new link in creation ### if global.new_link_source? ### create the draggable link representation ### p = d3.mouse(global.vis.node()) global.drag_link .attr('x1', global.new_link_source.x) # source node can be in movement .attr('y1', global.new_link_source.y) .attr('x2', p[0]) .attr('y2', p[1]) )) .on('mouseup.add_link', ((d) -> global.new_link_source = null ### remove the draggable link representation, if exists ### global.drag_link.remove() if global.drag_link? )) $("input[name='tool']").change(() -> new_tool = $("input[name='tool']:checked").val() nodes = global.vis.selectAll('.node') if new_tool is 'add_link' and global.tool isnt 'add_link' ### remove drag handlers from nodes ### nodes .on('mousedown.drag', null) .on('touchstart.drag', null) ### add drag handlers for the add_link tool ### nodes .call(drag_add_link) else if new_tool isnt 'add_link' and global.tool is 'add_link' ### remove drag handlers for the add_link tool ### nodes .on('mousedown.add_link', null) .on('mouseup.add_link', null) ### add drag behavior to nodes ### nodes .call(global.drag) if new_tool is 'add_node' library.show() else library.hide() global.tool = new_tool ) ) update = () -> ### update the layout ### global.force .nodes(graph.nodes) .links(graph.links) .start() ### create nodes and links ### ### (links are drawn with insert to make them appear under the nodes) ### ### also define a drag behavior to drag nodes ### ### dragged nodes become fixed ### nodes = global.vis.selectAll('.node') .data(graph.nodes, (d) -> d.id) new_nodes = nodes .enter().append('g') .attr('class', 'node') .on('click', ((d) -> ### SELECTION ### global.selection = d d3.selectAll('.node').classed('selected', (d2) -> d2 is d) d3.selectAll('.link').classed('selected', false) )) links = global.vis.selectAll('.link') .data(graph.links, (d) -> "#{d.source.id}->#{d.target.id}") links .enter().insert('line', '.node') .attr('class', 'link') .on('click', ((d) -> ### SELECTION ### global.selection = d d3.selectAll('.link').classed('selected', (d2) -> d2 is d) d3.selectAll('.node').classed('selected', false) )) links .exit().remove() ### TOOLBAR - add link tool initialization for new nodes ### if global.tool is 'add_link' new_nodes.call(drag_add_link) else new_nodes.call(global.drag) # DRAG new_nodes.append('circle') .attr('r', 18) .attr('stroke', (d) -> global.colorify(d.type)) .attr('fill', (d) -> d3.hcl(global.colorify(d.type)).brighter(3)) ### draw the label ### new_nodes.append('text') .text((d) -> d.id) .attr('dy', '0.35em') .attr('fill', (d) -> global.colorify(d.type)) nodes .exit().remove() drag_add_link = (selection) -> selection .on('mousedown.add_link', ((d) -> global.new_link_source = d ### create the draggable link representation ### p = d3.mouse(global.vis.node()) global.drag_link = global.vis.insert('line', '.node') .attr('class', 'drag_link') .attr('x1', d.x) .attr('y1', d.y) .attr('x2', p[0]) .attr('y2', p[1]) ### prevent pan activation ### d3.event.stopPropagation() ### prevent text selection ### d3.event.preventDefault() )) .on('mouseup.add_link', ((d) -> ### add link and update, but only if a link is actually added ### if graph.add_link(global.new_link_source, d)? update() ))
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,50 @@ .node > circle { stroke-width: 4px; } .node > text { pointer-events: none; font-family: sans-serif; font-weight: bold; text-anchor: middle; } .link, .drag_link { stroke-width: 6px; stroke: gray; opacity: 0.6; } .drag_link { stroke-linecap: round; } .selected > circle { stroke-width: 8px; } .selected.link { stroke-width: 14px; } .overlay { fill: transparent; } .toolbar { position: absolute; top: 12px; left: 480px; width: 240px; margin-left: -120px; } .library { border: 2px solid gray; border-radius: 6px; background: rgba(255, 255, 255, 0.7); padding: 6px; } .library svg:not(:last-child) { padding-right: 6px; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,13 @@ <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Graph editing tools</title> <link type="text/css" href="index.css" rel="stylesheet"/> <script src='//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js' type='text/javascript'></script> <script src="d3.v3.min.js"></script> <script src="index.js"></script> </head> <body onload="main()"> </body> </html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,434 @@ (function() { var drag_add_link, global, graph, height, update, width, __indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; width = 960; height = 500; /* SELECTION - store the selected node */ /* EDITING - store the drag mode (either 'drag' or 'add_link') */ global = { selection: null }; /* create some fake data */ graph = { nodes: [ { id: 'A', x: 469, y: 410, type: 'X' }, { id: 'B', x: 493, y: 364, type: 'X' }, { id: 'C', x: 442, y: 365, type: 'X' }, { id: 'D', x: 467, y: 314, type: 'X' }, { id: 'E', x: 477, y: 248, type: 'Y' }, { id: 'F', x: 425, y: 207, type: 'Y' }, { id: 'G', x: 402, y: 155, type: 'Y' }, { id: 'H', x: 369, y: 196, type: 'Y' }, { id: 'I', x: 350, y: 148, type: 'Z' }, { id: 'J', x: 539, y: 222, type: 'Z' }, { id: 'K', x: 594, y: 235, type: 'Z' }, { id: 'L', x: 582, y: 185, type: 'Z' }, { id: 'M', x: 633, y: 200, type: 'Z' } ], links: [ { source: 'A', target: 'B' }, { source: 'B', target: 'C' }, { source: 'C', target: 'A' }, { source: 'B', target: 'D' }, { source: 'D', target: 'C' }, { source: 'D', target: 'E' }, { source: 'E', target: 'F' }, { source: 'F', target: 'G' }, { source: 'F', target: 'H' }, { source: 'G', target: 'H' }, { source: 'G', target: 'I' }, { source: 'H', target: 'I' }, { source: 'J', target: 'E' }, { source: 'J', target: 'L' }, { source: 'J', target: 'K' }, { source: 'K', target: 'L' }, { source: 'L', target: 'M' }, { source: 'M', target: 'K' } ], objectify: (function() { /* resolve node IDs (not optimized at all!) */ var l, n, _i, _len, _ref, _results; _ref = graph.links; _results = []; for (_i = 0, _len = _ref.length; _i < _len; _i++) { l = _ref[_i]; _results.push((function() { var _j, _len2, _ref2, _results2; _ref2 = graph.nodes; _results2 = []; for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { n = _ref2[_j]; if (l.source === n.id) { l.source = n; continue; } if (l.target === n.id) { l.target = n; continue; } else { _results2.push(void 0); } } return _results2; })()); } return _results; }), remove: (function(condemned) { /* remove the given node or link from the graph, also deleting dangling links if a node is removed */ if (__indexOf.call(graph.nodes, condemned) >= 0) { graph.nodes = graph.nodes.filter(function(n) { return n !== condemned; }); return graph.links = graph.links.filter(function(l) { return l.source.id !== condemned.id && l.target.id !== condemned.id; }); } else if (__indexOf.call(graph.links, condemned) >= 0) { return graph.links = graph.links.filter(function(l) { return l !== condemned; }); } }), last_index: 0, add_node: (function(type) { var n; n = { id: graph.last_index++, x: width / 2, y: height / 2, type: type }; graph.nodes.push(n); return n; }), add_link: (function(source, target) { /* avoid links to self */ var l, link, _i, _len, _ref; if (source === target) return null; /* avoid link duplicates */ _ref = graph.links; for (_i = 0, _len = _ref.length; _i < _len; _i++) { link = _ref[_i]; if (link.source === source && link.target === target) return null; } l = { source: source, target: target }; graph.links.push(l); return l; }) }; graph.objectify(); window.main = (function() { /* create the SVG */ var container, library, svg, toolbar; svg = d3.select('body').append('svg').attr('width', width).attr('height', height); /* ZOOM and PAN */ /* create container elements */ container = svg.append('g'); container.call(d3.behavior.zoom().scaleExtent([0.5, 8]).on('zoom', (function() { return global.vis.attr('transform', "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); }))); global.vis = container.append('g'); /* create a rectangular overlay to catch events */ /* WARNING rect size is huge but not infinite. this is a dirty hack */ global.vis.append('rect').attr('class', 'overlay').attr('x', -500000).attr('y', -500000).attr('width', 1000000).attr('height', 1000000).on('click', (function(d) { /* SELECTION */ global.selection = null; d3.selectAll('.node').classed('selected', false); return d3.selectAll('.link').classed('selected', false); })); /* END ZOOM and PAN */ global.colorify = d3.scale.category10(); /* initialize the force layout */ global.force = d3.layout.force().size([width, height]).charge(-400).linkDistance(60).on('tick', (function() { /* update nodes and links */ global.vis.selectAll('.node').attr('transform', function(d) { return "translate(" + d.x + "," + d.y + ")"; }); return global.vis.selectAll('.link').attr('x1', function(d) { return d.source.x; }).attr('y1', function(d) { return d.source.y; }).attr('x2', function(d) { return d.target.x; }).attr('y2', function(d) { return d.target.y; }); })); /* DRAG */ global.drag = global.force.drag().on('dragstart', function(d) { return d.fixed = true; }); /* DELETION - pressing DEL deletes the selection */ /* CREATION - pressing N creates a new node */ d3.select(window).on('keydown', function() { if (d3.event.keyCode === 46) { if (global.selection != null) { graph.remove(global.selection); global.selection = null; return update(); } } }); update(); /* TOOLBAR */ toolbar = $("<div class='toolbar'></div>"); $('body').append(toolbar); toolbar.append($("<input type='radio' name='tool' value='pointer' checked='checked'>Pointer</input>")); toolbar.append($("<input type='radio' name='tool' value='add_node'>Add node</input>")); toolbar.append($("<input type='radio' name='tool' value='add_link'>Add link</input>")); library = $("<div class='library'></div></div>"); toolbar.append(library); ['X', 'Y', 'Z', 'W'].forEach(function(type) { var new_btn; new_btn = $("<svg width='42' height='42'>\n <g class='node'>\n <circle\n cx='21'\n cy='21'\n r='18'\n stroke='" + (global.colorify(type)) + "'\n fill='" + (d3.hcl(global.colorify(type)).brighter(3)) + "'\n />\n </g>\n</svg>"); new_btn.bind('click', function() { graph.add_node(type); return update(); }); library.append(new_btn); return library.hide(); }); global.tool = $("input[name='tool']:checked").val(); global.new_link_source = null; global.vis.on('mousemove.add_link', (function(d) { /* check if there is a new link in creation */ var p; if (global.new_link_source != null) { /* create the draggable link representation */ p = d3.mouse(global.vis.node()); return global.drag_link.attr('x1', global.new_link_source.x).attr('y1', global.new_link_source.y).attr('x2', p[0]).attr('y2', p[1]); } })).on('mouseup.add_link', (function(d) { global.new_link_source = null; /* remove the draggable link representation, if exists */ if (global.drag_link != null) return global.drag_link.remove(); })); return $("input[name='tool']").change(function() { var new_tool, nodes; new_tool = $("input[name='tool']:checked").val(); nodes = global.vis.selectAll('.node'); if (new_tool === 'add_link' && global.tool !== 'add_link') { /* remove drag handlers from nodes */ nodes.on('mousedown.drag', null).on('touchstart.drag', null); /* add drag handlers for the add_link tool */ nodes.call(drag_add_link); } else if (new_tool !== 'add_link' && global.tool === 'add_link') { /* remove drag handlers for the add_link tool */ nodes.on('mousedown.add_link', null).on('mouseup.add_link', null); /* add drag behavior to nodes */ nodes.call(global.drag); } if (new_tool === 'add_node') { library.show(); } else { library.hide(); } return global.tool = new_tool; }); }); update = function() { /* update the layout */ var links, new_nodes, nodes; global.force.nodes(graph.nodes).links(graph.links).start(); /* create nodes and links */ /* (links are drawn with insert to make them appear under the nodes) */ /* also define a drag behavior to drag nodes */ /* dragged nodes become fixed */ nodes = global.vis.selectAll('.node').data(graph.nodes, function(d) { return d.id; }); new_nodes = nodes.enter().append('g').attr('class', 'node').on('click', (function(d) { /* SELECTION */ global.selection = d; d3.selectAll('.node').classed('selected', function(d2) { return d2 === d; }); return d3.selectAll('.link').classed('selected', false); })); links = global.vis.selectAll('.link').data(graph.links, function(d) { return "" + d.source.id + "->" + d.target.id; }); links.enter().insert('line', '.node').attr('class', 'link').on('click', (function(d) { /* SELECTION */ global.selection = d; d3.selectAll('.link').classed('selected', function(d2) { return d2 === d; }); return d3.selectAll('.node').classed('selected', false); })); links.exit().remove(); /* TOOLBAR - add link tool initialization for new nodes */ if (global.tool === 'add_link') { new_nodes.call(drag_add_link); } else { new_nodes.call(global.drag); } new_nodes.append('circle').attr('r', 18).attr('stroke', function(d) { return global.colorify(d.type); }).attr('fill', function(d) { return d3.hcl(global.colorify(d.type)).brighter(3); }); /* draw the label */ new_nodes.append('text').text(function(d) { return d.id; }).attr('dy', '0.35em').attr('fill', function(d) { return global.colorify(d.type); }); return nodes.exit().remove(); }; drag_add_link = function(selection) { return selection.on('mousedown.add_link', (function(d) { var p; global.new_link_source = d; /* create the draggable link representation */ p = d3.mouse(global.vis.node()); global.drag_link = global.vis.insert('line', '.node').attr('class', 'drag_link').attr('x1', d.x).attr('y1', d.y).attr('x2', p[0]).attr('y2', p[1]); /* prevent pan activation */ d3.event.stopPropagation(); /* prevent text selection */ return d3.event.preventDefault(); })).on('mouseup.add_link', (function(d) { /* add link and update, but only if a link is actually added */ if (graph.add_link(global.new_link_source, d) != null) return update(); })); }; }).call(this); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,46 @@ .node > circle stroke-width: 4px .node > text pointer-events: none font-family: sans-serif font-weight: bold text-anchor: middle // editing .link, .drag_link stroke-width: 6px stroke: gray opacity: 0.6 .drag_link stroke-linecap: round // selection .selected > circle stroke-width: 8px .selected.link stroke-width: 14px // zoom and pan .overlay fill: transparent // toolbar .toolbar position: absolute top: 12px left: 480px width: 240px margin-left: -120px .library border: 2px solid gray border-radius: 6px background: rgba(255,255,255,0.7) padding: 6px svg:not(:last-child) padding-right: 6px
-
nitaku created this gist
Nov 17, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,5 @@ Starting from [the previous example](http://bl.ocks.org/nitaku/7493693), this one implements a more complete graph editing tool. Select a tool to operate on the graph: The *pointer* only lets the user pan & zoom or drag nodes around. The *add node tool* opens up a library of node types; drag one into the graph to add a node of that type. The *add link tool* lets the user connect two nodes with a drag gesture from the first to the second one. Clicking a node or a link always selects it regardless of the current tool. You can press `del` to remove the current selection.