I know this question has been asked many times but I am not able to solve the problem of updating my pie chart. I am completely lost. Could you please tell me what seems to the problem here ?
I tried the following way but the chart doesn't seem to update. I added a function change that is supposed to update the chart. I am updating the data, redrawing the arcs and changing the labels but it is not working.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Load D3 -->
<script src="https://d3js.org/d3.v5.min.js"></script>
<title>Document</title>
</head>
<body>
<div id="pie"></div>
<script>
var dataChart = { a: 9, b: 20, c: 30, d: 8, e: 12 };
var dataChart2 = { f: 9, g: 20, h: 30, i: 8 };
console.log(dataChart);
var width = 300,
height = 300,
// Think back to 5th grade. Radius is 1/2 of the diameter. What is the limiting factor on the diameter? Width or height, whichever is smaller
radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal()
.range(["#2C93E8", "#838690", "#F56C4E"]);
var pie = d3.pie()
.value(function (d) { return d.value; });
data = pie(d3.entries(dataChart));
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var labelArc = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
var svg = d3.select("#pie")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // Moving the center point. 1/2 the width and 1/2 the height
var g = svg.selectAll("arc")
.data(data)
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function (d) { return color(d.data.key); });
g.append("text")
.attr("transform", function (d) { return "translate(" + labelArc.centroid(d) + ")"; })
.text(function (d) { return d.data.key; })
.style("fill", "#fff");
function change(dataChart) {
var pie = d3.pie()
.value(function (d) { return d.value; });
data = pie(d3.entries(dataChart));
path = d3.select("#pie").selectAll("path").data(data); // Compute the new angles
path.attr("d", arc); // redrawing the path
d3.selectAll("text").data(data).attr("transform", function (d) { return "translate(" + labelArc.centroid(d) + ")"; }); // recomputing the centroid and translating the text accordingly.
}
// calling the update functions
change(dataChart);
change (dataChart2);
</script>
</body>
</html>
This is my chord diagram with d3.js version 4 (based on this chart in v3). You can run it or just have a look at the image:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Chord Diagramm</title>
<!-- D3.js -->
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>
<!-- Google Fonts -->
<link href='https://fonts.googleapis.com/css?family=Lato:400,900' rel='stylesheet' type='text/css'>
<!-- bootstrap 4(!) -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<style>
body {
font-size: 12px;
font-family: 'Lato', sans-serif;
text-align: center;
fill: #2B2B2B;
cursor: default;
}
#media (min-width: 600px) {
#chart{
font-size: 16px;
}
}
</style>
</head>
<body>
<h1> Chord Diagramm </h1>
<div id = "chart"></div>
</body>
<script>
////////////////////////////////////////////////////////////
//////////////////////// Set-Up ////////////////////////////
////////////////////////////////////////////////////////////
var margin = {left:90, top:90, right:90, bottom:90},
width = 1000 - margin.left - margin.right, // more flexibility: Math.min(window.innerWidth, 1000)
height = 1000 - margin.top - margin.bottom, // same: Math.min(window.innerWidth, 1000)
innerRadius = Math.min(width, height) * .39,
outerRadius = innerRadius * 1.1;
var names = ["Test1","Test2","AMO-DB","YouTube","Twitter", "Google+", "Pflegeratgeber" ,"O-Mag","RuV"],
colors = ["#301E1E", "#083E77", "#342350", "#567235", "#8B161C", "#DF7C00"],
opacityDefault = 0.8;
var matrix = [
[0,1,1,1,1,1,1,1,1], //Test1
[0,0,1,1,1,1,1,0,1], //Test2
[0,1,0,1,1,1,1,1,1], //Hawkeye
[0,1,1,0,1,1,0,1,1], //The Hulk
[0,1,1,1,0,1,1,1,1], //Iron Man
[0,1,1,1,1,0,1,1,1],
[0,1,1,1,1,1,0,1,1], //Iron Man
[0,1,1,1,1,1,1,0,1],
[0,1,1,1,1,1,1,0,0] //Thor //Thor
];
////////////////////////////////////////////////////////////
/////////// Create scale and layout functions //////////////
////////////////////////////////////////////////////////////
var colors = d3.scaleOrdinal()
.domain(d3.range(names.length))
.range(colors);
var chord = d3.chord()
.padAngle(.15)
.sortChords(d3.descending)
var arc = d3.arc()
.innerRadius(innerRadius*1.01)
.outerRadius(outerRadius);
var path = d3.ribbon()
.radius(innerRadius);
////////////////////////////////////////////////////////////
////////////////////// Create SVG //////////////////////////
////////////////////////////////////////////////////////////
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(" + (width/2 + margin.left) + "," + (height/2 + margin.top) + ")")
.datum(chord(matrix));
////////////////////////////////////////////////////////////
////////////////// Draw outer Arcs /////////////////////////
////////////////////////////////////////////////////////////
var outerArcs = svg.selectAll("g.group")
.data(function(chords) { return chords.groups; })
.enter().append("g")
.attr("class", "group")
.on("mouseover", fade(.1))
.on("mouseout", fade(opacityDefault))
// text popups
.on("click", mouseoverChord)
.on("mouseout", mouseoutChord);
outerArcs.append("path")
.style("fill", function(d) { return colors(d.index); })
.attr("d", arc);
////////////////////////////////////////////////////////////
////////////////////// Append names ////////////////////////
////////////////////////////////////////////////////////////
//Append the label names on the outside
outerArcs.append("text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("class", "titles")
.attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + (outerRadius + 10) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.text(function(d,i) { return names[i]; });
////////////////////////////////////////////////////////////
////////////////// Draw inner chords ///////////////////////
////////////////////////////////////////////////////////////
svg.selectAll("path.chord")
.data(function(chords) { return chords; })
.enter().append("path")
.attr("class", "chord")
.style("fill", function(d) { return colors(d.source.index); })
.style("opacity", opacityDefault)
.attr("d", path);
////////////////////////////////////////////////////////////
////////////////// Extra Functions /////////////////////////
////////////////////////////////////////////////////////////
function popup() {
return function(d,i) {
console.log("love");
};
}//popup
//Returns an event handler for fading a given chord group.
function fade(opacity) {
return function(d,i) {
svg.selectAll("path.chord")
.filter(function(d) { return d.source.index != i && d.target.index != i; })
.transition()
.style("opacity", opacity);
};
}//fade
//Highlight hovered over chord
function mouseoverChord(d,i) {
//Decrease opacity to all
svg.selectAll("path.chord")
.transition()
.style("opacity", 0.1);
//Show hovered over chord with full opacity
d3.select(this)
.transition()
.style("opacity", 1);
//Define and show the tooltip over the mouse location
$(this).popover({
//placement: 'auto top',
title: 'test',
placement: 'right',
container: 'body',
animation: false,
offset: "20px -100px",
followMouse: true,
trigger: 'click',
html : true,
content: function() {
return "<p style='font-size: 11px; text-align: center;'><span style='font-weight:900'>" +
"</span> text <span style='font-weight:900'>" +
"</span> folgt hier <span style='font-weight:900'>" + "</span> movies </p>"; }
});
$(this).popover('show');
}
//Bring all chords back to default opacity
function mouseoutChord(d) {
//Hide the tooltip
$('.popover').each(function() {
$(this).remove();
})
//Set opacity back to default for all
svg.selectAll("path.chord")
.transition()
.style("opacity", opacityDefault);
} //function mouseoutChord
</script>
</html>
I tried to follow this example: http://bl.ocks.org/syntagmatic/9eadf19bd2976653fa50 and also found a similar thread here: d3.js Add labels in Chord diagram
However, I can't wrap my head around how to integrate it into my code. Any help really appreciated.
We can approach it like this:
Add an id to the paths while you're appending them based on which group it is in.
outerArcs.append("path")
.style("fill", function(d) { return colors(d.index); })
.attr("id", function(d, i) { return "group" + d.index; }) //add id here
.attr("d", arc);
Append the text directly to the path and then use textpath which places it inside the arc like the following:
outerArcs.append("text")
.attr("x", 6)
.attr("dy", 15)
.append("textPath")
.attr("xlink:href", function(d) { return "#group" + d.index; })
.text(function(chords, i){return names[i];})
.style("fill", "white");
Working code here - https://jsfiddle.net/rjonean4/
I am new in d3.js language. I am trying to built a simple application but I stuck some where. I have a separate .js file jack.js which makes pie chart when you link it with html page.
Problem I want to use that file in every html page with different data. But i cant find the perfect solution of this. whenever page loaded in browser, file load its pie chart visualization. So can you suggest me what should i need to do?
HTML page
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Pie layout</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="lib/pie.js"></script>
<script>
dataset = [1,2,3,4,5];
</script>
</head>
<body>
</body>
</html> `
jack.js
//Width and height
var w = 300;
var h = 300;
var dataset = [ 5, 10, 20, 45, 6, 25 ];
var outerRadius = w / 2;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie();
//Easy colors accessible via a 10-step ordinal scale
var color = d3.scale.category10();
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Set up groups
var arcs = svg.selectAll("g.arc")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
//Draw arc paths
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
//Labels
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text(function(d) {
return d.value;
});
<body>
<script type="text/javascript" src="lib/pie.js"></script>
<script>dataset = [1, 2, 3, 4, 5];</script>
</body>
This way you can do this.
Hi Remove var dataset = [ 5, 10, 20, 45, 6, 25 ]; from jack.js and put them either in your html file like you did in the head of your html file. Call jack.js in the body.
This will ensure that the data is loaded first before jack.js.
Hence your code will look like this
Html
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Pie layout</title>
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script>dataset = [1, 2, 3, 4, 5];</script>
</head>
<body>
<script type="text/javascript" src="lib/pie.js"></script>
</body>
</html>
pie.js
var w = 300;
var h = 300;
var outerRadius = w / 2;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie();
//Easy colors accessible via a 10-step ordinal scale
var color = d3.scale.category10();
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
//Set up groups
var arcs = svg.selectAll("g.arc")
.data(pie(dataset))
.enter()
.append("g")
.attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
//Draw arc paths
arcs.append("path")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc);
//Labels
arcs.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.text(function(d) {
return d.value;
});
Alternatively, you place wrap you d3 code in a $( document ).ready( //your d3 code here ) http://learn.jquery.com/using-jquery-core/document-ready/
Alternatively
pie.js
$( document ).ready(
// d3 code here
var pie = d3.layout.pie();
//Easy colors accessible via a 10-step ordinal scale
var color = d3.scale.category10();
....
)
I pasted that code to jack.js file
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
//Width and height
var w = 300;
var h = 300;
var dataset = [ 5, 10, 20, 45, 6, 25 ];
var outerRadius = w / 2;
var innerRadius = 0;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var pie = d3.layout.pie();
var color = d3.scale.category10();
var svg = d3.select("body").append("svg").attr("width", w)
.attr("height", h);
var arcs = svg.selectAll("g.arc").data(pie(dataset)).enter()
.append("g").attr("class", "arc")
.attr("transform", "translate(" + outerRadius + "," +outerRadius + ")");
arcs.append("path").attr("fill", function(d, i) {
return color(i);})
.attr("d", arc).on("mouseenter", function(d) {
//console.log("mousein")
text = arcs.append("text").attr("transform", arc.centroid(d))
.attr("dy", ".5em").style("text-anchor", "middle")
.style("fill", "blue").attr("class", "on")
.text(d.data.place);})
.on("mouseout", function(d) {
text.remove();});
//Labels
arcs.append("text").attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")"; })
.attr("text-anchor", "middle").text(function(d) {
return d.value;
});</script>
and linked it to my html page.
Problem: This jack.js file is not showing pie chart in HTML page. can any body suggest me what should I need to do?
Is this the behavior you wanted?
plnkr
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<script type="text/javascript" src="jack.js"></script>
<h1>Hello Plunker!</h1>
</body>
</html>
I am trying to learn using d3 chord diagram. Original script in http://bl.ocks.org/mbostock/1046712#index.html
But as I try to use the code locally I am getting TypeError: imports is undefined
My index.html has the following code. I have created a readme.json file with exact data form http://bl.ocks.org/mbostock/raw/1046712/readme.json
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<style>
body {
font: 10px sans-serif;
}
.chord {
fill-opacity: .67;
}
</style>
<script>
function asd(){
alert("asd");
var outerRadius = 960 / 2,
innerRadius = outerRadius - 130;
var fill = d3.scale.category20c();
var chord = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.descending);
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(innerRadius + 20);
var svg = d3.select("body").append("svg")
.attr("width", outerRadius * 2)
.attr("height", outerRadius * 2)
.append("g")
.attr("transform", "translate(" + outerRadius + "," + outerRadius + ")");
d3.json("readme.json", function(error, imports) {
var indexByName = d3.map(),
nameByIndex = d3.map(),
matrix = [],
n = 0;
// Returns the Flare package name for the given class name.
function name(name) {
return name.substring(0, name.lastIndexOf(".")).substring(6);
}
// Compute a unique index for each package name.
imports.forEach(function(d) {
if (!indexByName.has(d = name(d.name))) {
nameByIndex.set(n, d);
indexByName.set(d, n++);
}
});
// Construct a square matrix counting package imports.
imports.forEach(function(d) {
var source = indexByName.get(name(d.name)),
row = matrix[source];
if (!row) {
row = matrix[source] = [];
for (var i = -1; ++i < n;) row[i] = 0;
}
d.imports.forEach(function(d) { row[indexByName.get(name(d))]++; });
});
chord.matrix(matrix);
var g = svg.selectAll(".group")
.data(chord.groups)
.enter().append("g")
.attr("class", "group");
g.append("path")
.style("fill", function(d) { return fill(d.index); })
.style("stroke", function(d) { return fill(d.index); })
.attr("d", arc);
g.append("text")
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
.attr("dy", ".35em")
.attr("transform", function(d) {
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + (innerRadius + 26) + ")"
+ (d.angle > Math.PI ? "rotate(180)" : "");
})
.style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
.text(function(d) { return nameByIndex.get(d.index); });
svg.selectAll(".chord")
.data(chord.chords)
.enter().append("path")
.attr("class", "chord")
.style("stroke", function(d) { return d3.rgb(fill(d.source.index)).darker(); })
.style("fill", function(d) { return fill(d.source.index); })
.attr("d", d3.svg.chord().radius(innerRadius));
});
d3.select(self.frameElement).style("height", outerRadius * 2 + "px");
}
</script>
</head>
<body onload="asd()">
asd
</body>
</html>
I use apache in localhost.
One needs to set up a web server on a local machine in order to run such examples locally.
A good explanation is here.
I usually use python SimpleHTTPServer.
Also, you need to access your example via localhost:{port number}, not via file system.
There are few more gotchas, but I believe this would be sufficient for you to start.