I have a tree that is created in d3 and each node can be dragged and dropped in any point.
I want my code to pop up a dialog box with several choices when I drop a node on specific location.
I do not have any idea how it can be implemented in d3. I searched and found out that this can be done with jquery but I do not know how I can apply jquery into a d3 environment.
An example similar to my problem is explained in here . I implemented something similar to this but my code does not show any jquery code in my webpage.
So my first question is that how can I use d3 and jquery at the same time? A simple example can help me. (like clicking on a node of a tree in d3 svg and a popup of a dialog box in jquery)
And my second question is related to my code snippet. I have provided my code below, if anyone can help me with the implementation of a popup dialog box in the commented area I would really appreciate that.
var treeData =
{
"name": "A",
"children": [
{
"name": "B",
"children": [
{ "name": "C" },
{ "name": "D" }
]
},
{
"name": "E"
}
]
};
var margin = {top: 40, right: 90, bottom: 50, left: 90},
width = 800 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// declares a tree layout and assigns the size
var treemap = d3.tree()
.size([width, height]);
// assigns the data to a hierarchy using parent-child relationships
var nodes = d3.hierarchy(treeData);
// maps the node data to the tree layout
nodes = treemap(nodes);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom),
g = svg.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// adds the links between the nodes
var link = g.selectAll(".link")
.data( nodes.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", function(d) {
return "M" + d.x + "," + d.y
+ "C" + d.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + (d.y + d.parent.y) / 2
+ " " + d.parent.x + "," + d.parent.y;
});
// adds each node as a group
var node = g.selectAll(".node")
.data(nodes.descendants())
.enter().append("g")
.attr("class", function(d) {
return "node" +
(d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; })
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
// adds the circle to the node
node.append("circle")
.attr('r', 10).attr("id", "nodeid");
node.append("text")
.attr("dy", ".60em")
.attr("y", function(d) { return d.children ? -20 : 20; })
.style("text-anchor", "middle")
.text(function(d) { return d.data.name; });
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
dragStarted = null;
}
function dragged(d) {
d.x += d3.event.dx
d.y += d3.event.dy
d3.select(this).attr("transform", "translate(" + d.x + "," + d.y + ")");
}
function dragended(d) {
draggedNode=d;
if (draggedNode.parent==d.parent){
//A popup dialog box should come here
console.log("a dialogbox in here")
//my implemented yet not working jquery dialog box
$( document ).ready(function() {
$("#nodeid").click(function (e) {
$("#modal01").show();
$("#box").show();
})
})
}
d3.select(this).classed("active", false);
}
.node circle {
fill: black;
stroke: steelblue;
stroke-width: 1px;
}
.node text { font: 12px sans-serif; }
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1px;
}
.modal {
position: absolute;
display: none;
z-index: 10;
}
.modal-box {
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 5;
display: none
}
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="stylesheet" href="styles.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<body>
<!-- load the d3.js library -->
<script src="mytree.js"></script>
<div id="modal01" class="modal">Blabla</div>
<div id="box" class="modal-box"></div>
</body>
Just comment the lines that are not needed.
How to close the dialog is still todo.
function dragended(d) {
draggedNode=d;
if (draggedNode.parent==d.parent){
//A popup dialog box should come here
console.log("a dialogbox in here")
//my implemented yet not working jquery dialog box
// $( document ).ready(function() {
// $("#nodeid").click(function (e) {
$("#modal01").show();
$("#box").show();
// })
// })
}
d3.select(this).classed("active", false);
}
I finally found the answer to my question. It basically did not load styles from jquer and the styles of the given modal and box is not completely correct. I am posting my answer in here so if anybody face with the same problem can see it.
Just add these lines to your head tag in html first:
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css"
rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
Then you can Add your dialog box to the body of your html code:
<div id = "dialog-1"
title = "Dialog Title goes here...">This my first jQuery UI Dialog!
<button id = "opener">Open Dialog</button>
</div>
And last we should add the jquery codes to our javascript code:
$( "#dialog-1" ).dialog( "open" );
Related
I'm a beginner to D3/Javascript.
I have a working D3 script where a bunch of path elements are drawn and can be dragged around.
However, when I add seemingly unrelated code elsewhere, that sets the d.x and d.y of the data (to its proper values BTW) the dragging breaks. The element jumps, so that it starts off some distance away and needs to be dragged back to its original place.
(The undesirable "jumping" is orderly way, consistent with a linear transformation of the mouse coordinates)
The "offending" code that seems to cause this behavior is:
hexdata.forEach(function(d) {
d["x"] = grid_x(d);
d["y"] = grid_y(d.grid_y);
});
The code that constructs the nodes and path that works without the code above is:
var node = svg.selectAll('g')
.data(hexdata)
.enter()
.append("g")
.call(d3.drag()
.on("drag", dragged))
.attr("class", "node");
node.append('path')
.attr("d", function (d) {
hex_alignment = (d.grid_y%2==1) ? hexRadius : 0
return "M" + (d.x *hexRadius*2 + 100) + "," + ((d.y*1.75 +100)) + hexPath;
})
function dragged(d) {
d3.select(this).attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")");
}
Does anyone know what is going on?
As mentioned in the comments, setting the origin(v3)/subject(v4) will fix this.
However, if you don't want (for any reason) to set the origin(v3)/subject(v4) in the drag function, simply change the property names for something else, like a and b. We know that x and y is the most common choice for naming the coordinates, but it will cause a conflict in the drag function (whose explanation is beyond the scope here, since you said you are a beginner).
This is easy to show. Here is a simple code using x and y, drag the circle around: it will jump.
var svg = d3.select("svg");
var circle = svg.append("circle")
.datum({
x: 150,
y: 75
})
.attr("transform", d => "translate(" + d.x + "," + d.y + ")")
.attr("r", 10)
.call(d3.drag()
.on("drag", dragged))
function dragged(d) {
d3.select(this).attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")");
}
svg{
border: 1px solid gray;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Now the same code, using a and b. The circle will not jump:
var svg = d3.select("svg");
var circle = svg.append("circle")
.datum({
a: 150,
b: 75
})
.attr("transform", d => "translate(" + d.a + "," + d.b + ")")
.attr("r", 10)
.call(d3.drag()
.on("drag", dragged))
function dragged(d) {
d3.select(this).attr("transform", "translate(" + d3.event.x + "," + d3.event.y + ")");
}
svg{
border: 1px solid gray;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Another alternative is reassigning d.x and d.y in the drag function:
d3.select(this).attr("transform", "translate(" + (d.x = d3.event.x) + ","
+ (d.y = d3.event.y) + ")");
Here is the code:
var svg = d3.select("svg");
var circle = svg.append("circle")
.datum({
x: 150,
y: 75
})
.attr("transform", d => "translate(" + d.x + "," + d.y + ")")
.attr("r", 10)
.call(d3.drag()
.on("drag", dragged))
function dragged(d) {
d3.select(this).attr("transform", "translate(" + (d.x = d3.event.x) + "," + (d.y = d3.event.y) + ")");
}
svg{
border: 1px solid gray;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Basically i wish to implement a zoom behavior to my family tree like in this example here http://bl.ocks.org/sgruhier/1d692762f8328a2c9957
I've added the call function to where im creating the svg canvas but it does nothing, am i missing something ? Thanks in advance
Here's the code:
<!DOCTYPE html>
<html>
<head>
<title>Fam tree</title>
<script src="http://d3js.org/d3.v2.js"></script>
<style>
body, html {
width: 100%;
height: 100%;
margin: 0;
}
svg {
position: absolute;
top: 0;
left: 0;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
div.tooltip {
position: absolute;
text-align: center;
width: 200px;
height: 30px;
padding: 8px;
font: 16px sans-serif;
font-weight: bold;
background: #ffff99;
border: solid 1px #aaa;
border-radius: 8px;
pointer-events: none;
background-color: rgba(0,128,128,0.5);
overflow: hidden;
transition: .5s ease
}
</style>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
//JSON
var treeData = {"name" : "Steve", "lname" : "Forester", "children" : [
{"name" : "Anna", "lname" : "Woods" },
{"name" : "Boris", "lname" : "Vladimirov" },
{"name" : "Clint", "lname" : "Eastwood", "children": [
{"name" : "Sheldon", "lname" : "Morris" },
{"name" : "Bert", "lname" : "Jefferson" }
]}
]};
// Create a svg canvas
var vis = d3.select("#viz")
.append("svg")
.attr("width", "1500")
.attr("height", "1000")
.call(d3.behavior.zoom().on("zoom", function () {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")")
}))
.append("g")
.attr("transform", "translate(100, 100)"); // shift everything to the right
// Add tooltip div
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 1e-6);
// Create a tree "canvas"
var tree = d3.layout.tree()
.size([1200, 500]);
var diagonal = d3.svg.diagonal();
// Preparing the data for the tree layout, convert data into an array of nodes
var nodes = tree.nodes(treeData);
// Create an array with all the links
var links = tree.links(nodes);
var link = vis.selectAll("pathlink")
.data(links)
.enter().append("svg:path")
.attr("class", "link")
.attr("d", diagonal)
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
// Hexagon img
node.append("svg:image")
.attr("xlink:href", "prva.png")
.attr("width", 100)
.attr("height", 100)
.attr("x", -50)
.attr("y", -30)
.on("mouseover", mouseover)
.on("mousemove", function(d){mousemove(d);})
.on("mouseout", mouseout)
.attr("fill","red")
.attr("r", 5.5);
function mouseover() {
div.transition()
.duration(300)
.style("opacity", 1);
d3.select(this).attr("xlink:href", "vtora.png");
}
function mousemove(d) {
div
.text(" Name:" + ' ' + d.name + ' ' + d.lname)
.style("left", (d3.event.pageX ) + "px")
.style("top", (d3.event.pageY) + "px");
}
function mouseout() {
div.transition()
.duration(300)
.style("opacity", 1e-6);
d3.select(this).attr("xlink:href", "prva.png");
}
</script>
</body>
</html>
I am trying to use the example from here, and my files are as follows:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Test Page</title>
<meta charset="utf-8">
<style>
.node circle {
fill: #999;
}
.node text {
font: 10px sans-serif;
}
.node--internal circle {
fill: #555;
}
.node--internal text {
text-shadow: 0 1px 0 #fff, 0 -1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff;
}
.link {
fill: none;
stroke: #555;
stroke-opacity: 0.4;
stroke-width: 1.5px;
}
html, body {
height: 100%;
}
html {
display: table;
margin: auto;
}
body {
display: table-cell;
vertical-align: middle;
}
</style>
</head>
<body>
<svg width="960" height="2000"></svg>
<script src="d3.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
g = svg.append("g").attr("transform", "translate(40,0)");
var tree = d3.cluster()
.size([height, width - 160]);
var stratify = d3.stratify()
.parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); });
d3.csv("test.csv", function(error, data) {
if (error) throw error;
var root = stratify(data)
.sort(function(a, b) { return (a.height - b.height) || a.id.localeCompare(b.id); });
tree(root);
var link = g.selectAll(".link")
.data(root.descendants().slice(1))
.enter().append("path")
.attr("class", "link")
.attr("d", function(d) {
return "M" + d.y + "," + d.x
+ "C" + (d.parent.y + 100) + "," + d.x
+ " " + (d.parent.y + 100) + "," + d.parent.x
+ " " + d.parent.y + "," + d.parent.x;
});
var node = g.selectAll(".node")
.data(root.descendants())
.enter().append("g")
.attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
node.append("circle")
.attr("r", 2.5);
node.append("text")
.attr("dy", 3)
.attr("x", function(d) { return d.children ? -8 : 8; })
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1); });
});
</script>
</body>
</html>
and test.csv
id
country
country.USA
country.Canada
country.Russia
country.China
country.India
country.England
country.USA.Wisconsin
country.USA.Wisconsin.Madison
country.USA.Washington DC
country.Canada.Toronto
country.Canada.Ottawa
country.Russia.St Petersburg
country.India.Karnataka
country.India.Maharashtra
country.India.Delhi
country.India.Karnataka.Bangalore
country.India.Karnataka.Bangalore.city
country.India.Karnataka.Bangalore.rural
country.India.Karnataka.Mysore
country.India.Karnataka.Mangalore
country.India.Maharashtra.Mumbai
country.India.Maharashtra.Pune
The resulting output is cutting off the first node, i.e. instead of country, it is displaying just ountry as highlighted in the screenshot below:
How to resolve this? This is just a sample, I have actual csv with the name of the nodes of length 10 Characters. How to auto-adjust the final output.
Your line with the g defined in it, you probably just want to increase the x translation.
g = svg.append("g").attr("transform", "translate(40,0)");
becomes
g = svg.append("g").attr("transform", "translate(60,0)");
This moves the group which contains the entire visualization over some additional pixels. If you want to get clever about it you could actually measure the length of the string "country" and translate by that amount. For example:
const countryText = g.append("g")
.attr("class", "node") //apply all the same classes to ensure css rules match
.append("text")
.text("country");
const width = countryText.node().getComputedTextLength()
g.attr("transform", `translate(${width}, 0)`);
Server Side: A word of warning about measuring strings though. This is only supported in an environment with a browser, which can make server side rendering (or automated tests that use something like Node) very difficult to work with.
If you look at Bostock's code, you can see that he's appending everything to a group, which is being translated 40 pixels to the right:
g = svg.append("g").attr("transform", "translate(40,0)");
Solution: translate more than that:
g = svg.append("g").attr("transform", "translate(50,0)");
Here is your updated bl.ocks: https://bl.ocks.org/anonymous/c873ba1afc1d58a1ea5a13a093468d39
I'm creating a proof of concept in v4 of D3JS. One of the things I'm trying to do is have a tooltip display when hovering over a data point. I found a good example of this here.
What I now need to do is add a link (or any clickable element) to the tooltip. I created a plunkr based on the example above and added a link to the tooltip. I can't click on the link and the tooltip appears to be below the line-chart as far as z-index goes.
I've tried setting the z-index on the chart and the tooltip to no avail. Can anyone point me in the right direction to sort this?
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
div.tooltip {
position: absolute;
text-align: center;
width: 150px;
height: 100px;
padding: 2px;
font: 12px sans-serif;
background: lightsteelblue;
border: 0px;
border-radius: 8px;
pointer-events: none;
}
</style>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%d-%b-%y");
var formatTime = d3.timeFormat("%e %B");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// Get the data
d3.csv("data.csv", function(error, data) {
if (error) throw error;
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.close = +d.close;
});
// scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// add the dots with tooltips
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) { return x(d.date); })
.attr("cy", function(d) { return y(d.close); })
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(formatTime(d.date) + "<br/>" + d.close + "<br/><a href='www.google.com'>Test it</a>")
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
});
// add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
});
</script>
</body>
When creating your tooltip based on the example in the link, you copied its CSS:
div.tooltip {
pointer-events: none;
...
}
The reason we generally set pointer-events to none in a <div> tooltip, as the linked example did, is that we want to get the mouseout event on the element that fired the mouseover (normally to set the tooltip's opacity to zero), and if the tooltip is positioned to close from the element (sometimes even directly over it) the pointer can hover over the div and ruin the mouseout. Besides that, another important reason to set pointer-events to none is that it allows other elements behind the tooltip to get mouseover events, just like if the tooltip was not there.
However, because in your code there is no mouseout, the easier solution here is simply eliminating the pointer-events: none in the CSS. That way the <div> get the click event.
This is the updated plunker: https://plnkr.co/edit/xfa8cjQd3tHYNu0dUla4?p=preview
I am attempting to create a Sankey diagram from a csv file. I am utilizing code provided by timelyportfolio, and also the code from the d3 site (and even the sample csv files). However, when I try to run the code in Chrome, I am getting a blank Html page, indicating that the code is crashing. I attempted to redirect the source codes to files on my desktop, but I am still running into the same issues. (I am working on a computer with Windows XP)
I have pasted the code below:
<!DOCTYPE html>
<meta charset="utf-8">
<title>SANKEY Experiment</title>
<style>
.node rect {
cursor: move;
fill-opacity: .9;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
}
.link {
fill: none;
stroke: #000;
stroke-opacity: .2;
}
.link:hover {
stroke-opacity: .5;
}
</style>
<body>
<p id="chart">
<script src="http://d3js.org/d3.v3.js"></script>
<script src="C:\Documents and Settings\jennifer.ducz\Desktop\sankey.js"></script>
<script>
var units = "Units";
var margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 1400 - margin.left - margin.right,
height = 740 - margin.top - margin.bottom;
var formatNumber = d3.format(",.0f"), // zero decimal places
format = function(d) { return formatNumber(d) + " " + units; },
color = d3.scale.category20();
// append the svg canvas to the page
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Set the sankey diagram properties
var sankey = d3.sankey()
.nodeWidth(36)
.nodePadding(10)
.size([width, height]);
var path = sankey.link();
// load the data with d3.csv instead of d3.json
//for another much simpler example uncomment the below
d3.csv("C:\Documents and Settings\jennifer.ducz\Desktop\sankey.csv", function(error, data) {
//d3.csv("d3noob_energy.csv", function(error, data) {
//set up graph in same style as original example but empty
graph = {"nodes" : [], "links" : []};
data.forEach(function (d) {
graph.nodes.push({ "name": d.source });
graph.nodes.push({ "name": d.target });
graph.links.push({ "source": d.source, "target": d.target, "value": +d.value });
});
//thanks Mike Bostock https://groups.google.com/d/msg/d3-js/pl297cFtIQk/Eso4q_eBu1IJ
//this handy little function returns only the distinct / unique nodes
graph.nodes = d3.keys(d3.nest()
.key(function (d) { return d.name; })
.map(graph.nodes));
//it appears d3 with force layout wants a numeric source and target
//so loop through each link replacing the text with its index from node
graph.links.forEach(function (d, i) {
graph.links[i].source = graph.nodes.indexOf(graph.links[i].source);
graph.links[i].target = graph.nodes.indexOf(graph.links[i].target);
});
//now loop through each nodes to make nodes an array of objects rather than an array of strings
graph.nodes.forEach(function (d, i) {
graph.nodes[i] = { "name": d };
});
sankey
.nodes(graph.nodes)
.links(graph.links)
.layout(32);
// add in the links
var link = svg.append("g").selectAll(".link")
.data(graph.links)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("stroke-width", function(d) { return Math.max(1, d.dy); })
.sort(function(a, b) { return b.dy - a.dy; });
// add the link titles
link.append("title")
.text(function(d) {
return d.source.name + " → " +
d.target.name + "\n" + format(d.value); });
// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; })
.call(d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", function() {
this.parentNode.appendChild(this); })
.on("drag", dragmove));
// add the rectangles for the nodes
node.append("rect")
.attr("height", function(d) { return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", function(d) {
return d.color = color(d.name.replace(/ .*/, "")); })
.style("stroke", function(d) {
return d3.rgb(d.color).darker(2); })
.append("title")
.text(function(d) {
return d.name + "\n" + format(d.value); });
// add in the title for the nodes
node.append("text")
.attr("x", -6)
.attr("y", function(d) { return d.dy / 2; })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.attr("transform", null)
.text(function(d) { return d.name; })
.filter(function(d) { return d.x < width / 2; })
.attr("x", 6 + sankey.nodeWidth())
.attr("text-anchor", "start");
// the function for moving the nodes
function dragmove(d) {
d3.select(this).attr("transform",
"translate(" + (
d.x = Math.max(0, Math.min(width - d.dx, d3.event.x))
) + "," + (
d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))
) + ")");
sankey.relayout();
link.attr("d", path);
}
});
</script>
</body>
</html>
If someone can tell me what I'm doing wrong, please let me know.
Edit: This is the sample data I'm using courtesy of timelyportfolio
source target value
Barry Elvis 2
Frodo Elvis 2
Frodo Sarah 2
Barry Alice 2
Elvis Sarah 2
Elvis Alice 2
Sarah Alice 4
I've never played with it; however,
1) run your developer tools/console to see exactly which line is crashing the app
2) the following link discusses problems/solutions in formatting the data
http://www.d3noob.org/2013/02/sankey-diagrams-description-of-d3js-code.html
if you are not using MAMP or any other kind of virtual server, Chrome won't load the csv or any other local files other than the html. Try using a local webserver and everything should be fine