d3.js - Having trouble converting a D3 v3 Force Directed graph into D3 v4 library implementation? -
i've created first force directed graph using v3 library, i'm required create same graph using d3 version 4 library, methods have changed tremendously in v4, , i'm getting error @ force()/drag() methods of 3 not exist in v4.
my graph based on following mockup - http://www.ourd3js.com/wordpress/?p=606
is there repository of samples have been created in v4 library of d3 someplace can take , learn few functions can replace particular chart?
edit:
my current code looks this, i'm not able convert completely, example, node links close text of links , nodes overlapping.
<svg width="960" height="600"></svg>
javascript code:
var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); var graph = root; var w = window, d = document, e = d.documentelement, g = d.getelementsbytagname('body')[0], x = w.innerwidth || e.clientwidth || g.clientwidth, y = w.innerheight|| e.clientheight|| g.clientheight; var width = x; var height = y; var img_w = 24; var img_h = 24; var k = math.sqrt(root.nodes.length / (width * height)); var simulation = d3.forcesimulation() .force("link", d3.forcelink().id(function(d) { return d.id; })) .force("charge", d3.forcemanybody().strength(-5 / k)) .force("center", d3.forcecenter(width / 2, height / 2)); 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("image") .attr("width",img_w) .attr("height",img_h) .attr("xlink:href",function(d){ return d.image; }) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); var links_text = svg.selectall(".linetext") .data(graph.links) .enter() .append("text") .attr("class","linetext slds-text-heading--small") .attr("text-anchor", "middle") .text(function(d){ return '['+d.relation+']'; }); var nodes_text = svg.selectall(".nodetext") .data(graph.nodes) .enter() .append("text") .attr("class","nodetext slds-text-heading--label") .attr("text-anchor", "middle") .attr("dx",-20) .attr("dy",20) .text(function(d){ return (d.subname!=''?(d.subname+': '):'')+d.name; }); 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; }); links_text .attr("x",function(d){ return (d.source.x + d.target.x) / 2; }) .attr("y",function(d){ return (d.source.y + d.target.y) / 2; }); node .attr("x", function(d) { return d.x; }) .attr("y", function(d) { return d.y; }); nodes_text .attr("x",function(d){ return d.x + 20 }) .attr("y",function(d){ return d.y + img_w/2; }); } 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; }
the json data string:
var root = { "nodes" : [ { "subname" : "", "name" : "telco power case", "image" : "/node32.png", "id" : 0 }, { "subname" : "contact", "name" : "suman kumar", "image" : "/subnode32.png.png", "id" : 1 }, { "subname" : "contact", "name" : "karla samuel", "image" : "/subnode32.png.png", "id" : 2 }, { "subname" : "account", "name" : "signa tech", "image" : "/subnode32.png.png", "id" : 3 }, { "subname" : "", "name" : "maven's case", "image" : "/node32.png", "id" : 4 }, { "subname" : "", "name" : "delta case", "image" : "/node32.png", "id" : 5 }, { "subname" : "contact", "name" : "t browney", "image" : "/subnode32.png.png", "id" : 6 }, { "subname" : "account", "name" : "presto", "image" : "/subnode32.png.png", "id" : 7 }, { "subname" : "contact", "name" : "bob tannenbaum", "image" : "/subnode32.png.png", "id" : 8 }, { "subname" : "account", "name" : "tesla power", "image" : "/subnode32.png.png", "id" : 9 } ], "links" : [ { "target" : 1, "source" : 0, "relation" : "trainee" }, { "target" : 2, "source" : 0, "relation" : "manager" }, { "target" : 3, "source" : 0, "relation" : "technology" }, { "target" : 1, "source" : 0, "relation" : "trainee" }, { "target" : 2, "source" : 0, "relation" : "manager" }, { "target" : 3, "source" : 0, "relation" : "technology" }, { "target" : 2, "source" : 4, "relation" : "expert" }, { "target" : 2, "source" : 5, "relation" : "expert" }, { "target" : 1, "source" : 5, "relation" : "expert" }, { "target" : 6, "source" : 5, "relation" : "trainee" }, { "target" : 7, "source" : 5, "relation" : "technology;new firm" }, { "target" : 8, "source" : 4, "relation" : "expert" }, { "target" : 9, "source" : 4, "relation" : "new firm" }, { "target" : 8, "source" : 4, "relation" : "expert" }, { "target" : 9, "source" : 4, "relation" : "new firm" }, { "target" : 6, "source" : 5, "relation" : "trainee" }, { "target" : 7, "source" : 5, "relation" : "technology;new firm" } ] };
you asking flurry of questions @ once, let's little sanity on question.
first, linkdistance distance on d3.forcelink, in code:
.force("link", d3.forcelink().id(function(d) { return d.id; }).distance(200))
second, center image, when set it's x position:
node .attr("x", function(d) { return (d.x - img_w /2); });
third, boundary detection need implement yourself. example, fix nodes position (building on last code snippet):
node .attr("x", function(d) { var xpos = (d.x - img_w /2); if (xpos < 0) return 0; if (xpos > (960 - img_w)) return (960 - img_w); return xpos; }) .attr("y", function(d) { var ypos = d.y; if (ypos < 0) return 0; if (ypos > (600 - img_h)) return (600 - img_h); return ypos; });
now apply same methodology links...
here's example code i've started implement fixes:
<!doctype html> <html> <head> <script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> <style> .links line { stroke: #aaa; } .nodes circle { pointer-events: all; stroke: none; stroke-width: 40px; } </style> </head> <body> <svg width="960" height="600"></svg> <script> var root = { "nodes": [{ "subname": "", "name": "telco power case", "image": "http://lorempixel.com/24/24/", "id": 0 }, { "subname": "contact", "name": "suman kumar", "image": "http://lorempixel.com/24/24/", "id": 1 }, { "subname": "contact", "name": "karla samuel", "image": "http://lorempixel.com/24/24/", "id": 2 }, { "subname": "account", "name": "signa tech", "image": "http://lorempixel.com/24/24/", "id": 3 }, { "subname": "", "name": "maven's case", "image": "http://lorempixel.com/24/24/", "id": 4 }, { "subname": "", "name": "delta case", "image": "http://lorempixel.com/24/24/", "id": 5 }, { "subname": "contact", "name": "t browney", "image": "http://lorempixel.com/24/24/", "id": 6 }, { "subname": "account", "name": "presto", "image": "http://lorempixel.com/24/24/", "id": 7 }, { "subname": "contact", "name": "bob tannenbaum", "image": "http://lorempixel.com/24/24/", "id": 8 }, { "subname": "account", "name": "tesla power", "image": "http://lorempixel.com/24/24/", "id": 9 }], "links": [{ "target": 1, "source": 0, "relation": "trainee" }, { "target": 2, "source": 0, "relation": "manager" }, { "target": 3, "source": 0, "relation": "technology" }, { "target": 1, "source": 0, "relation": "trainee" }, { "target": 2, "source": 0, "relation": "manager" }, { "target": 3, "source": 0, "relation": "technology" }, { "target": 2, "source": 4, "relation": "expert" }, { "target": 2, "source": 5, "relation": "expert" }, { "target": 1, "source": 5, "relation": "expert" }, { "target": 6, "source": 5, "relation": "trainee" }, { "target": 7, "source": 5, "relation": "technology;new firm" }, { "target": 8, "source": 4, "relation": "expert" }, { "target": 9, "source": 4, "relation": "new firm" }, { "target": 8, "source": 4, "relation": "expert" }, { "target": 9, "source": 4, "relation": "new firm" }, { "target": 6, "source": 5, "relation": "trainee" }, { "target": 7, "source": 5, "relation": "technology;new firm" }] }; var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); var graph = root; var w = window, d = document, e = d.documentelement, g = d.getelementsbytagname('body')[0], x = w.innerwidth || e.clientwidth || g.clientwidth, y = w.innerheight || e.clientheight || g.clientheight; var realwidth = width; var width = x; var height = y; var img_w = 24; var img_h = 24; var k = math.sqrt(root.nodes.length / (width * height)); var simulation = d3.forcesimulation() .force("link", d3.forcelink().id(function(d) { return d.id; }).distance(200)) .force("charge", d3.forcemanybody().strength(-5 / k)) .force("center", d3.forcecenter(width / 2, height / 2)); 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("image") .attr("width", img_w) .attr("height", img_h) .attr("xlink:href", function(d) { return d.image; }) .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); var links_text = svg.selectall(".linetext") .data(graph.links) .enter() .append("text") .attr("class", "linetext slds-text-heading--small") .attr("text-anchor", "middle") .text(function(d) { return '[' + d.relation + ']'; }); var nodes_text = svg.selectall(".nodetext") .data(graph.nodes) .enter() .append("text") .attr("class", "nodetext slds-text-heading--label") .attr("text-anchor", "middle") .attr("dx", -20) .attr("dy", 20) .text(function(d) { return (d.subname != '' ? (d.subname + ': ') : '') + d.name; }); simulation .nodes(graph.nodes) .on("tick", ticked); simulation.force("link") .links(graph.links); function ticked() { link .attr("x1", function(d) { var xpos = d.source.x; if (xpos < 0) return 0; if (xpos > (960 - img_w)) return (960 - img_w); return xpos; }) .attr("y1", function(d) { var ypos = d.source.y; if (ypos < 0) return 0; if (ypos > (600 - img_h)) return (600 - img_h); return ypos; }) .attr("x2", function(d) { var xpos = d.target.x; if (xpos < 0) return 0; if (xpos > (960 - img_w)) return (960 - img_w); return xpos; }) .attr("y2", function(d) { var ypos = d.target.y; if (ypos < 0) return 0; if (ypos > (600 - img_h)) return (600 - img_h); return ypos; }); links_text .attr("x", function(d) { var xpos = (d.source.x + d.target.x) / 2; if (xpos < 0) return 0; if (xpos > (960 - img_w)) return (960 - img_w); return xpos; }) .attr("y", function(d) { var ypos = (d.source.y + d.target.y) / 2; if (ypos < 0) return 0; if (ypos > (600 - img_h)) return (600 - img_h); return ypos; }); node .attr("x", function(d) { var xpos = (d.x - img_w /2); if (xpos < 0) return 0; if (xpos > (960 - img_w)) return (960 - img_w); return xpos; }) .attr("y", function(d) { var ypos = d.y; if (ypos < 0) return 0; if (ypos > (600 - img_h)) return (600 - img_h); return ypos; }); nodes_text .attr("x", function(d) { return d.x + 20 }) .attr("y", function(d) { return d.y + img_w / 2; }); } 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; } </script> </body> </html>
Comments
Post a Comment