Revisions
-
steveharoz revised this gist
Oct 11, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains 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,3 +1,3 @@ license: gpl-3.0 height: 1030 scrolling: yes -
steveharoz revised this gist
Oct 11, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains 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,3 +1,3 @@ license: gpl-3.0 height: 1025 scrolling: yes -
steveharoz revised this gist
Oct 11, 2016 . 2 changed files with 11 additions and 0 deletions.There are no files selected for viewing
This file contains 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 @@ -164,6 +164,7 @@ function ticked() { node .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); d3.select('#alpha_value').style('flex-basis', (simulation.alpha()*100) + '%'); } This file contains 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 @@ -23,6 +23,12 @@ .controls .force label { display: inline-block; } .controls input[type="checkbox"] { transform: scale(1.2, 1.2); } .controls input[type="range"] { margin: 0 5% 0.5em 5%; width: 90%; } /* alpha viewer */ .controls .alpha p { margin-bottom: .25em; } .controls .alpha .alpha_bar { height: .5em; border: 1px #777 solid; border-radius: 2px; padding: 1px; display: flex; } .controls .alpha .alpha_bar #alpha_value { background-color: #555; border-radius: 1px; flex-basis: 100% } .controls .alpha .alpha_bar:hover { border-width: 2px; margin:-1px; } .controls .alpha .alpha_bar:active #alpha_value { background-color: #222 } /* SVG styles */ svg { @@ -40,6 +46,10 @@ </head> <body> <div class="controls"> <div class="force alpha"> <p><label>alpha</label> Simulation activity</p> <div class="alpha_bar" onclick="updateAll();"><div id="alpha_value"></div></div> </div> <div class="force"> <p><label>center</label> Shifts the view, so the graph is centered at this location.</p> <label> -
steveharoz revised this gist
Oct 11, 2016 . 1 changed file with 0 additions and 1 deletion.There are no files selected for viewing
This file contains 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 @@ -136,7 +136,6 @@ </div> <svg></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="code.js"></script> </body> </html> -
steveharoz revised this gist
Oct 8, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains 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 @@ -182,7 +182,7 @@ function dragged(d) { } function dragended(d) { if (!d3.event.active) simulation.alphaTarget(0.0001); d.fx = null; d.fy = null; } -
steveharoz revised this gist
Oct 8, 2016 . 1 changed file with 52 additions and 30 deletions.There are no files selected for viewing
This file contains 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 @@ -5,10 +5,31 @@ var svg = d3.select("svg"), // svg objects var link, node; // the data - an object with nodes and links var graph; // load the data d3.json("miserables.json", function(error, _graph) { if (error) throw error; graph = _graph; initializeDisplay(); initializeSimulation(); }); //////////// FORCE SIMULATION //////////// // force simulator var simulation = d3.forceSimulation(); // set up the simulation and event to update locations after each tick function initializeSimulation() { simulation.nodes(graph.nodes); initializeForces(); simulation.on("tick", ticked); } // values for all forces forceProperties = { center: { @@ -84,32 +105,17 @@ function updateForces() { .iterations(forceProperties.link.iterations) .links(forceProperties.link.enabled ? graph.links : []); // updates ignored until this is run // restarts the simulation (important if simulation has already slowed down) simulation.alpha(1).restart(); } //////////// DISPLAY //////////// // generate the svg objects and force simulation function initializeDisplay() { // set the data and properties of link lines link = svg.append("g") .attr("class", "links") @@ -133,13 +139,22 @@ d3.json("miserables.json", function(error, _graph) { .text(function(d) { return d.id; }); // visualize the graph updateDisplay(); } // update the display based on the forces (but not positions) function updateDisplay() { node .attr("r", forceProperties.collide.radius) .attr("stroke", forceProperties.charge.strength > 0 ? "blue" : "red") .attr("stroke-width", forceProperties.charge.enabled==false ? 0 : Math.abs(forceProperties.charge.strength)/15); link .attr("stroke-width", forceProperties.link.enabled ? 1 : .5) .attr("opacity", forceProperties.link.enabled ? 1 : 0); } // update the display positions after each simulation tick function ticked() { link .attr("x1", function(d) { return d.source.x; }) .attr("y1", function(d) { return d.source.y; }) @@ -149,11 +164,12 @@ d3.json("miserables.json", function(error, _graph) { node .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); } //////////// UI EVENTS //////////// function dragstarted(d) { if (!d3.event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; @@ -176,4 +192,10 @@ d3.select(window).on("resize", function(){ width = +svg.node().getBoundingClientRect().width; height = +svg.node().getBoundingClientRect().height; updateForces(); }); // convenience function to update everything (run after UI input) function updateAll() { updateForces(); updateDisplay(); } -
steveharoz revised this gist
Oct 7, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains 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 @@ -79,7 +79,7 @@ function updateForces() { .strength(forceProperties.forceY.strength * forceProperties.forceY.enabled) .y(height * forceProperties.forceY.y); simulation.force("link") .id(function(d) {return d.id;}) .distance(forceProperties.link.distance) .iterations(forceProperties.link.iterations) .links(forceProperties.link.enabled ? graph.links : []); -
steveharoz revised this gist
Oct 7, 2016 . 2 changed files with 8 additions and 7 deletions.There are no files selected for viewing
This file contains 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 @@ -25,7 +25,7 @@ forceProperties = { enabled: true, strength: .7, iterations: 1, radius: 5 }, forceX: { enabled: false, @@ -86,12 +86,12 @@ function updateForces() { // updates ugnored until this is run // restarts the simulation (important if simulation has already slowed down) simulation.alpha(1).restart(); } // update the display based on the forces function updateDisplay() { node .attr("r", forceProperties.collide.radius) .attr("stroke", forceProperties.charge.strength > 0 ? "blue" : "red") .attr("stroke-width", forceProperties.charge.enabled==false ? 0 : Math.abs(forceProperties.charge.strength)/15); This file contains 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 @@ -78,17 +78,17 @@ <label> strength <output id="collide_StrengthSliderOutput">.7</output> <input type="range" min="0" max="2" value=".7" step=".1" oninput="d3.select('#collide_StrengthSliderOutput').text(value); forceProperties.collide.strength=value; updateAll();"> </label> <label title="Size of nodes"> radius <output id="collide_radiusSliderOutput">5</output> <input type="range" min="0" max="100" value="5" step="1" oninput="d3.select('#collide_radiusSliderOutput').text(value); forceProperties.collide.radius=value; updateAll();"> </label> <label title="Higher values increase rigidity of the nodes (WARNING: high values are computationally expensive)"> iterations <output id="collide_iterationsSliderOutput">1</output> <input type="range" min="1" max="10" value="1" step="1" oninput="d3.select('#collide_iterationsSliderOutput').text(value); forceProperties.collide.iterations=value; updateAll();"> </label> </div> @@ -136,6 +136,7 @@ </div> <svg></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="https://d3js.org/d3-force.v1.min.js"></script> <!-- use the latest d3-force --> <script src="code.js"></script> </body> </html> -
steveharoz revised this gist
Oct 7, 2016 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains 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,7 +7,7 @@ width: 100%; margin: 0; padding: 0; display: flex; font-family: sans-serif; font-size: 75%; } .controls { flex-basis: 200px; padding: 0 5px; @@ -18,7 +18,7 @@ padding: 5px; margin: 5px 0; } .controls .force p label { margin-right: .5em; font-size: 120%; font-weight: bold;} .controls .force p { margin-top: 0;} .controls .force label { display: inline-block; } .controls input[type="checkbox"] { transform: scale(1.2, 1.2); } -
steveharoz revised this gist
Oct 7, 2016 . 2 changed files with 11 additions and 4 deletions.There are no files selected for viewing
This file contains 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 @@ -39,7 +39,8 @@ forceProperties = { }, link: { enabled: true, distance: 30, iterations: 1 } } @@ -80,11 +81,12 @@ function updateForces() { simulation.force("link") .id(d => d.id) .distance(forceProperties.link.distance) .iterations(forceProperties.link.iterations) .links(forceProperties.link.enabled ? graph.links : []); // updates ugnored until this is run // restarts the simulation (important if simulation has already slowed down) simulation.alphaTarget(.3).alpha(1).restart(); } // update the display based on the forces function updateDisplay() { This file contains 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 @@ -121,12 +121,17 @@ </div> <div class="force"> <p><label><input type="checkbox" checked onchange="forceProperties.link.enabled = this.checked; updateAll();"> link</label> Sets link length</p> <label title="The force will push/pull nodes to make links this long"> distance <output id="link_DistanceSliderOutput">30</output> <input type="range" min="0" max="100" value="30" step="1" oninput="d3.select('#link_DistanceSliderOutput').text(value); forceProperties.link.distance=value; updateAll();"> </label> <label title="Higher values increase rigidity of the links (WARNING: high values are computationally expensive)"> iterations <output id="link_IterationsSliderOutput">1</output> <input type="range" min="1" max="10" value="1" step="1" oninput="d3.select('#link_IterationsSliderOutput').text(value); forceProperties.link.iterations=value; updateAll();"> </label> </div> </div> <svg></svg> -
steveharoz revised this gist
Oct 7, 2016 . No changes.There are no files selected for viewing
-
steveharoz revised this gist
Oct 7, 2016 . 6 changed files with 27 additions and 31 deletions.There are no files selected for viewing
This file contains 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,2 +1,3 @@ license: gpl-3.0 height: 1000 scrolling: yes This file contains 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,3 @@ This demo lets you interactively try various settings and combinations of forces for [d3-force](https://github.com/d3/d3-force). It's based on [Mike Bostock's](https://bost.ocks.org/) example code for a [force directed graph](http://bl.ocks.org/mbostock/2675ff61ea5e063ede2b5d63c08020c7). This file contains 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 @@ -45,20 +45,21 @@ forceProperties = { // add forces to the simulation function initializeForces() { // add forces and associate each with a name simulation .force("link", d3.forceLink()) .force("charge", d3.forceManyBody()) .force("collide", d3.forceCollide()) .force("center", d3.forceCenter()) .force("forceX", d3.forceX()) .force("forceY", d3.forceY()); // apply properties to each of the forces updateForces(); } // apply new force properties function updateForces() { // get each force by name and update the properties simulation.force("center") .x(width * forceProperties.center.x) .y(height * forceProperties.center.y); This file contains 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 @@ -2,30 +2,32 @@ <head> <style> /* HTML styles */ html{ width: 100%; } body{ width: 100%; margin: 0; padding: 0; display: flex; font-family: sans-serif; font-size: 80%; } .controls { flex-basis: 200px; padding: 0 5px; } .controls .force { background-color:#eee; border-radius: 3px; padding: 5px; margin: 5px 0; } .controls .force p label { margin-right: .5em; font-size: 125%; font-weight: bold;} .controls .force p { margin-top: 0;} .controls .force label { display: inline-block; } .controls input[type="checkbox"] { transform: scale(1.2, 1.2); } .controls input[type="range"] { margin: 0 5% 0.5em 5%; width: 90%; } /* SVG styles */ svg { flex-basis: 100%; min-width: 200px; } .links line { stroke: #aaa; @@ -39,8 +41,7 @@ <body> <div class="controls"> <div class="force"> <p><label>center</label> Shifts the view, so the graph is centered at this location.</p> <label> x <output id="center_XSliderOutput">.5</output> @@ -54,8 +55,7 @@ <h3>center</h3> </div> <div class="force"> <p><label><input type="checkbox" checked onchange="forceProperties.charge.enabled = this.checked; updateAll();"> charge</label> Attracts (+) or repels (-) nodes to/from each other.</p> <label title="Negative strength repels nodes. Positive strength attracts nodes."> strength <output id="charge_StrengthSliderOutput">-30</output> @@ -74,8 +74,7 @@ <h3><input type="checkbox" checked onchange="forceProperties.charge.enabled = th </div> <div class="force"> <p><label><input type="checkbox" checked onchange="forceProperties.collide.enabled = this.checked; updateAll();"> collide</label> Prevents nodes from overlapping</p> <label> strength <output id="collide_StrengthSliderOutput">.7</output> @@ -94,8 +93,7 @@ <h3><input type="checkbox" checked onchange="forceProperties.collide.enabled = t </div> <div class="force"> <p><label><input type="checkbox" onchange="forceProperties.forceX.enabled = this.checked; updateAll();"> forceX</label> Acts like gravity. Pulls all points towards an X location.</p> <label> strength <output id="forceX_StrengthSliderOutput">.1</output> @@ -109,8 +107,7 @@ <h3><input type="checkbox" onchange="forceProperties.forceX.enabled = this.check </div> <div class="force"> <p><label><input type="checkbox" onchange="forceProperties.forceY.enabled = this.checked; updateAll();"> forceY</label> Acts like gravity. Pulls all points towards a Y location.</p> <label> strength <output id="forceY_StrengthSliderOutput">.1</output> @@ -124,8 +121,7 @@ <h3><input type="checkbox" onchange="forceProperties.forceY.enabled = this.check </div> <div class="force"> <p><label><input type="checkbox" checked onchange="forceProperties.link.enabled = this.checked; updateAll();"> link</label> Tries to set length of links</p> <label title="The force will push/pull nodes to make links this long"> distance <output id="link_DistanceSliderOutput">30</output> LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed.Unable to render rich display
Invalid image source.
-
steveharoz revised this gist
Oct 6, 2016 . 2 changed files with 59 additions and 34 deletions.There are no files selected for viewing
This file contains 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 @@ -3,9 +3,11 @@ var svg = d3.select("svg"), width = +svg.node().getBoundingClientRect().width, height = +svg.node().getBoundingClientRect().height; // svg objects var link, node; // the data var graph; // force simulator var simulation = d3.forceSimulation(); // values for all forces forceProperties = { @@ -41,7 +43,7 @@ forceProperties = { } } // add forces to the simulation function initializeForces() { simulation .force("link", d3.forceLink().id(d => d.id)) @@ -55,6 +57,7 @@ function initializeForces() { simulation.force("link").links(graph.links); } // apply new force properties function updateForces() { simulation.force("center") .x(width * forceProperties.center.x) @@ -82,31 +85,53 @@ function updateForces() { // "reheats" the simulation (important if simulation has already slowed down) simulation.alphaTarget(0.3).restart(); } // update the display based on the forces function updateDisplay() { node .attr("r", forceProperties.collide.radius/2) .attr("stroke", forceProperties.charge.strength > 0 ? "blue" : "red") .attr("stroke-width", forceProperties.charge.enabled==false ? 0 : Math.abs(forceProperties.charge.strength)/15); link .attr("stroke-width", forceProperties.link.enabled ? 1 : .5) .attr("opacity", forceProperties.link.enabled ? 1 : 0); } // convenience function to update everything function updateAll() { updateForces(); updateDisplay(); } // load the data then generate the svg objects and force simulation d3.json("miserables.json", function(error, _graph) { if (error) throw error; graph = _graph; // set the data and properties of link lines link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) .enter().append("line"); // set the data and properties of node circles node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(graph.nodes) .enter().append("circle") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); // node tooltip node.append("title") .text(function(d) { return d.id; }); // visualize the graph updateDisplay(); // set up the simulation and event to update locations after each tick simulation.nodes(graph.nodes); initializeForces(); simulation.on("tick", ticked); @@ -124,6 +149,8 @@ d3.json("miserables.json", function(error, _graph) { } }); // drag-drop events function dragstarted(d) { if (!d3.event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; This file contains 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 @@ -3,7 +3,7 @@ <style> /* HTML styles */ html{ height: 100%; width: 100%; } body{ height: 100%; width: 100%; margin: 0; padding: 0; display: flex; font-family: sans-serif; } .controls { flex-basis: 20%; min-width: 120px; @@ -32,8 +32,6 @@ } .nodes circle { pointer-events: all; } </style> @@ -46,92 +44,92 @@ <h3>center</h3> <label> x <output id="center_XSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#center_XSliderOutput').text(value); forceProperties.center.x=value; updateAll();"> </label> <label> y <output id="center_YSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#center_YSliderOutput').text(value); forceProperties.center.y=value; updateAll();"> </label> </div> <div class="force"> <h3><input type="checkbox" checked onchange="forceProperties.charge.enabled = this.checked; updateAll();"> charge</h3> <p>Attracts (+) or repels (-) nodes to/from each other.</p> <label title="Negative strength repels nodes. Positive strength attracts nodes."> strength <output id="charge_StrengthSliderOutput">-30</output> <input type="range" min="-200" max="50" value="-30" step=".1" oninput="d3.select('#charge_StrengthSliderOutput').text(value); forceProperties.charge.strength=value; updateAll();"> </label> <label title="Minimum distance where force is applied"> distanceMin <output id="charge_distanceMinSliderOutput">1</output> <input type="range" min="0" max="50" value="1" step=".1" oninput="d3.select('#charge_distanceMinSliderOutput').text(value); forceProperties.charge.distanceMin=value; updateAll();"> </label> <label title="Maximum distance where force is applied"> distanceMax <output id="charge_distanceMaxSliderOutput">2000</output> <input type="range" min="0" max="2000" value="2000" step=".1" oninput="d3.select('#charge_distanceMaxSliderOutput').text(value); forceProperties.charge.distanceMax=value; updateAll();"> </label> </div> <div class="force"> <h3><input type="checkbox" checked onchange="forceProperties.collide.enabled = this.checked; updateAll();"> collide</h3> <p>Prevents nodes from overlapping</p> <label> strength <output id="collide_StrengthSliderOutput">.7</output> <input type="range" min="0" max="50" value=".7" step=".1" oninput="d3.select('#collide_StrengthSliderOutput').text(value); forceProperties.collide.strength=value; updateAll();"> </label> <label title="Size of nodes"> radius <output id="collide_radiusSliderOutput">10</output> <input type="range" min="0" max="100" value="10" step="1" oninput="d3.select('#collide_radiusSliderOutput').text(value); forceProperties.collide.radius=value; updateAll();"> </label> <label title="Higher values increase rigidity of the nodes (WARNING: high values are computationally expensive)"> iterations <output id="collide_iterationsSliderOutput">1</output> <input type="range" min="0" max="10" value="1" step="1" oninput="d3.select('#collide_iterationsSliderOutput').text(value); forceProperties.collide.iterations=value; updateAll();"> </label> </div> <div class="force"> <h3><input type="checkbox" onchange="forceProperties.forceX.enabled = this.checked; updateAll();"> forceX</h3> <p>Acts like gravity. Pulls all points towards an X location.</p> <label> strength <output id="forceX_StrengthSliderOutput">.1</output> <input type="range" min="0" max="1" value=".1" step="0.01" oninput="d3.select('#forceX_StrengthSliderOutput').text(value); forceProperties.forceX.strength=value; updateAll();"> </label> <label title="The X location that the force will push the nodes to (NOTE: This demo multiplies by the svg width)"> x <output id="forceX_XSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#forceX_XSliderOutput').text(value); forceProperties.forceX.x=value; updateAll();"> </label> </div> <div class="force"> <h3><input type="checkbox" onchange="forceProperties.forceY.enabled = this.checked; updateAll();"> forceY</h3> <p>Acts like gravity. Pulls all points towards a Y location.</p> <label> strength <output id="forceY_StrengthSliderOutput">.1</output> <input type="range" min="0" max="1" value=".1" step="0.01" oninput="d3.select('#forceY_StrengthSliderOutput').text(value); forceProperties.forceY.strength=value; updateAll();"> </label> <label title="The Y location that the force will push the nodes to (NOTE: This demo multiplies by the svg height)"> y <output id="forceY_YSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#forceY_YSliderOutput').text(value); forceProperties.forceY.y=value; updateAll();"> </label> </div> <div class="force"> <h3><input type="checkbox" checked onchange="forceProperties.link.enabled = this.checked; updateAll();"> link</h3> <p>Tries to set length of links</p> <label title="The force will push/pull nodes to make links this long"> distance <output id="link_DistanceSliderOutput">30</output> <input type="range" min="0" max="100" value="30" step="1" oninput="d3.select('#link_DistanceSliderOutput').text(value); forceProperties.link.distance=value; updateAll();"> </label> </div> </div> -
steveharoz revised this gist
Oct 6, 2016 . 2 changed files with 124 additions and 20 deletions.There are no files selected for viewing
This file contains 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,7 +7,7 @@ var svg = d3.select("svg"), var graph; // force direction simulator var simulation = d3.forceSimulation(); // values for all forces forceProperties = { center: { x: 0.5, @@ -22,15 +22,16 @@ forceProperties = { collide: { enabled: true, strength: .7, iterations: 1, radius: 10 }, forceX: { enabled: false, strength: .1, x: .5 }, forceY: { enabled: false, strength: .1, y: .5 }, @@ -64,16 +65,22 @@ function updateForces() { .distanceMax(forceProperties.charge.distanceMax); simulation.force("collide") .strength(forceProperties.collide.strength * forceProperties.collide.enabled) .radius(forceProperties.collide.radius) .iterations(forceProperties.collide.iterations); simulation.force("forceX") .strength(forceProperties.forceX.strength * forceProperties.forceX.enabled) .x(width * forceProperties.forceX.x); simulation.force("forceY") .strength(forceProperties.forceY.strength * forceProperties.forceY.enabled) .y(height * forceProperties.forceY.y); simulation.force("link") .id(d => d.id) .distance(forceProperties.link.distance) .links(forceProperties.link.enabled ? graph.links : []); // updates ugnored until this is run // "reheats" the simulation (important if simulation has already slowed down) simulation.alphaTarget(0.3).restart(); } d3.json("miserables.json", function(error, _graph) { @@ -100,6 +107,7 @@ d3.json("miserables.json", function(error, _graph) { node.append("title") .text(function(d) { return d.id; }); simulation.nodes(graph.nodes); initializeForces(); simulation.on("tick", ticked); This file contains 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,43 +1,139 @@ <html> <head> <style> /* HTML styles */ html{ height: 100%; width: 100%; } body{ height: 100%; width: 100%; margin: 0; padding: 0; display: flex; } .controls { flex-basis: 20%; min-width: 120px; height: 100%; padding: 5px; } .controls .force { background-color:#eee; border-radius: 3px; padding: 5px; margin: 5px 0 5px 0; } .controls .force h3 { margin-top:0; margin-bottom: 0.25em; } .controls .force p { margin-top: 0; } .controls input[type="checkbox"] { transform: scale(1.2, 1.2); } .controls input[type="range"] { margin: 0 5% 0.5em 5%; width: 90%; } /* SVG styles */ svg { flex-basis: 80%; min-width: 200px; height: 100%; } .links line { stroke: #aaa; } .nodes circle { pointer-events: all; stroke: none; stroke-width: 40px; } </style> </head> <body> <div class="controls"> <div class="force"> <h3>center</h3> <p>Shifts the view, so the graph is centered at this location.</p> <label> x <output id="center_XSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#center_XSliderOutput').text(value); forceProperties.center.x=value; updateForces();"> </label> <label> y <output id="center_YSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#center_YSliderOutput').text(value); forceProperties.center.y=value; updateForces();"> </label> </div> <div class="force"> <h3><input type="checkbox" checked onchange="forceProperties.charge.enabled = this.checked; updateForces();"> charge</h3> <p>Attracts (+) or repels (-) nodes to/from each other.</p> <label> strength <output id="charge_StrengthSliderOutput">-30</output> <input type="range" min="-200" max="1" value="-30" step=".1" oninput="d3.select('#charge_StrengthSliderOutput').text(value); forceProperties.charge.strength=value; updateForces();"> </label> <label title="Minimum distance where force is applied"> distanceMin <output id="charge_distanceMinSliderOutput">1</output> <input type="range" min="0" max="50" value="1" step=".1" oninput="d3.select('#charge_distanceMinSliderOutput').text(value); forceProperties.charge.distanceMin=value; updateForces();"> </label> <label title="Maximum distance where force is applied"> distanceMax <output id="charge_distanceMaxSliderOutput">2000</output> <input type="range" min="0" max="2000" value="2000" step=".1" oninput="d3.select('#charge_distanceMaxSliderOutput').text(value); forceProperties.charge.distanceMax=value; updateForces();"> </label> </div> <div class="force"> <h3><input type="checkbox" checked onchange="forceProperties.collide.enabled = this.checked; updateForces();"> collide</h3> <p>Prevents nodes from overlapping</p> <label> strength <output id="collide_StrengthSliderOutput">.7</output> <input type="range" min="0" max="50" value=".7" step=".1" oninput="d3.select('#collide_StrengthSliderOutput').text(value); forceProperties.collide.strength=value; updateForces();"> </label> <label title="Size of nodes"> radius <output id="collide_radiusSliderOutput">10</output> <input type="range" min="0" max="100" value="10" step="1" oninput="d3.select('#collide_radiusSliderOutput').text(value); forceProperties.collide.radius=value; updateForces();"> </label> <label title="Higher values increase rigidity of the nodes (WARNING: high values are computationally expensive)"> iterations <output id="collide_iterationsSliderOutput">1</output> <input type="range" min="0" max="10" value="1" step="1" oninput="d3.select('#collide_iterationsSliderOutput').text(value); forceProperties.collide.iterations=value; updateForces();"> </label> </div> <div class="force"> <h3><input type="checkbox" onchange="forceProperties.forceX.enabled = this.checked; updateForces();"> forceX</h3> <p>Acts like gravity. Pulls all points towards an X location.</p> <label> strength <output id="forceX_StrengthSliderOutput">.1</output> <input type="range" min="0" max="1" value=".1" step="0.01" oninput="d3.select('#forceX_StrengthSliderOutput').text(value); forceProperties.forceX.strength=value; updateForces();"> </label> <label title="The X location that the force will push the nodes to (NOTE: This demo multiplies by the svg width)"> x <output id="forceX_XSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#forceX_XSliderOutput').text(value); forceProperties.forceX.x=value; updateForces();"> </label> </div> <div class="force"> <h3><input type="checkbox" onchange="forceProperties.forceY.enabled = this.checked; updateForces();"> forceY</h3> <p>Acts like gravity. Pulls all points towards a Y location.</p> <label> strength <output id="forceY_StrengthSliderOutput">.1</output> <input type="range" min="0" max="1" value=".1" step="0.01" oninput="d3.select('#forceY_StrengthSliderOutput').text(value); forceProperties.forceY.strength=value; updateForces();"> </label> <label title="The Y location that the force will push the nodes to (NOTE: This demo multiplies by the svg height)"> y <output id="forceY_YSliderOutput">.5</output> <input type="range" min="0" max="1" value=".5" step="0.01" oninput="d3.select('#forceY_YSliderOutput').text(value); forceProperties.forceY.y=value; updateForces();"> </label> </div> <div class="force"> <h3><input type="checkbox" checked onchange="forceProperties.link.enabled = this.checked; updateForces();"> link</h3> <p>Tries to set length of links</p> <label title="The link length that the force will push/pull nodes to achieve"> distance <output id="link_DistanceSliderOutput">30</output> <input type="range" min="0" max="100" value="30" step="1" oninput="d3.select('#link_DistanceSliderOutput').text(value); forceProperties.link.distance=value; updateForces();"> </label> </div> </div> <svg></svg> <script src="https://d3js.org/d3.v4.min.js"></script> -
steveharoz revised this gist
Oct 5, 2016 . 1 changed file with 48 additions and 16 deletions.There are no files selected for viewing
This file contains 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,38 @@ var svg = d3.select("svg"), var graph; // force direction simulator var simulation = d3.forceSimulation(); // force properties forceProperties = { center: { x: 0.5, y: 0.5 }, charge: { enabled: true, strength: -30, distanceMin: 1, distanceMax: 2000 }, collide: { enabled: true, strength: .7, radius: 10 }, forceX: { enabled: true, strength: .1, x: .5 }, forceY: { enabled: true, strength: .1, y: .5 }, link: { enabled: true, distance: 30 } } function initializeForces() { @@ -15,30 +47,30 @@ function initializeForces() { .force("charge", d3.forceManyBody()) .force("collide", d3.forceCollide()) .force("center", d3.forceCenter()) .force("forceX", d3.forceX()) .force("forceY", d3.forceY()); updateForces(); simulation.force("link").links(graph.links); } function updateForces() { simulation.force("center") .x(width * forceProperties.center.x) .y(height * forceProperties.center.y); simulation.force("charge") .strength(forceProperties.charge.strength * forceProperties.charge.enabled) .distanceMin(forceProperties.charge.distanceMin) .distanceMax(forceProperties.charge.distanceMax); simulation.force("collide") .strength(forceProperties.collide.strength * forceProperties.collide.enabled) .radius(forceProperties.collide.radius); simulation.force("forceX") .strength(forceProperties.forceX.strength * forceProperties.forceX.enabled) .x(width * forceProperties.forceX.x); simulation.force("forceY") .strength(forceProperties.forceY.strength * forceProperties.forceY.enabled) .y(height * forceProperties.forceY.y); // updates ugnored until this is run simulation.nodes(graph.nodes); -
steveharoz revised this gist
Oct 5, 2016 . 2 changed files with 71 additions and 24 deletions.There are no files selected for viewing
This file contains 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 @@ -3,14 +3,50 @@ var svg = d3.select("svg"), width = +svg.node().getBoundingClientRect().width, height = +svg.node().getBoundingClientRect().height; // the data var graph; // force direction simulator var simulation = d3.forceSimulation(); function initializeForces() { simulation .force("link", d3.forceLink().id(d => d.id)) .force("charge", d3.forceManyBody()) .force("collide", d3.forceCollide()) .force("center", d3.forceCenter()) .force("gravityX", d3.forceX()) .force("gravityY", d3.forceY()); updateForces(); simulation.force("link").links(graph.links); } function updateForces() { simulation.force("charge") .strength(-30) .distanceMin(1) .distanceMax(Infinity); simulation.force("collide") .strength(.7) .radius(10); simulation.force("center") .x(width / 2) .y(height / 2); simulation.force("gravityX") .strength(.1*0) .x(width / 2); simulation.force("gravityY") .strength(.1*0) .y(height / 2); // updates ugnored until this is run simulation.nodes(graph.nodes); } d3.json("miserables.json", function(error, _graph) { if (error) throw error; graph = _graph; var link = svg.append("g") .attr("class", "links") @@ -32,12 +68,8 @@ d3.json("miserables.json", function(error, graph) { node.append("title") .text(function(d) { return d.id; }); initializeForces(); simulation.on("tick", ticked); function ticked() { link @@ -68,3 +100,10 @@ function dragended(d) { d.fx = null; d.fy = null; } // update size-related forces d3.select(window).on("resize", function(){ width = +svg.node().getBoundingClientRect().width; height = +svg.node().getBoundingClientRect().height; updateForces(); }); This file contains 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 @@ -2,15 +2,8 @@ <head> <style> html{ height: 100%; width: 100%; } body{ height: 100%; width: 100%; margin: 0; padding: 0; display: flex; } .controls { flex-basis: 20%; @@ -24,13 +17,28 @@ min-width: 200px; height: 100%; } .links line { stroke: #aaa; } .nodes circle { pointer-events: all; stroke: none; stroke-width: 40px; } .controls input { width: 90%; } </style> </head> <body> <div class="controls"> <label for="slider1">Volume: </label><output id="slider1output">3</output> <input type="range" min="0" max="5" value="3" oninput="d3.select('#slider1output').text(value);" id="slider1"> <button onclick="updateForces();"> update </button> </div> <svg></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="code.js"></script> -
steveharoz revised this gist
Oct 2, 2016 . 2 changed files with 94 additions and 75 deletions.There are no files selected for viewing
This file contains 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,70 @@ var svg = d3.select("svg"), width = +svg.node().getBoundingClientRect().width, height = +svg.node().getBoundingClientRect().height; var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)) .force("collide", d3.forceCollide(0)); d3.json("miserables.json", function(error, graph) { if (error) throw error; var link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) .enter().append("line"); var node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r", 2.5) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); node.append("title") .text(function(d) { return d.id; }); simulation .nodes(graph.nodes) .on("tick", ticked); simulation.force("link") .links(graph.links); function ticked() { 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; }); node .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); } }); function dragstarted(d) { if (!d3.event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { if (!d3.event.active) simulation.alphaTarget(0); d.fx = null; d.fy = null; } This file contains 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,5 @@ <html> <head> <style> .links line { @@ -11,79 +11,28 @@ stroke: none; stroke-width: 40px; } .controls { flex-basis: 20%; min-width: 100px; height: 100%; background-color:#eee; } svg { flex-basis: 80%; min-width: 200px; height: 100%; } html{ height: 100%; width: 100%; } body{ height: 100%; width: 100%; margin: 0; padding: 0; display: flex; } </style> </head> <body> <div class="controls"></div> <svg></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="code.js"></script> </body> </html> -
mbostock revised this gist
Jul 4, 2016 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains 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 @@ -76,8 +76,8 @@ } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { -
mbostock revised this gist
Jul 4, 2016 . 1 changed file with 8 additions and 5 deletions.There are no files selected for viewing
This file contains 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 @@ -14,7 +14,7 @@ </style> <svg width="960" height="600"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> <script> var svg = d3.select("svg"), @@ -70,17 +70,20 @@ }); function dragstarted(d) { if (!d3.event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d.event.x; d.fy = d.event.y; } function dragended(d) { if (!d3.event.active) simulation.alphaTarget(0); d.fx = null; d.fy = null; } </script> -
mbostock revised this gist
May 15, 2016 . 1 changed file with 13 additions and 11 deletions.There are no files selected for viewing
This file contains 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,23 +7,23 @@ } .nodes circle { pointer-events: all; stroke: none; stroke-width: 40px; } </style> <svg width="960" height="600"></svg> <script src="https://d3js.org/d3.v4.0.0-alpha.40.min.js"></script> <script> var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2)); d3.json("miserables.json", function(error, graph) { @@ -32,15 +32,15 @@ var link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) .enter().append("line"); var node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r", 2.5) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) @@ -70,15 +70,17 @@ }); function dragstarted(d) { if (!d3.event.active) simulation.alphaTarget(0.3).restart() simulation.fix(d); } function dragged(d) { simulation.fix(d, d3.event.x, d3.event.y); } function dragended(d) { if (!d3.event.active) simulation.alphaTarget(0); simulation.unfix(d); } </script> -
mbostock revised this gist
May 11, 2016 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains 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,3 +1,5 @@ This example demonstrates applying [d3-drag](https://github.com/d3/d3-drag) to a [force-directed graph](/mbostock/f584aa36df54c451c94a9d0798caed35) computed using [d3-force](https://github.com/d3/d3-force). When the drag gesture starts, the targetted node is [fixed](https://github.com/d3/d3-force#simulation_fix) to the pointer; it is released when the gesture ends. In addition, the simulation is temporarily “heated” during interaction by setting the [target *alpha*](https://github.com/d3/d3-force#simulation_alphaTarget) to a non-zero value. If desired, you could refine this technique by also fixing nodes on mouseover, and releasing them on mouseout. (However, if there’s an active drag gesture during mouseout, you wouldn’t want to release the node until the gesture finishes.) Compare to the [Canvas version](/mbostock/ad70335eeef6d167bc36fd3c04378048). -
mbostock revised this gist
May 11, 2016 . 2 changed files 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.Unable to render rich display
Invalid image source.
-
mbostock created this gist
May 11, 2016 .There are no files selected for viewing
This file contains 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,2 @@ license: gpl-3.0 height: 600 This file contains 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,3 @@ This example demonstrates applying [d3-drag](https://github.com/d3/d3-drag) to a [force-directed graph](/mbostock/f584aa36df54c451c94a9d0798caed35) computed using [d3-force](https://github.com/d3/d3-force). When the drag gesture starts, the targetted node is [fixed](https://github.com/d3/d3-force#simulation_fix) to the pointer; it is released when the gesture ends. In addition, the simulation is temporarily “heated” during interaction by setting the [target *alpha*](https://github.com/d3/d3-force#simulation_alphaTarget) to a non-zero value. If desired, you could refine this technique by also fixing nodes on mouseover, and releasing them on mouseout. (However, if there’s an active drag gesture during mouseout, you wouldn’t want to release the node until the gesture finishes.) This file contains 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,84 @@ <!DOCTYPE html> <meta charset="utf-8"> <style> .links line { stroke: #aaa; } .nodes circle { stroke: #fff; stroke-width: 2px; } </style> <svg width="960" height="600"></svg> <script src="https://d3js.org/d3.v4.0.0-alpha.37.min.js"></script> <script> var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), radius = 5; var simulation = d3.forceSimulation() .force("charge", d3.forceManyBody().strength(-150)) .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("center", d3.forceCenter(width / 2, height / 2)); d3.json("miserables.json", function(error, graph) { if (error) throw error; var link = svg.append("g") .attr("class", "links") .selectAll("line") .data(graph.links) .enter().append("line"); var node = svg.append("g") .attr("class", "nodes") .selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r", radius) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); node.append("title") .text(function(d) { return d.id; }); simulation .nodes(graph.nodes) .on("tick", ticked); simulation.force("link") .links(graph.links); function ticked() { 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; }); node .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); } }); function dragstarted(d) { simulation.fix(d).alphaTarget(0.3).restart(); } function dragged(d) { simulation.fix(d, d3.event.x, d3.event.y); } function dragended(d) { simulation.unfix(d).alphaTarget(0); } </script> This file contains 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,337 @@ { "nodes": [ {"id": "Myriel", "group": 1}, {"id": "Napoleon", "group": 1}, {"id": "Mlle.Baptistine", "group": 1}, {"id": "Mme.Magloire", "group": 1}, {"id": "CountessdeLo", "group": 1}, {"id": "Geborand", "group": 1}, {"id": "Champtercier", "group": 1}, {"id": "Cravatte", "group": 1}, {"id": "Count", "group": 1}, {"id": "OldMan", "group": 1}, {"id": "Labarre", "group": 2}, {"id": "Valjean", "group": 2}, {"id": "Marguerite", "group": 3}, {"id": "Mme.deR", "group": 2}, {"id": "Isabeau", "group": 2}, {"id": "Gervais", "group": 2}, {"id": "Tholomyes", "group": 3}, {"id": "Listolier", "group": 3}, {"id": "Fameuil", "group": 3}, {"id": "Blacheville", "group": 3}, {"id": "Favourite", "group": 3}, {"id": "Dahlia", "group": 3}, {"id": "Zephine", "group": 3}, {"id": "Fantine", "group": 3}, {"id": "Mme.Thenardier", "group": 4}, {"id": "Thenardier", "group": 4}, {"id": "Cosette", "group": 5}, {"id": "Javert", "group": 4}, {"id": "Fauchelevent", "group": 0}, {"id": "Bamatabois", "group": 2}, {"id": "Perpetue", "group": 3}, {"id": "Simplice", "group": 2}, {"id": "Scaufflaire", "group": 2}, {"id": "Woman1", "group": 2}, {"id": "Judge", "group": 2}, {"id": "Champmathieu", "group": 2}, {"id": "Brevet", "group": 2}, {"id": "Chenildieu", "group": 2}, {"id": "Cochepaille", "group": 2}, {"id": "Pontmercy", "group": 4}, {"id": "Boulatruelle", "group": 6}, {"id": "Eponine", "group": 4}, {"id": "Anzelma", "group": 4}, {"id": "Woman2", "group": 5}, {"id": "MotherInnocent", "group": 0}, {"id": "Gribier", "group": 0}, {"id": "Jondrette", "group": 7}, {"id": "Mme.Burgon", "group": 7}, {"id": "Gavroche", "group": 8}, {"id": "Gillenormand", "group": 5}, {"id": "Magnon", "group": 5}, {"id": "Mlle.Gillenormand", "group": 5}, {"id": "Mme.Pontmercy", "group": 5}, {"id": "Mlle.Vaubois", "group": 5}, {"id": "Lt.Gillenormand", "group": 5}, {"id": "Marius", "group": 8}, {"id": "BaronessT", "group": 5}, {"id": "Mabeuf", "group": 8}, {"id": "Enjolras", "group": 8}, {"id": "Combeferre", "group": 8}, {"id": "Prouvaire", "group": 8}, {"id": "Feuilly", "group": 8}, {"id": "Courfeyrac", "group": 8}, {"id": "Bahorel", "group": 8}, {"id": "Bossuet", "group": 8}, {"id": "Joly", "group": 8}, {"id": "Grantaire", "group": 8}, {"id": "MotherPlutarch", "group": 9}, {"id": "Gueulemer", "group": 4}, {"id": "Babet", "group": 4}, {"id": "Claquesous", "group": 4}, {"id": "Montparnasse", "group": 4}, {"id": "Toussaint", "group": 5}, {"id": "Child1", "group": 10}, {"id": "Child2", "group": 10}, {"id": "Brujon", "group": 4}, {"id": "Mme.Hucheloup", "group": 8} ], "links": [ {"source": "Napoleon", "target": "Myriel", "value": 1}, {"source": "Mlle.Baptistine", "target": "Myriel", "value": 8}, {"source": "Mme.Magloire", "target": "Myriel", "value": 10}, {"source": "Mme.Magloire", "target": "Mlle.Baptistine", "value": 6}, {"source": "CountessdeLo", "target": "Myriel", "value": 1}, {"source": "Geborand", "target": "Myriel", "value": 1}, {"source": "Champtercier", "target": "Myriel", "value": 1}, {"source": "Cravatte", "target": "Myriel", "value": 1}, {"source": "Count", "target": "Myriel", "value": 2}, {"source": "OldMan", "target": "Myriel", "value": 1}, {"source": "Valjean", "target": "Labarre", "value": 1}, {"source": "Valjean", "target": "Mme.Magloire", "value": 3}, {"source": "Valjean", "target": "Mlle.Baptistine", "value": 3}, {"source": "Valjean", "target": "Myriel", "value": 5}, {"source": "Marguerite", "target": "Valjean", "value": 1}, {"source": "Mme.deR", "target": "Valjean", "value": 1}, {"source": "Isabeau", "target": "Valjean", "value": 1}, {"source": "Gervais", "target": "Valjean", "value": 1}, {"source": "Listolier", "target": "Tholomyes", "value": 4}, {"source": "Fameuil", "target": "Tholomyes", "value": 4}, {"source": "Fameuil", "target": "Listolier", "value": 4}, {"source": "Blacheville", "target": "Tholomyes", "value": 4}, {"source": "Blacheville", "target": "Listolier", "value": 4}, {"source": "Blacheville", "target": "Fameuil", "value": 4}, {"source": "Favourite", "target": "Tholomyes", "value": 3}, {"source": "Favourite", "target": "Listolier", "value": 3}, {"source": "Favourite", "target": "Fameuil", "value": 3}, {"source": "Favourite", "target": "Blacheville", "value": 4}, {"source": "Dahlia", "target": "Tholomyes", "value": 3}, {"source": "Dahlia", "target": "Listolier", "value": 3}, {"source": "Dahlia", "target": "Fameuil", "value": 3}, {"source": "Dahlia", "target": "Blacheville", "value": 3}, {"source": "Dahlia", "target": "Favourite", "value": 5}, {"source": "Zephine", "target": "Tholomyes", "value": 3}, {"source": "Zephine", "target": "Listolier", "value": 3}, {"source": "Zephine", "target": "Fameuil", "value": 3}, {"source": "Zephine", "target": "Blacheville", "value": 3}, {"source": "Zephine", "target": "Favourite", "value": 4}, {"source": "Zephine", "target": "Dahlia", "value": 4}, {"source": "Fantine", "target": "Tholomyes", "value": 3}, {"source": "Fantine", "target": "Listolier", "value": 3}, {"source": "Fantine", "target": "Fameuil", "value": 3}, {"source": "Fantine", "target": "Blacheville", "value": 3}, {"source": "Fantine", "target": "Favourite", "value": 4}, {"source": "Fantine", "target": "Dahlia", "value": 4}, {"source": "Fantine", "target": "Zephine", "value": 4}, {"source": "Fantine", "target": "Marguerite", "value": 2}, {"source": "Fantine", "target": "Valjean", "value": 9}, {"source": "Mme.Thenardier", "target": "Fantine", "value": 2}, {"source": "Mme.Thenardier", "target": "Valjean", "value": 7}, {"source": "Thenardier", "target": "Mme.Thenardier", "value": 13}, {"source": "Thenardier", "target": "Fantine", "value": 1}, {"source": "Thenardier", "target": "Valjean", "value": 12}, {"source": "Cosette", "target": "Mme.Thenardier", "value": 4}, {"source": "Cosette", "target": "Valjean", "value": 31}, {"source": "Cosette", "target": "Tholomyes", "value": 1}, {"source": "Cosette", "target": "Thenardier", "value": 1}, {"source": "Javert", "target": "Valjean", "value": 17}, {"source": "Javert", "target": "Fantine", "value": 5}, {"source": "Javert", "target": "Thenardier", "value": 5}, {"source": "Javert", "target": "Mme.Thenardier", "value": 1}, {"source": "Javert", "target": "Cosette", "value": 1}, {"source": "Fauchelevent", "target": "Valjean", "value": 8}, {"source": "Fauchelevent", "target": "Javert", "value": 1}, {"source": "Bamatabois", "target": "Fantine", "value": 1}, {"source": "Bamatabois", "target": "Javert", "value": 1}, {"source": "Bamatabois", "target": "Valjean", "value": 2}, {"source": "Perpetue", "target": "Fantine", "value": 1}, {"source": "Simplice", "target": "Perpetue", "value": 2}, {"source": "Simplice", "target": "Valjean", "value": 3}, {"source": "Simplice", "target": "Fantine", "value": 2}, {"source": "Simplice", "target": "Javert", "value": 1}, {"source": "Scaufflaire", "target": "Valjean", "value": 1}, {"source": "Woman1", "target": "Valjean", "value": 2}, {"source": "Woman1", "target": "Javert", "value": 1}, {"source": "Judge", "target": "Valjean", "value": 3}, {"source": "Judge", "target": "Bamatabois", "value": 2}, {"source": "Champmathieu", "target": "Valjean", "value": 3}, {"source": "Champmathieu", "target": "Judge", "value": 3}, {"source": "Champmathieu", "target": "Bamatabois", "value": 2}, {"source": "Brevet", "target": "Judge", "value": 2}, {"source": "Brevet", "target": "Champmathieu", "value": 2}, {"source": "Brevet", "target": "Valjean", "value": 2}, {"source": "Brevet", "target": "Bamatabois", "value": 1}, {"source": "Chenildieu", "target": "Judge", "value": 2}, {"source": "Chenildieu", "target": "Champmathieu", "value": 2}, {"source": "Chenildieu", "target": "Brevet", "value": 2}, {"source": "Chenildieu", "target": "Valjean", "value": 2}, {"source": "Chenildieu", "target": "Bamatabois", "value": 1}, {"source": "Cochepaille", "target": "Judge", "value": 2}, {"source": "Cochepaille", "target": "Champmathieu", "value": 2}, {"source": "Cochepaille", "target": "Brevet", "value": 2}, {"source": "Cochepaille", "target": "Chenildieu", "value": 2}, {"source": "Cochepaille", "target": "Valjean", "value": 2}, {"source": "Cochepaille", "target": "Bamatabois", "value": 1}, {"source": "Pontmercy", "target": "Thenardier", "value": 1}, {"source": "Boulatruelle", "target": "Thenardier", "value": 1}, {"source": "Eponine", "target": "Mme.Thenardier", "value": 2}, {"source": "Eponine", "target": "Thenardier", "value": 3}, {"source": "Anzelma", "target": "Eponine", "value": 2}, {"source": "Anzelma", "target": "Thenardier", "value": 2}, {"source": "Anzelma", "target": "Mme.Thenardier", "value": 1}, {"source": "Woman2", "target": "Valjean", "value": 3}, {"source": "Woman2", "target": "Cosette", "value": 1}, {"source": "Woman2", "target": "Javert", "value": 1}, {"source": "MotherInnocent", "target": "Fauchelevent", "value": 3}, {"source": "MotherInnocent", "target": "Valjean", "value": 1}, {"source": "Gribier", "target": "Fauchelevent", "value": 2}, {"source": "Mme.Burgon", "target": "Jondrette", "value": 1}, {"source": "Gavroche", "target": "Mme.Burgon", "value": 2}, {"source": "Gavroche", "target": "Thenardier", "value": 1}, {"source": "Gavroche", "target": "Javert", "value": 1}, {"source": "Gavroche", "target": "Valjean", "value": 1}, {"source": "Gillenormand", "target": "Cosette", "value": 3}, {"source": "Gillenormand", "target": "Valjean", "value": 2}, {"source": "Magnon", "target": "Gillenormand", "value": 1}, {"source": "Magnon", "target": "Mme.Thenardier", "value": 1}, {"source": "Mlle.Gillenormand", "target": "Gillenormand", "value": 9}, {"source": "Mlle.Gillenormand", "target": "Cosette", "value": 2}, {"source": "Mlle.Gillenormand", "target": "Valjean", "value": 2}, {"source": "Mme.Pontmercy", "target": "Mlle.Gillenormand", "value": 1}, {"source": "Mme.Pontmercy", "target": "Pontmercy", "value": 1}, {"source": "Mlle.Vaubois", "target": "Mlle.Gillenormand", "value": 1}, {"source": "Lt.Gillenormand", "target": "Mlle.Gillenormand", "value": 2}, {"source": "Lt.Gillenormand", "target": "Gillenormand", "value": 1}, {"source": "Lt.Gillenormand", "target": "Cosette", "value": 1}, {"source": "Marius", "target": "Mlle.Gillenormand", "value": 6}, {"source": "Marius", "target": "Gillenormand", "value": 12}, {"source": "Marius", "target": "Pontmercy", "value": 1}, {"source": "Marius", "target": "Lt.Gillenormand", "value": 1}, {"source": "Marius", "target": "Cosette", "value": 21}, {"source": "Marius", "target": "Valjean", "value": 19}, {"source": "Marius", "target": "Tholomyes", "value": 1}, {"source": "Marius", "target": "Thenardier", "value": 2}, {"source": "Marius", "target": "Eponine", "value": 5}, {"source": "Marius", "target": "Gavroche", "value": 4}, {"source": "BaronessT", "target": "Gillenormand", "value": 1}, {"source": "BaronessT", "target": "Marius", "value": 1}, {"source": "Mabeuf", "target": "Marius", "value": 1}, {"source": "Mabeuf", "target": "Eponine", "value": 1}, {"source": "Mabeuf", "target": "Gavroche", "value": 1}, {"source": "Enjolras", "target": "Marius", "value": 7}, {"source": "Enjolras", "target": "Gavroche", "value": 7}, {"source": "Enjolras", "target": "Javert", "value": 6}, {"source": "Enjolras", "target": "Mabeuf", "value": 1}, {"source": "Enjolras", "target": "Valjean", "value": 4}, {"source": "Combeferre", "target": "Enjolras", "value": 15}, {"source": "Combeferre", "target": "Marius", "value": 5}, {"source": "Combeferre", "target": "Gavroche", "value": 6}, {"source": "Combeferre", "target": "Mabeuf", "value": 2}, {"source": "Prouvaire", "target": "Gavroche", "value": 1}, {"source": "Prouvaire", "target": "Enjolras", "value": 4}, {"source": "Prouvaire", "target": "Combeferre", "value": 2}, {"source": "Feuilly", "target": "Gavroche", "value": 2}, {"source": "Feuilly", "target": "Enjolras", "value": 6}, {"source": "Feuilly", "target": "Prouvaire", "value": 2}, {"source": "Feuilly", "target": "Combeferre", "value": 5}, {"source": "Feuilly", "target": "Mabeuf", "value": 1}, {"source": "Feuilly", "target": "Marius", "value": 1}, {"source": "Courfeyrac", "target": "Marius", "value": 9}, {"source": "Courfeyrac", "target": "Enjolras", "value": 17}, {"source": "Courfeyrac", "target": "Combeferre", "value": 13}, {"source": "Courfeyrac", "target": "Gavroche", "value": 7}, {"source": "Courfeyrac", "target": "Mabeuf", "value": 2}, {"source": "Courfeyrac", "target": "Eponine", "value": 1}, {"source": "Courfeyrac", "target": "Feuilly", "value": 6}, {"source": "Courfeyrac", "target": "Prouvaire", "value": 3}, {"source": "Bahorel", "target": "Combeferre", "value": 5}, {"source": "Bahorel", "target": "Gavroche", "value": 5}, {"source": "Bahorel", "target": "Courfeyrac", "value": 6}, {"source": "Bahorel", "target": "Mabeuf", "value": 2}, {"source": "Bahorel", "target": "Enjolras", "value": 4}, {"source": "Bahorel", "target": "Feuilly", "value": 3}, {"source": "Bahorel", "target": "Prouvaire", "value": 2}, {"source": "Bahorel", "target": "Marius", "value": 1}, {"source": "Bossuet", "target": "Marius", "value": 5}, {"source": "Bossuet", "target": "Courfeyrac", "value": 12}, {"source": "Bossuet", "target": "Gavroche", "value": 5}, {"source": "Bossuet", "target": "Bahorel", "value": 4}, {"source": "Bossuet", "target": "Enjolras", "value": 10}, {"source": "Bossuet", "target": "Feuilly", "value": 6}, {"source": "Bossuet", "target": "Prouvaire", "value": 2}, {"source": "Bossuet", "target": "Combeferre", "value": 9}, {"source": "Bossuet", "target": "Mabeuf", "value": 1}, {"source": "Bossuet", "target": "Valjean", "value": 1}, {"source": "Joly", "target": "Bahorel", "value": 5}, {"source": "Joly", "target": "Bossuet", "value": 7}, {"source": "Joly", "target": "Gavroche", "value": 3}, {"source": "Joly", "target": "Courfeyrac", "value": 5}, {"source": "Joly", "target": "Enjolras", "value": 5}, {"source": "Joly", "target": "Feuilly", "value": 5}, {"source": "Joly", "target": "Prouvaire", "value": 2}, {"source": "Joly", "target": "Combeferre", "value": 5}, {"source": "Joly", "target": "Mabeuf", "value": 1}, {"source": "Joly", "target": "Marius", "value": 2}, {"source": "Grantaire", "target": "Bossuet", "value": 3}, {"source": "Grantaire", "target": "Enjolras", "value": 3}, {"source": "Grantaire", "target": "Combeferre", "value": 1}, {"source": "Grantaire", "target": "Courfeyrac", "value": 2}, {"source": "Grantaire", "target": "Joly", "value": 2}, {"source": "Grantaire", "target": "Gavroche", "value": 1}, {"source": "Grantaire", "target": "Bahorel", "value": 1}, {"source": "Grantaire", "target": "Feuilly", "value": 1}, {"source": "Grantaire", "target": "Prouvaire", "value": 1}, {"source": "MotherPlutarch", "target": "Mabeuf", "value": 3}, {"source": "Gueulemer", "target": "Thenardier", "value": 5}, {"source": "Gueulemer", "target": "Valjean", "value": 1}, {"source": "Gueulemer", "target": "Mme.Thenardier", "value": 1}, {"source": "Gueulemer", "target": "Javert", "value": 1}, {"source": "Gueulemer", "target": "Gavroche", "value": 1}, {"source": "Gueulemer", "target": "Eponine", "value": 1}, {"source": "Babet", "target": "Thenardier", "value": 6}, {"source": "Babet", "target": "Gueulemer", "value": 6}, {"source": "Babet", "target": "Valjean", "value": 1}, {"source": "Babet", "target": "Mme.Thenardier", "value": 1}, {"source": "Babet", "target": "Javert", "value": 2}, {"source": "Babet", "target": "Gavroche", "value": 1}, {"source": "Babet", "target": "Eponine", "value": 1}, {"source": "Claquesous", "target": "Thenardier", "value": 4}, {"source": "Claquesous", "target": "Babet", "value": 4}, {"source": "Claquesous", "target": "Gueulemer", "value": 4}, {"source": "Claquesous", "target": "Valjean", "value": 1}, {"source": "Claquesous", "target": "Mme.Thenardier", "value": 1}, {"source": "Claquesous", "target": "Javert", "value": 1}, {"source": "Claquesous", "target": "Eponine", "value": 1}, {"source": "Claquesous", "target": "Enjolras", "value": 1}, {"source": "Montparnasse", "target": "Javert", "value": 1}, {"source": "Montparnasse", "target": "Babet", "value": 2}, {"source": "Montparnasse", "target": "Gueulemer", "value": 2}, {"source": "Montparnasse", "target": "Claquesous", "value": 2}, {"source": "Montparnasse", "target": "Valjean", "value": 1}, {"source": "Montparnasse", "target": "Gavroche", "value": 1}, {"source": "Montparnasse", "target": "Eponine", "value": 1}, {"source": "Montparnasse", "target": "Thenardier", "value": 1}, {"source": "Toussaint", "target": "Cosette", "value": 2}, {"source": "Toussaint", "target": "Javert", "value": 1}, {"source": "Toussaint", "target": "Valjean", "value": 1}, {"source": "Child1", "target": "Gavroche", "value": 2}, {"source": "Child2", "target": "Gavroche", "value": 2}, {"source": "Child2", "target": "Child1", "value": 3}, {"source": "Brujon", "target": "Babet", "value": 3}, {"source": "Brujon", "target": "Gueulemer", "value": 3}, {"source": "Brujon", "target": "Thenardier", "value": 3}, {"source": "Brujon", "target": "Gavroche", "value": 1}, {"source": "Brujon", "target": "Eponine", "value": 1}, {"source": "Brujon", "target": "Claquesous", "value": 1}, {"source": "Brujon", "target": "Montparnasse", "value": 1}, {"source": "Mme.Hucheloup", "target": "Bossuet", "value": 1}, {"source": "Mme.Hucheloup", "target": "Joly", "value": 1}, {"source": "Mme.Hucheloup", "target": "Grantaire", "value": 1}, {"source": "Mme.Hucheloup", "target": "Bahorel", "value": 1}, {"source": "Mme.Hucheloup", "target": "Courfeyrac", "value": 1}, {"source": "Mme.Hucheloup", "target": "Gavroche", "value": 1}, {"source": "Mme.Hucheloup", "target": "Enjolras", "value": 1} ] }