Created
March 9, 2018 17:13
-
-
Save timproDev/16c474af603d4e73e18fcaf385c89528 to your computer and use it in GitHub Desktop.
Single Value Donut Chart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
document.addEventListener("DOMContentLoaded", function(){ | |
// set global variables | |
var path = ''; | |
var dataFile = ['placeholder-dataset.csv','placeholder-two.csv']; | |
var dataFileTwo = 'placeholder-two.csv'; | |
var elemContainer = ['#donutChart', '#donutChartTwo', '#donutChartThree','#donutChartFour']; | |
var uiEl = '.chart-ui-container input'; | |
var cssFile = 'donut-chart-single.css'; | |
var strNumHeaders = ['header_two_amount','header_three_amount']; // to convert to numbers | |
// instantiate constructor methods | |
var donutChartSingle = new DonutChartSingle({ | |
elem:document.querySelector(elemContainer[2]), | |
dataCount:'header_two_amount', | |
transSpeed:350 | |
}); | |
var donutChartSingleTwo = new DonutChartSingle({ | |
elem:document.querySelector(elemContainer[3]), | |
dataCount:'header_two_amount', | |
transSpeed:350 | |
}); | |
// fire chart and events | |
// chartInit(instance, element, dataPath) | |
chartInitSingle(donutChartSingle, elemContainer[2], dataFile[0], ['header_one_name', 'Chocolate']); | |
chartInitSingle(donutChartSingleTwo, elemContainer[3], dataFile[1], ['header_one_name', 'Carrots']); | |
styleLink(); | |
function chartInitSingle(chartInst, elem, dataFile, valArr) { | |
d3.csv((path + dataFile), function(data) { | |
data.forEach(function(d) { | |
for (var i = 0; i < strNumHeaders.length; i++) { | |
d[strNumHeaders[i]] = +d[strNumHeaders[i]] || 0; | |
} | |
}); | |
makeItFirst(data, valArr[0], valArr[1]); | |
chartInst.setData(data); | |
// ui events | |
var inputs = document.querySelectorAll(elem + ' ' + uiEl); | |
for (var i = 0; i < inputs.length; i++) { | |
inputs[i].addEventListener('click', function(){ | |
var value = this.value; | |
console.log(data) | |
chartInst.setDataCount(value); | |
}); | |
} | |
function makeItFirst(data, column, element) { | |
var index = data.map(function(d){ return d[column] }).indexOf(element); | |
var lastIndex = data.map(function(d){ return d[column] }).lastIndexOf(element) + 1; | |
data.unshift(data[index]); | |
if (lastIndex > -1) { | |
data.splice(lastIndex, 1); | |
} | |
return data; | |
} | |
}); | |
} | |
// include resize event | |
d3.select(window).on('resize', function(){ | |
donutChartSingle.resize(); | |
donutChartSingleTwo.resize(); | |
}); | |
// inject custom chart css | |
function styleLink(){ | |
var linkElem = document.createElement('link'); | |
document.getElementsByTagName('head')[0].appendChild(linkElem); | |
linkElem.rel = 'stylesheet'; | |
linkElem.type = 'text/css'; | |
linkElem.href = (path + cssFile); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* { | |
font-family: arial, verdana, sans-serif; | |
color:#808080; | |
-webkit-font-smoothing: antialiased; | |
-moz-osx-font-smoothing: grayscale; | |
} | |
line { | |
shape-rendering: crispEdges; | |
} | |
.tooltip { | |
box-shadow: 0 2px 4px 0px rgba(0, 0, 0, 0.5); | |
border-radius: 2px; | |
background-color: #fff; | |
top: -1000px; | |
position: fixed; | |
padding: .65rem; | |
pointer-events: none; | |
max-width: 25%; | |
z-index: 500; | |
} | |
.tooltip-info { | |
padding: 0; | |
margin: 0; | |
display: block; | |
width: 100%; | |
} | |
.tooltip-hidden { | |
opacity: 0; | |
transition: all .3s; | |
transition-delay: .1s; | |
} | |
.chart-ui-container { | |
display: block; | |
width: 200px; | |
margin:0 auto; | |
padding: 2rem 0 0 0; | |
} | |
.chart-ui-container .chart-form__radio {} | |
.chart-ui-container .chart-form__radio-label { | |
display: inline-block; | |
padding: 0 .5rem; | |
border-radius: 3px; | |
font-size: .8rem; | |
} | |
.chart-ui-container .chart-form__radio-input { | |
margin-right: .75rem; | |
cursor: pointer; | |
outline:none; | |
} | |
.value-percentage { | |
font-weight: bold; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var DonutChartSingle = function(opts){ | |
this.transSpeed = opts.transSpeed; | |
this.dataCount = opts.dataCount; | |
this.colorScheme = d3.schemeCategory20b || this.colorScheme; // set up customize | |
this.element = opts.elem.querySelector('.plot-wrap.w-svg'); | |
} | |
DonutChartSingle.prototype.getPercentage = function(){ | |
var total = []; | |
for (var i = 0; i < this.data.length; i++) { | |
total.push(this.data[i][this.dataCount]); | |
} | |
// console.log(total) | |
var sum = total.reduce(add, 0); | |
function add(a, b) { | |
return a + b; | |
} | |
// console.log(sum) | |
var result = (this.data[0][this.dataCount] * 100) / sum; | |
result = Math.round(result) | |
// console.log(result.toString() + '%'); | |
return result.toString() + '%'; | |
} | |
DonutChartSingle.prototype.setData = function(newData){ | |
this.data = newData; | |
this.draw(); | |
} | |
DonutChartSingle.prototype.draw = function(){ | |
var self = this | |
this.margin = { | |
top:0, | |
left:0, | |
right:0, | |
bottom:0 | |
}; | |
this.width = this.element.offsetWidth - this.margin.left - this.margin.right; | |
this.height = this.width / 2 - (this.margin.top - this.margin.bottom); | |
this.element.innerHTML = ''; | |
var svg = d3.select(this.element).append('svg'); | |
svg.attr('width', this.width + (this.margin.left + this.margin.right)); | |
svg.attr('height', (this.height + this.margin.top + this.margin.bottom)); | |
this.plot = svg.append('g') | |
.attr("transform", "translate(" + this.width / 2 + "," + this.height / 2 + ")"); | |
this.tau = 2 * Math.PI; | |
this.radius = Math.min(this.width, this.height) / 2; | |
this.ringSize = this.height / 5; | |
this.colorRange = d3.scaleOrdinal(this.colorScheme); | |
this.color = d3.scaleOrdinal() | |
.range(this.colorRange.range()); | |
this.arc = d3.arc() | |
.innerRadius(this.radius) | |
.outerRadius(this.radius - this.ringSize); | |
this.outerArc = d3.arc() // for labels | |
.innerRadius(this.radius * 0.9) | |
.outerRadius(this.radius * 0.9); | |
this.backgroundDonut = this.plot.append("path") | |
.datum({endAngle: this.tau}) | |
.style("fill", "#f4f4f4") | |
.attr("d", this.arc.startAngle(0)); | |
this.createDonut() | |
} | |
DonutChartSingle.prototype.setDataCount = function(newData){ | |
this.dataCount = newData; | |
this.updateData(); | |
} | |
DonutChartSingle.prototype.updateData = function(opts, elem){ | |
var self = this | |
this.plot = d3.select(this.element).select('svg').select('g'); | |
this.path = this.plot.selectAll('path.slice-single').data(this.pie(this.data)); | |
this.path | |
.transition().duration(this.transSpeed) | |
.attrTween("d", function(d) { | |
this._current = this._current || d; | |
var interpolate = d3.interpolate(this._current, d); | |
this._current = interpolate(0); | |
return function(t) { | |
return self.arc(interpolate(t)); | |
}; | |
}); | |
this.newText = this.plot.selectAll("text.value-percentage") | |
.text(this.getPercentage()); | |
} | |
DonutChartSingle.prototype.createDonut = function() { | |
var self = this | |
this.pie = d3.pie() | |
// .value(function(d,i) {return d[self.dataCount];}) | |
.value(function(d,i) {return d[self.dataCount];}) | |
.sort(null); | |
this.path = this.plot.selectAll("path.slice-single") | |
.data(this.pie(this.data)); | |
this.path | |
.enter() | |
.append("path") | |
.attr("class", "slice-single") | |
.attr("fill", function(d, i) { | |
// if not the first value, no fill | |
if (i <= 0) { | |
return self.color(i); | |
} else { | |
return 'transparent'; | |
} | |
}) | |
.attr('d', this.arc) | |
.each(function(d){this._current = d;}); | |
this.plot | |
.append('text.value-percentage') | |
.style('font-size',this.height / 5) | |
.attr("fill", function(d, i) { | |
return self.color(i); | |
}) | |
.text(this.getPercentage()) | |
.style('text-anchor','middle') | |
.attr('transform','translate(0,' + (this.height / 15) + ')'); | |
} | |
DonutChartSingle.prototype.resize = function(){ | |
console.log("single") | |
this.width = parseInt(d3.select(this.element).style('width'), 10); | |
this.draw(); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html class="no-js" lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<meta http-equiv="x-ua-compatible" content="ie=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>D3 Factory | D3 Libs Dependency Page</title> | |
<link rel="stylesheet" href="assets/css/app.css"> | |
</head> | |
<body><script id="__bs_script__">//<![CDATA[ | |
document.write("<script async src='/browser-sync/browser-sync-client.js?v=2.23.5'><\/script>".replace("HOST", location.hostname)); | |
//]]></script> | |
<div style="text-align: center;"> | |
<section style="width:40%; margin:5rem 0; display: inline-block;"> | |
<div class="mx-dv-container" id="donutChartThree"> | |
<div class="plot-wrap w-svg"></div> | |
<div class="plot-wrap no-svg"></div> | |
<form class="chart-ui-container"> | |
<div class="chart-form__radio"> | |
<label class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="header_two_amount" checked>Header Two Amount</label> | |
</div> | |
<div class="chart-form__radio"> | |
<label class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="header_three_amount">Header Three Amount</label> | |
</div> | |
</form> | |
</div> | |
</section> | |
<section style="width:40%; margin:5rem 0; display: inline-block;"> | |
<div class="mx-dv-container" id="donutChartFour"> | |
<div class="plot-wrap w-svg"></div> | |
<div class="plot-wrap no-svg"></div> | |
<form class="chart-ui-container"> | |
<div class="chart-form__radio"> | |
<label class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="header_two_amount" checked>Header Two Amount</label> | |
</div> | |
<div class="chart-form__radio"> | |
<label class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="header_three_amount">Header Three Amount</label> | |
</div> | |
</form> | |
</div> | |
</section> | |
</div> | |
<script src="donut-chart-single.js"></script> | |
<script src="donut-chart-single-init.js"></script> | |
<script src="https://rawgit.com/timproDev/d3-first-timer/master/js/d3v4-473-jetpack.js"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
header_one_name | header_two_amount | header_three_amount | header_four_text_string | header_five_date | |
---|---|---|---|---|---|
Glazed | 50 | faucibus | 30/04/2013 | ||
Chocolate | 64 | 44 | viverra | 20/11/2017 | |
Cinnamon Sugar | 30 | 76 | purus | 15/11/2015 | |
Jelly | 73 | sed | 27/01/2015 | ||
Marble Frosted | 95 | 495 | amet | 17/02/2015 | |
Apple Crumb | 97 | 367 | tellus | 27/11/2013 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
header_one_name | header_two_amount | header_three_amount | header_four_text_string | header_five_date | |
---|---|---|---|---|---|
Apples | 12 | faucibus | 30/04/2013 | ||
Bananas | 88 | 144 | viverra | 20/11/2017 | |
Grapes | 54 | 376 | purus | 15/11/2015 | |
Pears | 21 | sed | 27/01/2015 | ||
Carrots | 93 | 299 | amet | 17/02/2015 | |
Celery | 11 | 245 | tellus | 27/11/2013 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment