I am trying to get d3 design based on input
MySQL table
value id name parent
A 1 A 0
A 2 A1 1
A 3 A2 1
B 4 B 0
B 5 B1 4
php code to get mysql data into json format to use in d3
UPDATED PHP AND JSON RESULT BASED ON #Z-BONE ANSWER
index.php
<?php
if(isset($_GET['input']))
{
$con=mysqli_connect("localhost","root","admin321","php");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$name=$_GET['input'];
$sql="SELECT * FROM tab where value LIKE '%".$name."%'";
$r = mysqli_query($con,$sql);
$data = array();
while($row = mysqli_fetch_assoc($r)) {
$data[] = $row;
}
function buildtree($src_arr, $parent_id = 0, $tree = array())
{
foreach($src_arr as $idx => $row)
{
if($row['parent'] == $parent_id)
{
foreach($row as $k => $v)
$tree[$row['id']][$k] = $v;
unset($src_arr[$idx]);
$tree[$row['id']]['children'] = buildtree($src_arr, $row['id']);
}
}
ksort($tree);
return $tree;
}
function insertIntoNestedArray(&$array, $searchItem){
if($searchItem['parent'] == 0){
array_push($array, $searchItem);
return;
}
if(empty($array)){ return; }
array_walk($array, function(&$item, $key, $searchItem){
if($item['id'] == $searchItem['parent']){
array_push($item['children'], $searchItem);
return;
}
insertIntoNestedArray($item['children'], $searchItem);
}, $searchItem);
}
$nestedArray = array();
foreach($data as $itemData){
$nestedArrayItem['id'] = $itemData['id'];
$nestedArrayItem['name'] = $itemData['name'];
$nestedArrayItem['parent'] = $itemData['parent'];
$nestedArrayItem['children'] = array();
insertIntoNestedArray($nestedArray, $nestedArrayItem);
}
header('Content-Type: application/json');
$json= json_encode($nestedArray);
echo $json ;
}
?>
json result from PHP is below based on my input (B)
[
{
"id":"4",
"name":"B",
"parent":"0",
"children":[
{
"id":"5",
"name":"B1",
"parent":"4",
"children":[
]
}
]
}
]
BEFORE UPDATE PHP AND JSON RESULT IS as here - http://pastebin.com/409DfSuQ
I used
echo $json = substr($json, 1, -1);
here ,to remove the first and last brackets which give "cannot read property of foreach"error in D3.
draw.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title> draw</title>
</head>
<body>
<form name="vinform"method="get">
<input type="text" name="input">
<input type="submit" value="Show" id="display">
</form>
<div id="content">
</div>
</body>
</html>
if I run this code with
<form name="vinform"method="get"action="index.php">
the output is A valid json..and i also tried copying this json into a separate file and used in d3...that works fine...
but the problem is when i used the draw.html file with
<form name="vinform"method="get"action="index.html">
it shows this
and this error take me to this line in index.html
d3.json("index.php", function(error,flare) {
if (error) throw error; //shows Unexpected end of json input
my index.html is
<!DOCTYPE html>
<html>
<head>
<title>Radial Cluster Demo</title>
<script src="//d3js.org/d3.v3.min.js"></script>
<style>
.node {
cursor: pointer;
}
.overlay {
background-color:white;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: sans-serif;
font-size: 80%;
text-align: center;
}
.link {
fill: none;
}
.parent{
fill :red;
}
div#tooltip {
position: absolute;
font: 15px sans-serif;
background: orange;
border-radius: 8px;
padding-left: 5px;
padding-right: 5px;
pointer-events: none;
}
</style>
</head>
<body>
<div id="tooltip" style="display:none"></div>
<div id="tree-container"class="full"></div>
<script type="text/javascript">
var selectedNode = null;
var draggingNode = null;
var panSpeed = 200;
var panBoundary = 0;
var i = 0;
var duration = 750;
var root;
var width = 5000;
var height = 5000;
var diameter = 750;
var tree = d3.layout.tree().size([360, diameter / 2 - 120])
.separation(function (a, b) {
return (a.parent == b.parent ? 1 : 5) / a.depth;
});
var diagonal = d3.svg.diagonal.radial()
.projection(function (d) {
return [d.y, d.x / 180 * Math.PI];
});
d3.select(self.frameElement).style("height", width);
function sortTree() {
tree.sort(function (a, b) {
return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
});
}
sortTree();
var baseSvg = d3.select("#tree-container").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "overlay")
.attr("transform", "translate(" + 1000 + "," + 1000 + ")");
function expand(d) {
if (d._children) {
d.children = d._children;
d.children.forEach(expand);
d._children = null;
}
}
d3.json("index.php", function(error,flare) {
if (error) throw error;
root = flare;
root.x0 = height / 2;
root.y0 = 0;
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
update(d);
}
flare.children.forEach(collapse);
update(root);
function toggleChildren(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else if (d._children) {
d.children = d._children;
d._children = null;
}
return d;
}
function click(d) {
if (!d.children)
root.children.forEach(collapse);
//d.children = d._children;
// d._children = null;
if (d3.event.defaultPrevented) return;
d = toggleChildren(d);
update(d);
}
function update(source) {
var levelWidth = [1];
var childCount = function (level, n) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) levelWidth.push(0);
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (d) {
childCount(level + 1, d);
});
}
};
childCount(0, root);
var nodes = tree.nodes(root);
links = tree.links(nodes);
node = svgGroup.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.on('click', click);
nodeEnter.append("circle")
.attr("class", "smallcircle")
.style("stroke", function(d) { return d.color;});
nodeEnter.append("text")
.text(function (d) { return d.name; })
// .style("font", "12px serif")
.style("opacity", 1)
.style("fill-opacity", 0)
.on("mouseover", function (d) {
var r = d3.select(this).node().getBoundingClientRect();
d3.select("div#tooltip")
.style("display", "inline")
.style("top", (r.top-25) + "px")
.style("top", 10 + "px")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 40) + "px")
.style("left", r.left + 40+"px")
.style("left", + "px")
.style("position", "absolute")
.text(d.t);
})
.on("mouseout", function(){
d3.select("div#tooltip").style("display", "none")
});
node.select("circle.nodeCircle")
.attr("r", 4.5)
.style("fill", function (d) { return d._children ? "red" : "#fff"; });
// });
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function (d) { return
"rotate(" + (d.x - 90) + ")translate
(" + d.y + ")rotate(" + (-d.x + 90) + ")"; });
nodeUpdate.select("circle").attr("r", 4.5)
.style("fill", function (d) {return d._children ?
"lightsteelblue" : "#fff";});
nodeUpdate.select("text")
.style("fill-opacity", 4)
.attr("fill",function(d){return (d.children?"red":"black");})
.attr("stroke-width",function(d)
{return (d.children?"4":"1");})
.attr("stroke-width",function(d)
{return (d.children?"4 px":"1 px");})
.attr("dy", ".35em")
.attr("text-anchor", function (d) {
return d.x < 180 ? "start" : "end";
})
.attr("transform", function (d) {
return d.x < 180 ? "translate(8)" : "rotate(360)translate(-8)";
});
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + source.x + "," + source.y + ")"; })
.remove();
nodeExit.select("circle")
.attr("r", 0);
nodeExit.select("text")
.style("fill-opacity", 0);
var link = svgGroup.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
})
link.style("stroke", function(d) {
return d.color;
})
link.enter().insert("path", "g")
.attr("class", "link")
link.style("stroke", function(d) {
return d.target.color;
})
.attr("d", function (d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
link.transition()
.duration(duration)
.attr("d", diagonal);
link.exit().transition()
.duration(duration)
.attr("d", function (d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
})
.remove();
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
});
var svgGroup = baseSvg.append("g")
.attr("transform", "translate(" + 550 + "," + 300 + ")");
d3.selectAll("text").style("fill", function (d)
{ return d3.select(this).classed(d.cond, true); });
</script>
</body>
</html>
Any idea about this problem???
In your PHP file:
You are overriding content type json with HTML... Remove this line header('Content-Type: text/html; charset=utf-8'); and leave the line before it which declares json...
Also why are you removing the root brackets with this line: echo $json = substr($json, 1, -1);? It will make json invalid.. Just echo the JSON encoded array as is..
Related
How can I wrap text inside each node making the node automatically resize, just as in css you would do with fit-content or display flex?
Here's the snippet, available at this link: https://codepen.io/boxxello/pen/XWYvRQO
or here:
css:
html, body {
margin: 0;
padding: 0;
background-color: rgb(140, 149, 226);
}
.node {
cursor: pointer;
}
.node circle {
}
.node-leaf {
}
.node text {
font: 10px sans-serif;
}
.link {
fill: none;
stroke: rgb(55, 68, 105);
stroke-width: 1px;
}
js:
var margin = {top: 20, right: 90, bottom: 30, left: 90},
width = 1300 - margin.left - margin.right,
height = 900 - margin.top - margin.bottom;
var svg = d3
.select("body")
.append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var i = 0,
duration = 750,
root;
var treemap = d3.tree().size([height, width]);
root = d3.hierarchy(treeData, function (d) {
return d.children;
});
root.x0 = height / 2;
root.y0 = 0;
root.children.forEach(collapse);
update(root);
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
function update(source) {
var treeData = treemap(root);
var nodes = treeData.descendants(),
links = treeData.descendants().slice(1);
nodes.forEach(function (d) {
d.y = d.depth * 180;
});
var node = svg.selectAll("g.node").data(nodes, function (d) {
return d.id || (d.id = ++i);
});
var nodeEnter = node
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", click);
nodeEnter
.attr("class", "node")
.attr("r", 1e-6)
.style("display", function (d) {
if (d.depth === 0) { //Is top root
return 'none';
}
});
nodeEnter
.append("rect")
.attr("rx", function (d) {
if (d.parent) return d.children || d._children ? 0 : 6;
return 10;
})
.attr("ry", function (d) {
if (d.parent) return d.children || d._children ? 0 : 6;
return 10;
})
.attr("stroke-width", function (d) {
return d.parent ? 1 : 0;
})
.attr("stroke", function (d) {
return d.children || d._children
? "rgb(3, 192, 220)"
: "rgb(38, 222, 176)";
})
.attr("stroke-dasharray", function (d) {
return d.children || d._children ? "0" : "2.2";
})
.attr("stroke-opacity", function (d) {
return d.children || d._children ? "1" : "0.6";
})
.attr("x", 0)
.attr("y", -10)
.attr("width", function (d) {
return d.parent ? 40 : 20;
})
.attr("height", 20)
.classed("node-leaf", true);
nodeEnter
.append("text")
.style("fill", function (d) {
if (d.parent) {
return d.children || d._children ? "#ffffff" : "rgb(38, 222, 176)";
}
return "rgb(39, 43, 77)";
})
.attr("dy", ".35em")
.attr("x", function (d) {
return d.parent ? 20 : 10;
})
.attr("text-anchor", function (d) {
return "middle";
})
.text(function (d) {
return d.data.name;
});
var nodeUpdate = nodeEnter.merge(node);
nodeUpdate
.transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
});
var nodeExit = node
.exit()
.transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("rect").style("opacity", 1e-6);
nodeExit.select("rect").attr("stroke-opacity", 1e-6);
nodeExit.select("text").style("fill-opacity", 1e-6);
var link = svg.selectAll("path.link").data(links, function (d) {
return d.id;
});
var linkEnter = link
.enter()
.insert("path", "g")
.attr("class", "link")
.attr("d", function (d) {
var o = {x: source.x0, y: source.y0};
return diagonal(o, o);
}).style("display", function (d) {
if (d.depth === 1) { //Is top link
return 'none';
}
})
var linkUpdate = linkEnter.merge(link);
linkUpdate
.transition()
.duration(duration)
.attr("d", function (d) {
return diagonal(d, d.parent);
});
var linkExit = link
.exit()
.transition()
.duration(duration)
.attr("d", function (d) {
var o = {x: source.x, y: source.y};
return diagonal(o, o);
})
.remove();
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
function diagonal(s, d) {
path = `M ${s.y} ${s.x}
C ${(s.y + d.y) / 2} ${s.x},
${(s.y + d.y) / 2} ${d.x},
${d.y} ${d.x}`;
return path;
}
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
}
The part where you could change the style property is at:
.attr("width", function (d) {
return d.parent ? 40 : 20;
})
.attr("height", 20)
.classed("node-leaf", true);
Or at least is where I've tried to deal with it. The current version I'm using of d3js is the 4.2.2, I actually used this version it fitted my needs (found the snippet online and there have been breaking changes in the 7.* which is the current version) not because I didn't want to upgrade it (if it's easier in the newer versions please let me know.
This is an expected output, as you can see the node basically fits all the text inside it (I left the parent nodes blank because they're not relevant in this case, but they would need to do the same thing, so applying a property to all the nodes would be great.
So d3.js i am using to display a nodes diagram. right now parent start form left and children on right. is there any way to invert that direction so that children on left and parent on right.
Below is the function render tree which will display tree node. I call renderTree for example like vm.renderTree(vm.tree, "#tree-container");
vm.renderTree = function (treeData, treeId) {
var totalNodes = 0;
var maxLabelLength = 0;
var selectedNode = null;
var draggingNode = null;
var panSpeed = 200;
var panBoundary = 20;
var i = 0;
var duration = 750;
var root;
var viewerWidth = $(document).width();
var viewerHeight = $(document).height();
vm.tree = d3.layout.tree()
.size([viewerHeight, viewerWidth]);
var diagonal = d3.svg.diagonal()
.projection(function (d) {
return [d.y, d.x];
});
function visit(parent, visitFn, childrenFn) {
if (!parent)
return;
visitFn(parent);
var children = childrenFn(parent);
if (children) {
var count = children.length;
for (var i = 0; i < count; i++) {
visit(children[i], visitFn, childrenFn);
}
}
}
visit(treeData, function (d) {
totalNodes++;
if (typeof d.lename !== "undefined") {
if (treeId == "#tree-container-legalTree") {
maxLabelLength = Math.max(d.lename.length, maxLabelLength);
}
else {
maxLabelLength = Math.max(d.name.length, maxLabelLength);
}
}
}, function (d) {
return d.children && d.children.length > 0 ? d.children : null;
});
var sortTree = function () {
vm.tree.sort(function (a, b) {
if (typeof d !== "undefined") {
if (treeId == "#tree-container-legalTree") {
return b.lename.toLowerCase() < a.lename.toLowerCase() ? 1 : -1;
}
else {
return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
}
}
});
};
sortTree();
var pan = function (domNode, direction) {
var speed = panSpeed;
if (panTimer) {
clearTimeout(panTimer);
var translateCoords = d3.transform(svgGroup.attr("transform"));
if (direction == 'left' || direction == 'right') {
translateX = direction == 'left' ? translateCoords.translate[0] + speed : translateCoords.translate[0] - speed;
translateY = translateCoords.translate[1];
}
else if (direction == 'up' || direction == 'down') {
translateX = translateCoords.translate[0];
translateY = direction == 'up' ? translateCoords.translate[1] + speed : translateCoords.translate[1] - speed;
}
scaleX = translateCoords.scale[0];
scaleY = translateCoords.scale[1];
scale = zoomListener.scale();
svgGroup.transition().attr("transform", "translate(" + translateX + "," + translateY + ")scale(" + scale + ")");
d3.select(domNode).select('g.node').attr("transform", "translate(" + translateX + "," + translateY + ")");
zoomListener.scale(zoomListener.scale());
zoomListener.translate([translateX, translateY]);
panTimer = setTimeout(function () {
pan(domNode, speed, direction);
}, 50);
}
};
function zoom() {
svgGroup.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
var zoomListener = d3.behavior.zoom().scaleExtent([0.1, 3]).on("zoom", zoom);
var initiateDrag = function (d, domNode) {
draggingNode = d;
d3.select(domNode).select('.ghostCircle').attr('pointer-events', 'none');
d3.selectAll('.ghostCircle').attr('class', 'ghostCircle show');
d3.select(domNode).attr('class', 'node activeDrag');
svgGroup.selectAll("g.node").sort(function (a, b) {
if (a.id != draggingNode.id)
return 1;
else
return -1;
});
if (nodes.length > 1) {
links = vm.tree.links(nodes);
nodePaths = svgGroup.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
}).remove();
nodesExit = svgGroup.selectAll("g.node")
.data(nodes, function (d) {
return d.id;
}).filter(function (d, i) {
if (d.id == draggingNode.id) {
return false;
}
return true;
}).remove();
}
parentLink = vm.tree.links(vm.tree.nodes(draggingNode.parent));
svgGroup.selectAll('path.link').filter(function (d, i) {
if (d.target.id == draggingNode.id) {
return true;
}
return false;
}).remove();
dragStarted = null;
};
var baseSvg = d3.select(treeId).append("svg")
.attr("width", viewerWidth)
.attr("height", viewerHeight)
.attr("class", "overlay")
.call(zoomListener);
dragListener = d3.behavior.drag()
.on("dragstart", function (d) {
if (d == root) {
return;
}
dragStarted = true;
nodes = vm.tree.nodes(d);
d3.event.sourceEvent.stopPropagation();
})
.on("drag", function (d) {
if (d == root) {
return;
}
if (dragStarted) {
domNode = vm;
initiateDrag(d, domNode);
}
var relCoords = d3.mouse($('svg').get(0));
if (relCoords[0] < panBoundary) {
panTimer = true;
pan(vm, 'left');
}
else if (relCoords[0] > ($('svg').width() - panBoundary)) {
panTimer = true;
pan(vm, 'right');
}
else if (relCoords[1] < panBoundary) {
panTimer = true;
pan(vm, 'up');
}
else if (relCoords[1] > ($('svg').height() - panBoundary)) {
panTimer = true;
pan(vm, 'down');
}
else {
try {
clearTimeout(panTimer);
}
catch (e) {
}
}
d.x0 += d3.event.dy;
d.y0 += d3.event.dx;
var node = d3.select(vm);
node.attr("transform", "translate(" + d.y0 + "," + d.x0 + ")");
updateTempConnector();
}).on("dragend", function (d) {
if (d == root) {
return;
}
domNode = vm;
if (selectedNode) {
var index = draggingNode.parent.children.indexOf(draggingNode);
if (index > -1) {
draggingNode.parent.children.splice(index, 1);
}
if (typeof selectedNode.children !== 'undefined' || typeof selectedNode._children !== 'undefined') {
if (typeof selectedNode.children !== 'undefined') {
selectedNode.children.push(draggingNode);
}
else {
selectedNode._children.push(draggingNode);
}
}
else {
selectedNode.children = [];
selectedNode.children.push(draggingNode);
}
expand(selectedNode);
sortTree();
endDrag();
}
else {
endDrag();
}
});
function endDrag() {
selectedNode = null;
d3.selectAll('.ghostCircle').attr('class', 'ghostCircle');
d3.select(domNode).attr('class', 'node');
d3.select(domNode).select('.ghostCircle').attr('pointer-events', '');
updateTempConnector();
if (draggingNode !== null) {
update(root);
centerNode(draggingNode);
draggingNode = null;
}
}
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
}
function expand(d) {
if (d._children) {
d.children = d._children;
d.children.forEach(expand);
d._children = null;
}
}
var overCircle = function (d) {
selectedNode = d;
updateTempConnector();
};
var outCircle = function (d) {
selectedNode = null;
updateTempConnector();
};
var updateTempConnector = function () {
var data = [];
if (draggingNode !== null && selectedNode !== null) {
data = [{
source: {
x: selectedNode.y0,
y: selectedNode.x0
},
target: {
x: draggingNode.y0,
y: draggingNode.x0
}
}];
}
var link = svgGroup.selectAll(".templink").data(data);
link.enter().append("path")
.attr("class", "templink")
.attr("d", d3.svg.diagonal())
.attr('pointer-events', 'none');
link.attr("d", d3.svg.diagonal());
link.exit().remove();
};
function centerNode(source) {
scale = zoomListener.scale();
x = -source.y0;
y = -source.x0;
x = 150;
y = y * scale + viewerHeight / 2;
d3.select('g').transition()
.duration(duration)
.attr("transform", "translate(" + x + "," + y + ")scale(" + scale + ")");
zoomListener.scale(scale);
zoomListener.translate([x, y]);
}
function toggleChildren(d) {
if (d.children) {
d._children = d.children;
d.children = null;
}
else if (d._children) {
d.children = d._children;
d._children = null;
}
return d;
}
function click(d) {
if (d3.event.defaultPrevented)
return;
d = toggleChildren(d);
update(d);
centerNode(d);
}
var update = function (source) {
var levelWidth = [1];
var childCount = function (level, n) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1)
levelWidth.push(0);
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (d) {
childCount(level + 1, d);
});
}
};
childCount(0, root);
var newHeight = d3.max(levelWidth) * 25;
vm.tree = vm.tree.size([newHeight, viewerWidth]);
var nodes = vm.tree.nodes(root).reverse(), links = vm.tree.links(nodes);
nodes.forEach(function (d) {
d.y = (d.depth * (maxLabelLength * 10));
});
node = svgGroup.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
var nodeEnter = node.enter().append("g")
.call(dragListener)
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on('click', click);
nodeEnter.append("circle")
.attr('class', 'nodeCircle')
.attr("r", 0)
.style("fill", function (d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("x", function (d) {
return d.children || d._children ? -10 : 10;
})
.attr("dy", ".35em")
.attr('class', 'nodeText')
.attr("text-anchor", function (d) {
return d.children || d._children ? "end" : "start";
})
.text(function (d) {
if (vm.showName == "LE Name") {
if (treeId == "#tree-container-legalTree") {
return d.lename;
}
return d.name;
}
})
.style("fill-opacity", 0);
nodeEnter.append("circle")
.attr('class', 'ghostCircle')
.attr("r", 30)
.attr("opacity", 0.2)
.style("fill", "red")
.attr('pointer-events', 'mouseover')
.on("mouseover", function (node) {
overCircle(node);
})
.on("mouseout", function (node) {
outCircle(node);
});
node.select('text')
.attr("x", function (d) {
return d.children || d._children ? -10 : 10;
})
.attr("text-anchor", function (d) {
return d.children || d._children ? "end" : "start";
})
.text(function (d) {
if (vm.showName == "LE Name") {
if (treeId == "#tree-container-legalTree") {
return d.lename;
}
return d.name;
}
});
node.select("circle.nodeCircle")
.attr("r", 4.5)
.style("fill", function (d) {
return d._children ? "lightsteelblue" : "#fff";
});
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + d.y + "," + d.x + ")";
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 0);
nodeExit.select("text")
.style("fill-opacity", 0);
var link = svgGroup.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
});
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function (d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
link.transition()
.duration(duration)
.attr("d", diagonal);
link.exit().transition()
.duration(duration)
.attr("d", function (d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
})
.remove();
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
};
var svgGroup = baseSvg.append("g");
root = treeData;
root.x0 = viewerHeight / 2;
root.y0 = 0;
update(root);
centerNode(root);
};
and below is example of treeData
{
"id": 1,
"code": "a",
"name": "b",
"type": "t",
"leId": 2,
"leName": "d",
"children": [
{
"id": 2,
"code": "e",
"name": "f",
"type": "g",
"leId": 4,
"lename": "e",
"childrenCount": 0
}
],
"childrenCount": 1
}
Here is a snippet of a tree with inverse direction.
Replace d.y with height - d.y, swap positionning of text (start / end) and modify call of diagonal for links:
var data = [
{ "name" : "Level 2: A", "parent":"Top Level" },
{ "name" : "Top Level", "parent":"null" },
{ "name" : "Son of A", "parent":"Level 2: A" },
{ "name" : "Daughter of A", "parent":"Level 2: A" },
{ "name" : "Level 2: B", "parent":"Top Level" }
];
// *********** Convert flat data into a nice tree ***************
// create a name: node map
var dataMap = data.reduce(function(map, node) {
map[node.name] = node;
return map;
}, {});
// create the tree array
var treeData = [];
data.forEach(function(node) {
// add to parent
var parent = dataMap[node.parent];
if (parent) {
// create child array if it doesn't exist
(parent.children || (parent.children = []))
// add node to child array
.push(node);
} else {
// parent is null or missing
treeData.push(node);
}
});
// ************** Generate the tree diagram *****************
var margin = {top: 20, right: 120, bottom: 20, left: 120},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var i = 0;
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = treeData[0];
update(root);
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse(),
links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
// Declare the nodes…
var node = svg.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter the nodes.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + (height - d.y) + "," + d.x + ")"; });
nodeEnter.append("circle")
.attr("r", 10)
.style("fill", "#fff");
nodeEnter.append("text")
.attr("x", function(d) {
return d.children || d._children ? 13 : -13; })
.attr("dy", ".35em")
.attr("text-anchor", function(d) {
return d.children || d._children ? "start" : "end"; })
.text(function(d) { return d.name; })
.style("fill-opacity", 1);
// Declare the links…
var link = svg.selectAll("path.link")
.data(links, function(d) { return d.target.id; });
// Enter the links.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", d => {
console.log(d);
const source = {x: d.source.x, y: height - d.source.y};
const target = {x: d.target.x, y: height - d.target.y};
return diagonal({source, target});
//diagonal({x: d.x, y: height - d.y})
});
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 3px;
}
.node text { font: 12px sans-serif; }
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.7/d3.min.js"></script>
i am working in d3 ,rotating cluster layout ..i want to resize the cluster layout based on number of child nodes..
based on my code ,when i open the parent with minimum child ,there is no problem
when i open a parent that contains more child,there is some overlapping ,so want to reduce the cluster size further,when there is more number of child in the parent...how can i do this??
my entire code is
myJSON= http://pastebin.com/vZ32jGQc
treeData = myJSON;
var selectedNode = null;
var draggingNode = null;
var panSpeed = 200;
var panBoundary = 0;
var i = 0;
var duration = 750;
var root;
var width = 5000;
var height = 5000;
var diameter = 750;
var tree = d3.layout.tree().size([360, diameter / 2 - 120])
.separation(function (a, b) {
return (a.parent == b.parent ? 1 : 5) / a.depth;
});
var diagonal = d3.svg.diagonal.radial()
.projection(function (d) {
return [d.y, d.x / 180 * Math.PI];
});
root = treeData;
root.x0 = height / 2;
root.y0 = 0;
function sortTree() {
tree.sort(function (a, b) {
return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
});
}
sortTree();
var baseSvg = d3.select("#tree-container").append("svg")
.attr("width", 1200)
.attr("height",1200)
.attr("class", "overlay")
.attr("transform", "translate(" + 1000 + "," + 1000 + ")");
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
update(d);
}
function expand(d) {
if (d._children) {
d.children = d._children;
d.children.forEach(expand);
d._children = null;
}
}
function toggleChildren(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else if (d._children) {
d.children = d._children;
d._children = null;
}
return d;
}
function click(d) {
if(!d.parent){
return;
}
if (!d.children)
myJSON.children.forEach(collapse);
if (d3.event.defaultPrevented) return;
d = toggleChildren(d);
update(d);
}
function update(source) {
var levelWidth = [1];
var childCount = function (level, n) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) levelWidth.push(0);
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (d) {
childCount(level + 1, d);
});
}
};
childCount(0, root);
var nodes = tree.nodes(root);
links = tree.links(nodes);
node = svgGroup.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.on('click', click)
nodeEnter.append("circle")
.attr("class", "smallcircle")
.style("stroke", function(d) {
return d.color;
})
nodeEnter.append("text")
.text(function (d) {
return d.name;
})
// .style("font", "12px serif")
.style("opacity", 1)
.style("fill-opacity", 0)
.on("mouseover", function (d) {
var r = d3.select(this).node().getBoundingClientRect();
d3.select("div#tooltip")
.style("display", "inline")
.style("top", (r.top-25) + "px")
.style("top", 10 + "px")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 40) + "px")
.style("left", r.left + 40+"px")
.style("left", + "px")
.style("position", "absolute")
.text(d.t);
})
.on("mouseout", function(){
d3.select("div#tooltip").style("display", "none")
})
node.select("circle.nodeCircle")
.attr("r", 4.5)
.style("fill", function (d) {
return d._children ? "red" : "#fff";
});
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function (d) {
return "rotate(" + (d.x - 90) + ")
translate(" + d.y + ")rotate(" + (-d.x + 90) + ")";
});
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function (d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", 9)
.attr("fill",function(d){return (d.children?"red":"black");})
.attr("font-size",function(d)
{return (d.children?"20px":"12px");})
.attr("dy", ".35em")
.attr("text-anchor", function (d) {
return d.x < 180 ? "start" : "end";
})
.attr("transform", function (d) {
return d.x < 180 ? "translate(8)"
: "rotate(360)translate(-8)";
});
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + source.x + "," + source.y + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 0);
nodeExit.select("text")
.style("fill-opacity", 0);
var link = svgGroup.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
})
link.style("stroke", function(d) {
return d.color;
})
link.enter().insert("path", "g")
.attr("class", "link")
link.style("stroke", function(d) {
return d.target.color;
})
.attr("d", function (d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
});
link.transition()
.duration(duration)
.attr("d", diagonal);
link.exit().transition()
.duration(duration)
.attr("d", function (d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
var svgGroup = baseSvg.append("g")
.attr("transform", "translate(" + 550 + "," + 300 + ")")
d3.selectAll("text").style("fill", function (d)
{ return d3.select(this).classed(d.cond, true); })
root.children.forEach(function (child) {
collapse(child);
});
update(root);
d3.select(self.frameElement).style("height", width);
i tried to add php output in html for d3.for testing purpose i tried with simple code
index.html
<!DOCTYPE html>
<html>
<head>
<title>including php in javascript</title>
<?
include ('index.php');
?>
</head>
<body>
<script>
var myJSON = <?php echo json_encode($json); ?>;
document.write(myJSON);
</script>
</body>
</html>
another method to add the external file to d3
<!DOCTYPE html>
<html>
<head>
<title>Radial Cluster Demo</title>
<script src="ddd.js"></script>
<style>
.node {
cursor: pointer;
}
.overlay {
background-color:white;
}
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: sans-serif;
text-align: center;
}
.link {
fill: none;
}
.parent{
fill :red;
font-weight:bolder
}
div#tooltip {
position: absolute;
font: 15px sans-serif;
background: orange;
border-radius: 8px;
padding-left: 5px;
padding-right: 5px;
pointer-events: none;
}
</style>
</head>
<body>
<div id="tooltip" style="display:none"></div>
<div id="tree-container"class="full"></div>
<script type="text/javascript">
d3.json("http://localhost:8888/new/new.json",function(treeData){
var selectedNode = null;
var draggingNode = null;
var panSpeed = 200;
var panBoundary = 0;
var i = 0;
var duration = 750;
var root;
var width = 5000;
var height = 5000;
var diameter = 750;
var tree = d3.layout.tree().size([360, diameter / 2 - 120])
.separation(function (a, b) {
return (a.parent == b.parent ? 1 : 5) / a.depth;
});
var diagonal = d3.svg.diagonal.radial()
.projection(function (d) {
return [d.y, d.x / 180 * Math.PI];
});
root = treeData;
root.x0 = height / 2;
root.y0 = 0;
function sortTree() {
tree.sort(function (a, b) {
return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
});
}
sortTree();
var baseSvg = d3.select("#tree-container").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "overlay")
.attr("transform", "translate(" + 1000 + "," + 1000 + ")");
function collapse(d) {
if (d.children) {
d._children = d.children;
d._children.forEach(collapse);
d.children = null;
}
update(d);
}
function expand(d) {
if (d._children) {
d.children = d._children;
d.children.forEach(expand);
d._children = null;
}
}
function toggleChildren(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else if (d._children) {
d.children = d._children;
d._children = null;
}
return d;
}
function click(d) {
if(!d.parent){
return;
}
if (!d.children)
treeData.children.forEach(collapse);
if (d3.event.defaultPrevented) return;
d = toggleChildren(d);
update(d);
}
function update(source) {
var levelWidth = [1];
var childCount = function (level, n) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) levelWidth.push(0);
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (d) {
childCount(level + 1, d);
});
}
};
childCount(0, root);
var nodes = tree.nodes(root);
links = tree.links(nodes);
node = svgGroup.selectAll("g.node")
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.on('click', click)
nodeEnter.append("circle")
.attr("class", "smallcircle")
.style("stroke", function(d) {
return d.color;
})
nodeEnter.append("text")
.text(function (d) {
return d.name;
})
// .style("font", "12px serif")
.style("opacity", 1)
.style("fill-opacity", 0)
.on("mouseover", function (d) {
var r = d3.select(this).node().getBoundingClientRect();
d3.select("div#tooltip")
.style("display", "inline")
.style("top", (r.top-25) + "px")
.style("top", 10 + "px")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 40) + "px")
.style("left", r.left + 40+"px")
.style("left", + "px")
.style("position", "absolute")
.text(d.t);
})
.on("mouseout", function(){
d3.select("div#tooltip").style("display", "none")
})
node.select("circle.nodeCircle")
.attr("r", 4.5)
.style("fill", function (d) {
return d._children ? "red" : "#fff";
});
// });
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function (d) {
return "rotate(" + (d.x - 90) + ")translate
(" + d.y + ")rotate(" + (-d.x + 90) + ")";
});
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function (d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
// .style("font-size", "13px")
.style("fill-opacity", 2)
.attr("fill",function(d){return (d.children?"red":"black");})
.attr("dy", ".35em")
.attr("text-anchor", function (d) {
return d.x < 180 ? "start" : "end";
})
.attr("transform", function (d) {
return d.x < 180 ? "translate(8)" : "rotate(360)translate(-8)";
});
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function (d) {
return "translate(" + source.x + "," + source.y + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 0);
nodeExit.select("text")
.style("fill-opacity", 0);
var link = svgGroup.selectAll("path.link")
.data(links, function (d) {
return d.target.id;
})
link.style("stroke", function(d) {
return d.color;
})
link.enter().insert("path", "g")
.attr("class", "link")
link.style("stroke", function(d) {
return d.target.color;
})
.attr("d", function (d) {
var o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
});
link.transition()
.duration(duration)
.attr("d", diagonal);
link.exit().transition()
.duration(duration)
.attr("d", function (d) {
var o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
})
.remove();
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
var svgGroup = baseSvg.append("g")
.attr("transform", "translate(" + 550 + "," + 300 + ")")
d3.selectAll("text").style("fill", function (d)
{ return d3.select(this).classed(d.cond, true); })
root.children.forEach(function (child) {
collapse(child);
});
update(root);
d3.select(self.frameElement).style("height", width);
});
</script>
</body>
</html>
in this method i am getting
Uncaught TypeError: Cannot read property 'forEach' of undefined
where it is wrong?
index.php output
[
{
"id":"1",
"name":"parent",
"parent":"0",
"children":[
{
"id":"2",
"name":"c1",
"parent":"1",
"children":[
{
"id":"3",
"name":"c11",
"parent":"2",
"children":[
]
},
{
"id":"4",
"name":"c12",
"parent":"2",
"children":[
]
}
]
},
{
"id":"5",
"name":"c2",
"parent":"1",
"children":[
{
"id":"6",
"name":"c21",
"parent":"5",
"children":[
]
},
{
"id":"7",
"name":"c22",
"parent":"5",
"children":[
]
}
]
},
{
"id":"8",
"name":"c3",
"parent":"1",
"children":[
]
}
]
}
]
Try addding
header('Content-Type: application/json');
before
$json= json_encode($nestedArray);
echo $json;
To specify that you are returning a json format data
I am very new to d3 and svg, this may sound very naive.
I have one force layout graph and one Circle pack and want to show them both on one page side by side. I went to the "Multiple layouts on same page (multiple force layouts same page)" questions but not able to understand how can I put these layout in div element.
This one is Force layout -
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style>
h3{
border: 1px solid green ;
}
.link {
stroke: #666;
stroke-opacity: 0.1;
stroke-width: 1.5px;
}
.node circle {
stroke: #fff;
opacity: 0.9;
stroke-width: 1.5px;
}
.node:not(:hover) .nodetext {
display: none;
}
text {
font: 17px serif;
opacity: 0.9;
pointer-events: none;
fill : red;
}
</style>
<script src=http://d3js.org/d3.v3.min.js></script>
<script>
var links= [];
var nodes= [];
var width = 800
height = 400;
var color = d3.scale.category20();
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkStrength(0.1)
.linkDistance(150)
.charge(-150)
.friction(0.6)
.gravity(0.5);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("sample1.json", function(error, data) {
nodes = data.nodes;
links = data.links;
force
.nodes(nodes)
.links(links)
.on("tick", tick)
.start();
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(1); });
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.style("fill", "#7a85ec")
.style("opacity", 0.9)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click",clickf)
.call(force.drag);
node.append("circle")
.attr("r", function(d) { return Math.sqrt(3*d.weight); })
node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", "1.35em")
.attr("dy", "-1.35em")
.text(function(d) { return d.name });
function tick() {
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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
function mouseover(d) {
var circle = d3.select(this);
node
.transition(500)
.style("opacity", function(o) {
return isConnected(o, d) ? 1.0 : 0.1 ;
})
.style("fill", function(o){
if (isEqual(o, d)){
return "red"
}
else return "#7a85ec"
})
;
link
.transition(500)
.style("stroke-opacity", function(o) {
return o.source === d || o.target === d ? 1 : 0.1;
})
;
}
function mouseout() {
var circle = d3.select(this);
node
.transition(500)
.style("opacity", "1.0")
.style("fill", "#7a85ec")
;
link
.transition(500)
.style("stroke-opacity", "0.1");
}
function clickf(d){
}
var linkedByIndex = {};
links.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = true;
});
function isConnected(a, b) {
return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) || a.index == b.index;
}
function isConnectedAsSource(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
function isConnectedAsTarget(a, b) {
return linkedByIndex[b.index + "," + a.index];
}
function isEqual(a, b) {
return a.index == b.index;
}
});
</script>
</body>
This is my circle pack (sample from mbostock) -
<!DOCTYPE html>
<meta charset="utf-8">
<style>
circle {
fill: rgb(31, 119, 180);
fill-opacity: .25;
stroke: rgb(31, 119, 180);
stroke-width: 1px;
}
.leaf circle {
fill: #ff7f0e;
fill-opacity: 1;
}
text {
font: 10px sans-serif;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var diameter = 560,
format = d3.format(",d");
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.value(function(d) { return d.size; });
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(2,2)");
d3.json("flare.json", function(error, root) {
var node = svg.datum(root).selectAll(".node")
.data(pack.nodes)
.enter().append("g")
.attr("class", function(d) { return d.children ? "node" : "leaf node"; })
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.name + (d.children ? "" : ": " + format(d.size)); });
node.append("circle")
.attr("r", function(d) { return d.r; });
node.filter(function(d) { return !d.children; }).append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.name.substring(0, d.r / 3); });
});
d3.select(self.frameElement).style("height", diameter + "px");
</script>
Please help me put these in one page using div.
This worked for me with the changes below. Hope this helps.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
#left-div
{
width:560px;
height:560px;
border:1px solid red;
margin:10px;
display:table-cell;
}
#right-div
{
width:560px;
height:560px;
border:1px solid red;
margin:10px;
display:table-cell;
}
circle {
fill: rgb(31, 119, 180);
fill-opacity: .25;
stroke: rgb(31, 119, 180);
stroke-width: 1px;
}
.leaf circle {
fill: #ff7f0e;
fill-opacity: 1;
}
text {
font: 10px sans-serif;
}
</style>
<div id="left-div"></div>
<div id="right-div"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<body>
<script>
var diameter = 560,
format = d3.format(",d");
var pack = d3.layout.pack()
.size([diameter - 4, diameter - 4])
.value(function(d) { return d.size; });
var svg = d3.select("#left-div").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.append("g")
.attr("transform", "translate(2,2)");
d3.json("flare.json", function(error, root) {
var node = svg.datum(root).selectAll(".node")
.data(pack.nodes)
.enter().append("g")
.attr("class", function(d) { return d.children ? "node" : "leaf node"; })
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.name + (d.children ? "" : ": " + format(d.size)); });
node.append("circle")
.attr("r", function(d) { return d.r; });
node.filter(function(d) { return !d.children; }).append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.name.substring(0, d.r / 3); });
});
d3.select(self.frameElement).style("height", diameter + "px");
</script>
<script>
var links= [];
var nodes= [];
var width = 500
height = 500;
var color = d3.scale.category20();
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkStrength(0.1)
.linkDistance(150)
.charge(-150)
.friction(0.6)
.gravity(0.5);
var svg2 = d3.select("#right-div").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("sample1.json", function(error, data) {
nodes = data.nodes;
links = data.links;
force
.nodes(nodes)
.links(links)
.on("tick", tick)
.start();
var link = svg2.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(1); });
var node = svg2.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.style("fill", "#7a85ec")
.style("opacity", 0.9)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click",clickf)
.call(force.drag);
node.append("circle")
.attr("r", function(d) { return Math.sqrt(3*d.weight); })
node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", "1.35em")
.attr("dy", "-1.35em")
.text(function(d) { return d.name });
function tick() {
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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}
function mouseover(d) {
var circle = d3.select(this);
node
.transition(500)
.style("opacity", function(o) {
return isConnected(o, d) ? 1.0 : 0.1 ;
})
.style("fill", function(o){
if (isEqual(o, d)){
return "red"
}
else return "#7a85ec"
})
;
link
.transition(500)
.style("stroke-opacity", function(o) {
return o.source === d || o.target === d ? 1 : 0.1;
})
;
}
function mouseout() {
var circle = d3.select(this);
node
.transition(500)
.style("opacity", "1.0")
.style("fill", "#7a85ec")
;
link
.transition(500)
.style("stroke-opacity", "0.1");
}
function clickf(d){
}
var linkedByIndex = {};
links.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = true;
});
function isConnected(a, b) {
return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) || a.index == b.index;
}
function isConnectedAsSource(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
function isConnectedAsTarget(a, b) {
return linkedByIndex[b.index + "," + a.index];
}
function isEqual(a, b) {
return a.index == b.index;
}
});
</script>
Note, some of the CSS was left out from one of the graphs. Adjust that as needed. The key to getting the d3 graph to load into a div is by this code below. Notice the # within the string name of the div id.
var svg = d3.select("#left-div").append("svg")
Instead of this code below.
var svg = d3.select("body").append("svg")
The next issue that I ran into was due to a duplicate var named "svg" between both scripts, so I renamed one of them to svg2.