How to get values of selected nodes in the console in D3 - javascript
I have an application where i need to make a mesh using D3.and i also need to get their values .So my application have the ability of selection using mouse drag and now i need its values in the console. here it is...
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.node .selected {
stroke: red;
}
.link {
stroke: #999;
}
.brush .extent {
fill-opacity: .1;
stroke: #fff;
shape-rendering: crispEdges;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
shiftKey;
var svg = d3.select("body")
.attr("tabindex", 1)
.on("keydown.brush", keyflip)
.on("keyup.brush", keyflip)
.each(function() { this.focus(); })
.append("svg")
.attr("width", width)
.attr("height", height);
d3.json("graph.json", function(error, graph) {
graph.links.forEach(function(d) {
d.source = graph.nodes[d.source];
d.target = graph.nodes[d.target];
});
var link = svg.append("g")
.attr("class", "link")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.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; });
var brush = svg.append("g")
.datum(function() { return {selected: false, previouslySelected: false}; })
.attr("class", "brush")
.call(d3.svg.brush()
.x(d3.scale.identity().domain([0, width]))
.y(d3.scale.identity().domain([0, height]))
.on("brushstart", function(d) {
node.each(function(d) { d.previouslySelected = shiftKey && d.selected; });
})
.on("brush", function() {
var extent = d3.event.target.extent();
node.classed("selected", function(d) {
return d.selected = d.previouslySelected ^
(extent[0][0] <= d.x && d.x < extent[1][0]
&& extent[0][1] <= d.y && d.y < extent[1][1]);
});
})
.on("brushend", function() {
d3.event.target.clear();
d3.select(this).call(d3.event.target);
}));
var node = svg.append("g")
.attr("class", "node")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 4)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.on("mousedown", function(d) {
if (shiftKey) d3.select(this).classed("selected", d.selected = !d.selected);
else node.classed("selected", function(p) { return p.selected = d === p; });
});
});
function keyflip() {
shiftKey = d3.event.shiftKey || d3.event.metaKey;
}
</script>
And here is the json
{"nodes":[{"x":444,"y":275},{"x":378,"y":324},{"x":478,"y":278},{"x":471,"y":256},{"x":382,"y":269},{"x":371,"y":247},{"x":359,"y":276},{"x":364,"y":302},{"x":400,"y":330},{"x":388,"y":298},{"x":524,"y":296},{"x":570,"y":243},{"x":552,"y":159},{"x":502,"y":287},{"x":511,"y":313},{"x":513,"y":265},{"x":602,"y":132},{"x":610,"y":90},{"x":592,"y":91},{"x":575,"y":89},{"x":607,"y":73},{"x":591,"y":68},{"x":574,"y":73},{"x":589,"y":149},{"x":620,"y":205},{"x":621,"y":230},{"x":589,"y":234},{"x":602,"y":223},{"x":548,"y":188},{"x":532,"y":196},{"x":548,"y":114},{"x":575,"y":174},{"x":497,"y":250},{"x":576,"y":196},{"x":504,"y":201},{"x":494,"y":186},{"x":482,"y":199},{"x":505,"y":219},{"x":486,"y":216},{"x":590,"y":306},{"x":677,"y":169},{"x":657,"y":258},{"x":667,"y":205},{"x":552,"y":227},{"x":518,"y":173},{"x":473,"y":125},{"x":796,"y":260},{"x":731,"y":272},{"x":642,"y":288},{"x":576,"y":269},{"x":605,"y":187},{"x":559,"y":289},{"x":544,"y":356},{"x":505,"y":365},{"x":579,"y":289},{"x":619,"y":282},{"x":574,"y":329},{"x":664,"y":306},{"x":627,"y":304},{"x":643,"y":327},{"x":664,"y":348},{"x":665,"y":327},{"x":653,"y":317},{"x":650,"y":338},{"x":622,"y":321},{"x":633,"y":338},{"x":647,"y":357},{"x":718,"y":362},{"x":636,"y":240},{"x":640,"y":227},{"x":617,"y":249},{"x":631,"y":254},{"x":566,"y":213},{"x":713,"y":322},{"x":716,"y":298},{"x":666,"y":241},{"x":627,"y":355}],"links":[{"source":1,"target":0},{"source":2,"target":0},{"source":3,"target":0},{"source":3,"target":2},{"source":4,"target":0},{"source":5,"target":0},{"source":6,"target":0},{"source":7,"target":0},{"source":8,"target":0},{"source":9,"target":0},{"source":11,"target":10},{"source":11,"target":3},{"source":11,"target":2},{"source":11,"target":0},{"source":12,"target":11},{"source":13,"target":11},{"source":14,"target":11},{"source":15,"target":11},{"source":17,"target":16},{"source":18,"target":16},{"source":18,"target":17},{"source":19,"target":16},{"source":19,"target":17},{"source":19,"target":18},{"source":20,"target":16},{"source":20,"target":17},{"source":20,"target":18},{"source":20,"target":19},{"source":21,"target":16},{"source":21,"target":17},{"source":21,"target":18},{"source":21,"target":19},{"source":21,"target":20},{"source":22,"target":16},{"source":22,"target":17},{"source":22,"target":18},{"source":22,"target":19},{"source":22,"target":20},{"source":22,"target":21},{"source":23,"target":16},{"source":23,"target":17},{"source":23,"target":18},{"source":23,"target":19},{"source":23,"target":20},{"source":23,"target":21},{"source":23,"target":22},{"source":23,"target":12},{"source":23,"target":11},{"source":24,"target":23},{"source":24,"target":11},{"source":25,"target":24},{"source":25,"target":23},{"source":25,"target":11},{"source":26,"target":24},{"source":26,"target":11},{"source":26,"target":16},{"source":26,"target":25},{"source":27,"target":11},{"source":27,"target":23},{"source":27,"target":25},{"source":27,"target":24},{"source":27,"target":26},{"source":28,"target":11},{"source":28,"target":27},{"source":29,"target":23},{"source":29,"target":27},{"source":29,"target":11},{"source":30,"target":23},{"source":31,"target":30},{"source":31,"target":11},{"source":31,"target":23},{"source":31,"target":27},{"source":32,"target":11},{"source":33,"target":11},{"source":33,"target":27},{"source":34,"target":11},{"source":34,"target":29},{"source":35,"target":11},{"source":35,"target":34},{"source":35,"target":29},{"source":36,"target":34},{"source":36,"target":35},{"source":36,"target":11},{"source":36,"target":29},{"source":37,"target":34},{"source":37,"target":35},{"source":37,"target":36},{"source":37,"target":11},{"source":37,"target":29},{"source":38,"target":34},{"source":38,"target":35},{"source":38,"target":36},{"source":38,"target":37},{"source":38,"target":11},{"source":38,"target":29},{"source":39,"target":25},{"source":40,"target":25},{"source":41,"target":24},{"source":41,"target":25},{"source":42,"target":41},{"source":42,"target":25},{"source":42,"target":24},{"source":43,"target":11},{"source":43,"target":26},{"source":43,"target":27},{"source":44,"target":28},{"source":44,"target":11},{"source":45,"target":28},{"source":47,"target":46},{"source":48,"target":47},{"source":48,"target":25},{"source":48,"target":27},{"source":48,"target":11},{"source":49,"target":26},{"source":49,"target":11},{"source":50,"target":49},{"source":50,"target":24},{"source":51,"target":49},{"source":51,"target":26},{"source":51,"target":11},{"source":52,"target":51},{"source":52,"target":39},{"source":53,"target":51},{"source":54,"target":51},{"source":54,"target":49},{"source":54,"target":26},{"source":55,"target":51},{"source":55,"target":49},{"source":55,"target":39},{"source":55,"target":54},{"source":55,"target":26},{"source":55,"target":11},{"source":55,"target":16},{"source":55,"target":25},{"source":55,"target":41},{"source":55,"target":48},{"source":56,"target":49},{"source":56,"target":55},{"source":57,"target":55},{"source":57,"target":41},{"source":57,"target":48},{"source":58,"target":55},{"source":58,"target":48},{"source":58,"target":27},{"source":58,"target":57},{"source":58,"target":11},{"source":59,"target":58},{"source":59,"target":55},{"source":59,"target":48},{"source":59,"target":57},{"source":60,"target":48},{"source":60,"target":58},{"source":60,"target":59},{"source":61,"target":48},{"source":61,"target":58},{"source":61,"target":60},{"source":61,"target":59},{"source":61,"target":57},{"source":61,"target":55},{"source":62,"target":55},{"source":62,"target":58},{"source":62,"target":59},{"source":62,"target":48},{"source":62,"target":57},{"source":62,"target":41},{"source":62,"target":61},{"source":62,"target":60},{"source":63,"target":59},{"source":63,"target":48},{"source":63,"target":62},{"source":63,"target":57},{"source":63,"target":58},{"source":63,"target":61},{"source":63,"target":60},{"source":63,"target":55},{"source":64,"target":55},{"source":64,"target":62},{"source":64,"target":48},{"source":64,"target":63},{"source":64,"target":58},{"source":64,"target":61},{"source":64,"target":60},{"source":64,"target":59},{"source":64,"target":57},{"source":64,"target":11},{"source":65,"target":63},{"source":65,"target":64},{"source":65,"target":48},{"source":65,"target":62},{"source":65,"target":58},{"source":65,"target":61},{"source":65,"target":60},{"source":65,"target":59},{"source":65,"target":57},{"source":65,"target":55},{"source":66,"target":64},{"source":66,"target":58},{"source":66,"target":59},{"source":66,"target":62},{"source":66,"target":65},{"source":66,"target":48},{"source":66,"target":63},{"source":66,"target":61},{"source":66,"target":60},{"source":67,"target":57},{"source":68,"target":25},{"source":68,"target":11},{"source":68,"target":24},{"source":68,"target":27},{"source":68,"target":48},{"source":68,"target":41},{"source":69,"target":25},{"source":69,"target":68},{"source":69,"target":11},{"source":69,"target":24},{"source":69,"target":27},{"source":69,"target":48},{"source":69,"target":41},{"source":70,"target":25},{"source":70,"target":69},{"source":70,"target":68},{"source":70,"target":11},{"source":70,"target":24},{"source":70,"target":27},{"source":70,"target":41},{"source":70,"target":58},{"source":71,"target":27},{"source":71,"target":69},{"source":71,"target":68},{"source":71,"target":70},{"source":71,"target":11},{"source":71,"target":48},{"source":71,"target":41},{"source":71,"target":25},{"source":72,"target":26},{"source":72,"target":27},{"source":72,"target":11},{"source":73,"target":48},{"source":74,"target":48},{"source":74,"target":73},{"source":75,"target":69},{"source":75,"target":68},{"source":75,"target":25},{"source":75,"target":48},{"source":75,"target":41},{"source":75,"target":70},{"source":75,"target":71},{"source":76,"target":64},{"source":76,"target":65},{"source":76,"target":66},{"source":76,"target":63},{"source":76,"target":62},{"source":76,"target":48},{"source":76,"target":58}]}
i need that i will select the nodes using mouse drag as the application is working and the values will come to the console
Related
D3.js network graph
Hi I have this nice network graph going. The node that says "scanner" I am trying to make that radius bigger than the other nodes and I want the scanner to be printed on the node while the other nodes have the hover feature. I am struggling since the nodes have to be linked together in order for it to work cohesively. Thank you in advance, looking forward to how you tackle this issue. var graph = { "nodes":[ {"name":" Scanner","group":1}, {"name":"Chemical 1 ","group":1}, {"name":"Chemical 2","group":1}, {"name":"Chemical 3","group":1}, {"name":"Chemical 4","group":1} ], "links":[ {"source":0,"target":1,"value":1}, {"source":0,"target":2,"value":1}, {"source":0,"target":3,"value":1}, {"source":0,"target":4,"value":1}, {"source":0,"target":0,"value":1} ] }; var width = 1000, height = 1000; var force = d3.layout.force() .charge(-300) .linkDistance(300) .size([width, height]); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var drawGraph = function(graph) { force .nodes(graph.nodes) .links(graph.links) .start(); var link = svg.selectAll(".link") .data(graph.links) .enter().append("line") .attr("class", "link") .style("stroke-width", function(d) { return Math.sqrt(d.value); }); var gnodes = svg.selectAll('g.gnode') .data(graph.nodes) .enter() .append('g') .classed('gnode', true); var node = gnodes.append("circle") .attr("class", "node") .attr("r", 25) .on("mouseover", function(d) { d3.select(labels[0][d.index]).style("visibility","visible") }) .on("mouseout", function(d) { d3.select(labels[0][d.index]).style("visibility","hidden") }) .call(force.drag); var labels = gnodes.append("text") .text(function(d) { return d.name; }) .style("visibility", "hidden"); force.on("tick", function() { 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; }); gnodes.attr("transform", function(d) { return 'translate(' + [d.x, d.y] + ')'; }); }); }; drawGraph(graph); .node { stroke: #fff; stroke-width: 1.5px; } .nodeDetail { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } .text { font: 12px sans-serif; pointer-events: none; } .node { stroke:#fff; stroke-width:3px; fill:#2E8B57; } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
Larger radius for "scanner" circle d3.js selection.attr accepts a function as the second parameter, allowing to set different values according to the data. In this function, you should check whether d.name is "Scanner", and return a radius value accordingly. .attr("r", function(d) { return d.name === 'Scanner'? 40 : 25; }) Always display the label for Scanner Similarly, selection.style setting visibility for labels should be initialized in a function checking data value: .style("visibility", function(d) { return d.name === 'Scanner'? 'visible' : 'hidden'; }); In order to have the mouseover and mouseout event listeners only applying to the other nodes, use selection.filter: .filter(function(d) { return d.name !== 'Scanner'}) .on("mouseover", function(d) // ... Demo The snippet below illustrates the solution. Remark: The leading space character scanner node found in the question has been removed in this demo : "Scanner" instead of " Scanner" var graph = { "nodes":[ {"name":"Scanner","group":1}, {"name":"Chemical 1 ","group":1}, {"name":"Chemical 2","group":1}, {"name":"Chemical 3","group":1}, {"name":"Chemical 4","group":1} ], "links":[ {"source":0,"target":1,"value":1}, {"source":0,"target":2,"value":1}, {"source":0,"target":3,"value":1}, {"source":0,"target":4,"value":1}, {"source":0,"target":0,"value":1} ] }; var width = 1000, height = 1000; var force = d3.layout.force() .charge(-300) .linkDistance(300) .size([width, height]); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var drawGraph = function(graph) { force .nodes(graph.nodes) .links(graph.links) .start(); var link = svg.selectAll(".link") .data(graph.links) .enter().append("line") .attr("class", "link") .style("stroke-width", function(d) { return Math.sqrt(d.value); }); var gnodes = svg.selectAll('g.gnode') .data(graph.nodes) .enter() .append('g') .classed('gnode', true); var node = gnodes.append("circle") .attr("class", "node") .attr("r", function(d) { return d.name === 'Scanner'? 40 : 25; }) .call(force.drag) .filter(function(d) { return d.name !== 'Scanner'}) .on("mouseover", function(d) { d3.select(labels[0][d.index]).style("visibility","visible") }) .on("mouseout", function(d) { d3.select(labels[0][d.index]).style("visibility","hidden") }) var labels = gnodes.append("text") .text(function(d) { return d.name; }) .style("visibility", function(d) { return d.name === 'Scanner'? 'visible' : 'hidden'; }); force.on("tick", function() { 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; }); gnodes.attr("transform", function(d) { return 'translate(' + [d.x, d.y] + ')'; }); }); }; drawGraph(graph); .node { stroke: #fff; stroke-width: 1.5px; } .nodeDetail { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } .text { font: 12px sans-serif; pointer-events: none; } .node { stroke:#fff; stroke-width:3px; fill:#2E8B57; } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
Hide nodes on Mousedown in d3
I have an HTML file that reads a JSON graph file and displays in the browser <!DOCTYPE html> <meta charset="utf-8"> <style> .node { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; stroke-opacity: .6; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var width = 1280, height = 960; var color = d3.scale.category20(); var force = d3.layout.force() .charge(-120) .linkDistance(30) .size([width, height]); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); d3.json("data.json", function(error, graph) { if (error) throw error; force .nodes(graph.nodes) .links(graph.links) .start(); var link = svg.selectAll(".link") .data(graph.links) .enter().append("line") .attr("class", "link") .style("stroke-width", function(d) { return Math.sqrt(d.value); }); var node = svg.selectAll(".node") .data(graph.nodes) .enter().append("circle") .attr("class", "node") .attr("r", 5) .style("fill", function(d) { return color(d.fill); }) .call(force.drag); node.append("title") .text(function(d) { return d.id; }); force.on("tick", function() { 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; }); }); }); </script> I have an attribute for each node called clique_nodes which is a list of nodes that need to displayed on mousedown (hide every other node in the graph on mousedown). How do I do this?
You should attach 'mousedown' event handler to your nodes where you filter the "clique_node" attribute and make their opacity 0. var gnodes = svg.selectAll('g.gnode') .data(graph.nodes) .enter() .append('g') .classed('gnode', true) .attr('clique_node', function(d,i){ if(d.attr === "clique_node"){ return true; } }) .on("mousedown", function(d,i){ d3.selectAll('.gnode').filter(function(d) { if(d.attr !== "clique_node"){return d;} }) .attr("opacity",0); d3.selectAll('.link').filter(function(d) { if(d.source.attr !== "clique_node" || d.target.attr !== "clique_node"){return d;} }) .attr("opacity",0); }); See the fiddle: https://jsfiddle.net/mcm3p2e9/1/
Circle Pack & Force layout on same page?
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.
d3.js move node and label together
In our project I want to add cicrles dynamically when the add node button is clicked and link these circles with an arrow. But When I linked the circles labels of the circles do not move together with circles. The code is below. JS Fiddle Link: http://jsfiddle.net/pinargocebe/kEhes/3/ How can I solve this problem? Thanks in advance.. <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" template="layout/template.xhtml"> <ui:define name="body"> <a4j:commandButton value="Add Node" onclick="mousedown();"> </a4j:commandButton> <div id="activationGraphDiv" style="width: 960px; height: 500px"> </div> <rich:popupPanel id="addnode" width="100" height="100"> <h:form> <h:outputLabel value="http://add.mode.deneme#relation" /> <a4j:commandButton value="OK" onclick="#{rich:component('addnode')}.hide()"> </a4j:commandButton> </h:form> </rich:popupPanel> <style type="text/css"> rect { fill: none; pointer-events: all; } .node { fill: white; stroke: pink; stroke-width: 2; color: black; } .cursor { fill: none; pointer-events: none; } .link { stroke: #999; } path,line { stroke: silver; stroke-width: 2; fill: none; } </style> <script src="jquery.pack.js"></script> <script type="text/javascript"> var width = 960, height = 500; var sourceNode,targetNode; var fill = d3.scale.category20(); var force = d3.layout.force() .size([width, height]) .gravity(.05) .charge(-450) .linkDistance(200) .on("tick", tick); var svg = d3.select("#activationGraphDiv").append("svg") .attr("width", width) .attr("height", height) .on("mousemove", mousemove); svg.append("rect") .attr("width", width) .attr("height", height); // Draw Lines var container = $('#activationGraphDiv'); var line = d3.svg.line() .x(function(d) { return d[0]; }) .y(function(d) { return d[1]; }) .interpolate('linear'); svg .append('svg:path') .style('stroke-width', 1) .style('stroke', 'silver') .style('fill', 'rgba(120, 220, 54, 0.2)'); var lineData = []; var redrawLine = function() { var svgLines = svg.selectAll('path.my-lines') .data(lineData) .remove(); svgLines.enter() .append('path') .attr('d', line(lineData)) .attr('class', 'my-lines'); svgLines.exit() .remove(); }; var mouseIsDown = false; container.on('mousemove', function(e) { if (mouseIsDown && sourceNode!=null) { lineData[1] = [e.offsetX, e.offsetY]; redrawLine(); }}) .on('mouseup',function(){ sourceNode=null; targetNode=null; mouseIsDown=false; svg.selectAll('path.my-lines') .data(lineData) .remove(); }); var nodes = force.nodes(), links = force.links(), node=svg.selectAll(".node"), link = svg.selectAll(".link"), text=svg.selectAll(".nodetext"); var cursor = svg.append("circle") .attr("r", 0) .attr("class", "cursor"); restart(); function mousemove() { cursor.attr("transform", "translate(" + d3.mouse(this) + ")"); } var i=0; function mousedown() { //x coordinate of node.. var x=document.getElementById("activationGraphDiv").offsetLeft; //y coordinate of node.. var y=document.getElementById("activationGraphDiv").offsetTop; var node = {x:x, y: y, name: i}, n = nodes.push(node); i++; console.log("node name: "+node.name); restart(); sourceNode=null targetNode=null; mouseIsDown=false; } 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("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }); text.attr("x", function(d) {return d.x; }) .attr("y", function(d) { return d.y; }); } svg.append("svg:defs").selectAll("marker") .data(["arrow"]) .enter().append("svg:marker") .attr("id", String) .attr("viewBox", "0 -5 10 10") .attr("refX", 10) .attr("refY", 0) .attr("markerWidth", 10) .attr("markerHeight", 10) .attr("orient", "auto") .append("svg:path") .attr("d", "M0,-5L10,0L0,5"); function restart() { node = node.data(nodes); node.enter().insert("circle") .attr("class", "node") .attr("id",function(d){return d.name;}) .attr("r", 15); //Insert text to node.. text=svg.selectAll(".nodetext") .data(nodes) .enter() .append("text") .attr("class","nodetext") .text(function(d){return d.name;}) .attr("dx", 13) .attr("dy", ".35em"); d3.selectAll(".node").on("mousedown",function(d){ if(sourceNode==null){ mouseIsDown = true; lineData[0] = [d3.mouse(this)[0], d3.mouse(this)[1]]; redrawLine(); sourceNode=d.index; console.log("Source node: "+d.name); } }) .on("mouseup",function(d){ if(targetNode==null && sourceNode!=null && mouseIsDown){ targetNode=d.index; links.push({source: sourceNode, target: targetNode}); lineData[1] = [d3.mouse(this)[0], d3.mouse(this)[1]]; redrawLine(); console.log("Target node: "+d.name); sourceNode=null; targetNode=null; mouseIsDown = false; svg.selectAll('path.my-lines') .data(lineData) .remove(); restart(); } }); link = link.data(links); link.enter().insert("line") .attr("class", "link"); link.attr("marker-end", "url(#arrow)"); force.start(); } </script> </ui:define> </ui:composition>
The canonical solution is to put the text and circles into a group. Instead of force.tick() moving both the text and nodes individually, you simply transform the group. So this: node.attr("cx", function (d) { return d.x; }) .attr("cy", function (d) { return d.y; }); text.attr("x", function (d) { return d.x; }) .attr("y", function (d) { return d.y; }); Becomes this: node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); Check out the example here: http://bl.ocks.org/mbostock/950642
Node drag not working on iPad
I would like to drag node and drag canvas (svg element) On a desktop browser, it works fine, but on an iPad it only drags the canvas; node dragging is not working. Where did I go wrong? My source code: <!DOCTYPE html> <meta charset="utf-8"> <style> .node { stroke: #fff; stroke-width: 1.5px; } .link { stroke: #999; } </style> <body> <script src="d3.js"></script> <script> var view_w = width = 960, view_h = height = 500, view_y = 0, view_x = 0; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .attr("viewBox", view_x+" "+view_y+" "+view_w+" "+view_h); var canvasdrag = d3.behavior.drag().on("drag", function(d){ view_x -= d3.event.dx; view_y -= d3.event.dy; //change svg position svg.attr("translate", view_x + " " + view_y); //change viewBox start position svg.attr("viewBox", view_x+" "+view_y+" "+view_w+" "+view_h); }); svg.call(canvasdrag); d3.json("./sample.json", function(error, graph) { graph.links.forEach(function(d) { d.source = graph.nodes[d.source]; d.target = graph.nodes[d.target]; }); var link = svg.append("g") .attr("class", "link") .selectAll("line") .data(graph.links) .enter().append("line") .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; }); var node = svg.append("g") .attr("class", "node") .selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r", 6) .attr("cx", function(d) { return d.x; }) .attr("cy", function(d) { return d.y; }) .call(d3.behavior.drag() .origin(function(d) { return d; }) .on("drag", function(d) { d.x = d3.event.x, d.y = d3.event.y; d3.select(this).attr("cx", d.x).attr("cy", d.y); link.filter(function(l) { return l.source === d; }).attr("x1", d.x).attr("y1", d.y); link.filter(function(l) { return l.target === d; }).attr("x2", d.x).attr("y2", d.y); })); }); </script> [sample.json] {"nodes":[{"x":444,"y":275},{"x":378,"y":324},{"x":478,"y":278},{"x":471,"y":256},{"x":382,"y":269},{"x":371,"y":247},{"x":359,"y":276},{"x":364,"y":302},{"x":400,"y":330},{"x":388,"y":298},{"x":524,"y":296},{"x":570,"y":243},{"x":552,"y":159},{"x":502,"y":287},{"x":511,"y":313},{"x":513,"y":265},{"x":602,"y":132},{"x":610,"y":90},{"x":592,"y":91},{"x":575,"y":89},{"x":607,"y":73},{"x":591,"y":68},{"x":574,"y":73},{"x":589,"y":149},{"x":620,"y":205},{"x":621,"y":230},{"x":589,"y":234},{"x":602,"y":223},{"x":548,"y":188},{"x":532,"y":196},{"x":548,"y":114},{"x":575,"y":174},{"x":497,"y":250},{"x":576,"y":196},{"x":504,"y":201},{"x":494,"y":186},{"x":482,"y":199},{"x":505,"y":219},{"x":486,"y":216},{"x":590,"y":306},{"x":677,"y":169},{"x":657,"y":258},{"x":667,"y":205},{"x":552,"y":227},{"x":518,"y":173},{"x":473,"y":125},{"x":796,"y":260},{"x":731,"y":272},{"x":642,"y":288},{"x":576,"y":269},{"x":605,"y":187},{"x":559,"y":289},{"x":544,"y":356},{"x":505,"y":365},{"x":579,"y":289},{"x":619,"y":282},{"x":574,"y":329},{"x":664,"y":306},{"x":627,"y":304},{"x":643,"y":327},{"x":664,"y":348},{"x":665,"y":327},{"x":653,"y":317},{"x":650,"y":338},{"x":622,"y":321},{"x":633,"y":338},{"x":647,"y":357},{"x":718,"y":362},{"x":636,"y":240},{"x":640,"y":227},{"x":617,"y":249},{"x":631,"y":254},{"x":566,"y":213},{"x":713,"y":322},{"x":716,"y":298},{"x":666,"y":241},{"x":627,"y":355}],"links":[{"source":1,"target":0},{"source":2,"target":0},{"source":3,"target":0},{"source":3,"target":2},{"source":4,"target":0},{"source":5,"target":0},{"source":6,"target":0},{"source":7,"target":0},{"source":8,"target":0},{"source":9,"target":0},{"source":11,"target":10},{"source":11,"target":3},{"source":11,"target":2},{"source":11,"target":0},{"source":12,"target":11},{"source":13,"target":11},{"source":14,"target":11},{"source":15,"target":11},{"source":17,"target":16},{"source":18,"target":16},{"source":18,"target":17},{"source":19,"target":16},{"source":19,"target":17},{"source":19,"target":18},{"source":20,"target":16},{"source":20,"target":17},{"source":20,"target":18},{"source":20,"target":19},{"source":21,"target":16},{"source":21,"target":17},{"source":21,"target":18},{"source":21,"target":19},{"source":21,"target":20},{"source":22,"target":16},{"source":22,"target":17},{"source":22,"target":18},{"source":22,"target":19},{"source":22,"target":20},{"source":22,"target":21},{"source":23,"target":16},{"source":23,"target":17},{"source":23,"target":18},{"source":23,"target":19},{"source":23,"target":20},{"source":23,"target":21},{"source":23,"target":22},{"source":23,"target":12},{"source":23,"target":11},{"source":24,"target":23},{"source":24,"target":11},{"source":25,"target":24},{"source":25,"target":23},{"source":25,"target":11},{"source":26,"target":24},{"source":26,"target":11},{"source":26,"target":16},{"source":26,"target":25},{"source":27,"target":11},{"source":27,"target":23},{"source":27,"target":25},{"source":27,"target":24},{"source":27,"target":26},{"source":28,"target":11},{"source":28,"target":27},{"source":29,"target":23},{"source":29,"target":27},{"source":29,"target":11},{"source":30,"target":23},{"source":31,"target":30},{"source":31,"target":11},{"source":31,"target":23},{"source":31,"target":27},{"source":32,"target":11},{"source":33,"target":11},{"source":33,"target":27},{"source":34,"target":11},{"source":34,"target":29},{"source":35,"target":11},{"source":35,"target":34},{"source":35,"target":29},{"source":36,"target":34},{"source":36,"target":35},{"source":36,"target":11},{"source":36,"target":29},{"source":37,"target":34},{"source":37,"target":35},{"source":37,"target":36},{"source":37,"target":11},{"source":37,"target":29},{"source":38,"target":34},{"source":38,"target":35},{"source":38,"target":36},{"source":38,"target":37},{"source":38,"target":11},{"source":38,"target":29},{"source":39,"target":25},{"source":40,"target":25},{"source":41,"target":24},{"source":41,"target":25},{"source":42,"target":41},{"source":42,"target":25},{"source":42,"target":24},{"source":43,"target":11},{"source":43,"target":26},{"source":43,"target":27},{"source":44,"target":28},{"source":44,"target":11},{"source":45,"target":28},{"source":47,"target":46},{"source":48,"target":47},{"source":48,"target":25},{"source":48,"target":27},{"source":48,"target":11},{"source":49,"target":26},{"source":49,"target":11},{"source":50,"target":49},{"source":50,"target":24},{"source":51,"target":49},{"source":51,"target":26},{"source":51,"target":11},{"source":52,"target":51},{"source":52,"target":39},{"source":53,"target":51},{"source":54,"target":51},{"source":54,"target":49},{"source":54,"target":26},{"source":55,"target":51},{"source":55,"target":49},{"source":55,"target":39},{"source":55,"target":54},{"source":55,"target":26},{"source":55,"target":11},{"source":55,"target":16},{"source":55,"target":25},{"source":55,"target":41},{"source":55,"target":48},{"source":56,"target":49},{"source":56,"target":55},{"source":57,"target":55},{"source":57,"target":41},{"source":57,"target":48},{"source":58,"target":55},{"source":58,"target":48},{"source":58,"target":27},{"source":58,"target":57},{"source":58,"target":11},{"source":59,"target":58},{"source":59,"target":55},{"source":59,"target":48},{"source":59,"target":57},{"source":60,"target":48},{"source":60,"target":58},{"source":60,"target":59},{"source":61,"target":48},{"source":61,"target":58},{"source":61,"target":60},{"source":61,"target":59},{"source":61,"target":57},{"source":61,"target":55},{"source":62,"target":55},{"source":62,"target":58},{"source":62,"target":59},{"source":62,"target":48},{"source":62,"target":57},{"source":62,"target":41},{"source":62,"target":61},{"source":62,"target":60},{"source":63,"target":59},{"source":63,"target":48},{"source":63,"target":62},{"source":63,"target":57},{"source":63,"target":58},{"source":63,"target":61},{"source":63,"target":60},{"source":63,"target":55},{"source":64,"target":55},{"source":64,"target":62},{"source":64,"target":48},{"source":64,"target":63},{"source":64,"target":58},{"source":64,"target":61},{"source":64,"target":60},{"source":64,"target":59},{"source":64,"target":57},{"source":64,"target":11},{"source":65,"target":63},{"source":65,"target":64},{"source":65,"target":48},{"source":65,"target":62},{"source":65,"target":58},{"source":65,"target":61},{"source":65,"target":60},{"source":65,"target":59},{"source":65,"target":57},{"source":65,"target":55},{"source":66,"target":64},{"source":66,"target":58},{"source":66,"target":59},{"source":66,"target":62},{"source":66,"target":65},{"source":66,"target":48},{"source":66,"target":63},{"source":66,"target":61},{"source":66,"target":60},{"source":67,"target":57},{"source":68,"target":25},{"source":68,"target":11},{"source":68,"target":24},{"source":68,"target":27},{"source":68,"target":48},{"source":68,"target":41},{"source":69,"target":25},{"source":69,"target":68},{"source":69,"target":11},{"source":69,"target":24},{"source":69,"target":27},{"source":69,"target":48},{"source":69,"target":41},{"source":70,"target":25},{"source":70,"target":69},{"source":70,"target":68},{"source":70,"target":11},{"source":70,"target":24},{"source":70,"target":27},{"source":70,"target":41},{"source":70,"target":58},{"source":71,"target":27},{"source":71,"target":69},{"source":71,"target":68},{"source":71,"target":70},{"source":71,"target":11},{"source":71,"target":48},{"source":71,"target":41},{"source":71,"target":25},{"source":72,"target":26},{"source":72,"target":27},{"source":72,"target":11},{"source":73,"target":48},{"source":74,"target":48},{"source":74,"target":73},{"source":75,"target":69},{"source":75,"target":68},{"source":75,"target":25},{"source":75,"target":48},{"source":75,"target":41},{"source":75,"target":70},{"source":75,"target":71},{"source":76,"target":64},{"source":76,"target":65},{"source":76,"target":66},{"source":76,"target":63},{"source":76,"target":62},{"source":76,"target":48},{"source":76,"target":58}]} I’m using d3.js version 788855b4a4141fab9554513976dcc50004c76489.