Skip to content

Instantly share code, notes, and snippets.

@akulmehta
Last active April 17, 2019 20:36
Show Gist options
  • Save akulmehta/923f277f8a10d0c35b77f6e3a84929bf to your computer and use it in GitHub Desktop.
Save akulmehta/923f277f8a10d0c35b77f6e3a84929bf to your computer and use it in GitHub Desktop.
Pie Chart Redraw
license: mit
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment