This block redraws the entire pie chart depending on the data.
This was created to answer a StackOverflow Question https://stackoverflow.com/questions/55719253/d3js-switching-between-multiple-charts?noredirect=1#comment98146478_55719253
license: mit |
This block redraws the entire pie chart depending on the data.
This was created to answer a StackOverflow Question https://stackoverflow.com/questions/55719253/d3js-switching-between-multiple-charts?noredirect=1#comment98146478_55719253
var gender =[ | |
{ | |
"gender":"Female", | |
"count":533 | |
}, | |
{ | |
"gender":"Male", | |
"count":260 | |
} | |
] | |
var age = [ | |
{ | |
"Age": "0 < 12 years", | |
"count": 8 | |
}, | |
{ | |
"Age": "13 years", | |
"count": 1 | |
}, | |
{ | |
"Age": "14 years", | |
"count": 102 | |
}, | |
{ | |
"Age": "15 years", | |
"count": 195 | |
}, | |
{ | |
"Age": "16 years", | |
"count": 200 | |
}, | |
{ | |
"Age": "17 years", | |
"count": 187 | |
}, | |
{ | |
"Age": "18 years", | |
"count": 100 | |
} | |
] | |
var race = [ | |
{ | |
"race_code": "A", | |
"count": 20 | |
}, | |
{ | |
"race_code": "A F", | |
"count": 0 | |
}, | |
{ | |
"race_code": "A E", | |
"count": 19 | |
}, | |
{ | |
"race_code": "A D", | |
"count": 2 | |
}, | |
{ | |
"race_code": "A DE", | |
"count": 1 | |
}, | |
{ | |
"race_code": "A C", | |
"count": 5 | |
}, | |
{ | |
"race_code": "A C E", | |
"count": 5 | |
}, | |
{ | |
"race_code": "A CD", | |
"count": 0 | |
}, | |
{ | |
"race_code": "A CDE", | |
"count": 0 | |
}, | |
{ | |
"race_code": "AB", | |
"count": 0 | |
}, | |
{ | |
"race_code": "AB E", | |
"count": 0 | |
}, | |
{ | |
"race_code": "AB D", | |
"count": 1 | |
}, | |
{ | |
"race_code": "AB DE", | |
"count": 0 | |
}, | |
{ | |
"race_code": "ABC", | |
"count": 0 | |
}, | |
{ | |
"race_code": "ABC E", | |
"count": 1 | |
}, | |
{ | |
"race_code": "ABCD", | |
"count": 1 | |
}, | |
{ | |
"race_code": "ABCDE", | |
"count": 1 | |
}, | |
{ | |
"race_code": "B", | |
"count": 27 | |
}, | |
{ | |
"race_code": "B H", | |
"count": 0 | |
}, | |
{ | |
"race_code": "B E", | |
"count": 6 | |
}, | |
{ | |
"race_code": "B D", | |
"count": 6 | |
}, | |
{ | |
"race_code": "B DE", | |
"count": 2 | |
}, | |
{ | |
"race_code": "BC", | |
"count": 2 | |
}, | |
{ | |
"race_code": "BC E", | |
"count": 0 | |
}, | |
{ | |
"race_code": "BCD", | |
"count": 1 | |
}, | |
{ | |
"race_code": "BCDE", | |
"count": 0 | |
}, | |
{ | |
"race_code": "C", | |
"count": 175 | |
}, | |
{ | |
"race_code": "C E", | |
"count": 17 | |
}, | |
{ | |
"race_code": "CD", | |
"count": 3 | |
}, | |
{ | |
"race_code": "CDE", | |
"count": 0 | |
}, | |
{ | |
"race_code": "D", | |
"count": 14 | |
}, | |
{ | |
"race_code": "DE", | |
"count": 3 | |
}, | |
{ | |
"race_code": "E", | |
"count": 481 | |
}, | |
{ | |
"race_code": "E G", | |
"count": 0 | |
}, | |
{ | |
"race_code": "EF", | |
"count": 0 | |
}, | |
{ | |
"race_code": "F", | |
"count": 0 | |
}, | |
{ | |
"race_code": "H", | |
"count": 0 | |
} | |
] | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Untitled Document</title> | |
<!-- Bootstrap --> | |
<link rel="stylesheet" href="css/bootstrap.min.css"> | |
<link rel="shortcut icon" href="icons8-bookmark-40.png"> | |
<!-- Custom styling --> | |
<link rel="stylesheet" href="style.css"> | |
<!-- JS libraries --> | |
<script src="https://code.jquery.com/jquery-3.4.0.min.js"></script> | |
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
</head> | |
<body> | |
<div id="demo"> | |
<div id="buttons"> | |
<button id="gender">Gender</button> | |
<button id="age">Age</button> | |
<button id="race">Race</button> | |
</div> | |
<div class="col-md-9" id="pie-chart-area"></div> | |
</div> | |
<!-- Custom JS --> | |
<!-- This sends the data --> | |
<script src="dataset.js"></script> | |
<!-- This creates the graphs --> | |
<script src="main.js"></script> | |
</body> | |
</html> |
//data comes in through data.js which has all the variables. | |
//color function determines the color | |
//you can add more colors based on your data | |
//alternatively you can have an interpolation or other means of choosing the color | |
function color(d) { | |
//create an array of colors depending on names | |
var colors = [ | |
{name: 'Male', fill: '#0079BB' }, | |
{name: 'Female', fill: '#9E519F' }, | |
{name: '0 < 12 years', fill: '#c792c8' }, | |
{name: '13 years', fill: '#a47ebe' }, | |
{name: '14 years', fill: '#827ebe' }, | |
{name: '15 years', fill: '#7e95be' }, | |
{name: '16 years', fill: '#7eb1be' }, | |
{name: '17 years', fill: '#70b785' }, | |
{name: '18 years', fill: '#84b770' }, | |
]; | |
var findcolor = colors.find((c) => c.name === d); | |
//set default | |
if (findcolor != undefined){ | |
var fill = findcolor.fill; | |
}else { | |
var fill = 'blue'; | |
} | |
return fill; | |
} | |
//some drawing variables which will be used repeatedly | |
var margin = {left:40, right:40, top:40, bottom:40}; | |
var width = 400 - margin.top - margin.bottom, | |
height = 400 - margin.left - margin.right; | |
var radius = Math.min(width, height) / 2; | |
var donutWidth = 65; | |
// Define the div for the tooltip | |
var tooltipdiv = d3.select("body").append("div") | |
.attr("class", "tooltip") | |
.style("opacity", 0); | |
//init() adds event listeners to the button to pass the data | |
function init() | |
{ | |
d3.select("#gender") | |
.on("click", function(d,i) { | |
pieChart(gender, 'gender') //pass the data and the key | |
}) | |
d3.select("#age") | |
.on("click", function(d,i) { | |
pieChart(age, 'Age') | |
}) | |
d3.select("#race") | |
.on("click", function(d,i) { | |
//num = document.getElementById("num").value | |
pieChart(race, 'race_code') | |
}) | |
pieChart(gender,'gender') //creates default pie-chart | |
} | |
init(); //calls init() on load | |
//creates the piechart with the data and the key | |
function pieChart(data, key) { | |
//empty the div - wipe the slate clean to create a new pie chart | |
d3.select('#pie-chart-area').html(''); | |
// create the svg | |
var svg = d3.select("#pie-chart-area") | |
.append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.attr('perserveAspectRatio', 'xMinYMid') //new | |
.append("g") | |
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); | |
//define arc | |
var arc = d3.arc() | |
.innerRadius(radius - donutWidth) | |
.outerRadius(radius - 20); | |
// second arc for labels | |
var arc2 = d3.arc() | |
.outerRadius(radius) | |
.innerRadius(radius + 20); | |
// import pie chart and data | |
var pie = d3.pie() | |
.sort(null) | |
.startAngle(1.1*Math.PI) //new | |
.endAngle(3.1*Math.PI) //new | |
.value(function(d) { return d.count; }); | |
//append the arcs based on the data | |
var g = svg.selectAll(".arc") | |
.data(pie(data)) | |
.enter().append("g") | |
.attr("class", "arc") | |
.attr('d', arc) | |
//draw the paths | |
g.append("path") | |
.style("fill", function(d) { return color(d.data[key]); }) | |
.transition().delay(function(d, i) { return i * 500; }).duration(500) | |
.attrTween('d', function(d) { | |
var i = d3.interpolate(d.startAngle, d.endAngle); | |
return function(t) { | |
d.endAngle = i(t); | |
return arc(d); | |
}; | |
}) | |
.each(function(d) { this._current = d; }); // store the initial values | |
g.append("text") | |
.attr("transform", function(d) { return "translate(" + arc2.centroid(d) + ")"; }) | |
.attr("dy", ".35em") | |
.attr("class", "d3-label") | |
.style("text-anchor", "middle") | |
.text(function(d) { return d.data[key]; }); | |
//Append to the tooltip div on mouseover | |
var sum = d3.sum(data, (d) => d.count); | |
g.on("mouseover", function(d) { | |
tooltipdiv.transition() | |
.duration(200) | |
.style("opacity", .9); | |
tooltipdiv.html(d.data[key] +"<br>" + d.data.count + "<br>" + percentage(d.data.count, sum, 2)+"%") | |
.style("left", (d3.event.pageX) + "px") | |
.style("top", (d3.event.pageY - 28) + "px"); | |
}) | |
.on("mouseout", function(d) { | |
tooltipdiv.transition() | |
.duration(500) | |
.style("opacity", 0); | |
}); | |
} | |
//takes number and sum and returns percentage rounded to digits d | |
function percentage(num, sum, d) | |
{ | |
var p = (num/sum)*100; | |
var digits = Math.pow(10, d); | |
return (Math.round (p * digits))/digits; | |
} |
@charset "UTF-8"; | |
/* CSS Document */ | |
#chart-area svg { | |
margin-left: auto; | |
margin-right: auto; | |
display: block; | |
} | |
/*pie chart*/ | |
.arc path { | |
stroke: #FFF; | |
stroke-width: 4px; | |
} | |
.d3-label { | |
fill: #494848; | |
font-family: "Helvetica"; | |
} | |
/*Tool tip*/ | |
div.tooltip { | |
position: absolute; | |
text-align: center; | |
width: 60px; | |
padding: 3px; | |
font: 14px sans-serif; | |
background: white; | |
border: 0px; | |
border-radius: 8px; | |
pointer-events: none; | |
} | |
#pie-chart-area{ | |
height: 500px; | |
position: relative; | |
width: 500px; | |
} | |