Last active
December 27, 2021 22:41
-
-
Save timproDev/f87388942ca951c092a97c70f07fc979 to your computer and use it in GitHub Desktop.
Pareto 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
<!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>Timmy's Pareto Chart!</title> | |
<!-- css dynamically injected --> | |
</head> | |
<body> | |
<section style="width:80%; margin:5rem auto;"> | |
<div class="mx-dv-container" id="paretoChart"> | |
<div class="plot-wrap w-svg"></div> | |
<div class="plot-wrap no-svg"> | |
<!-- <img src="assets/d3-bundles/horiz-barchart.png"> --> | |
</div> | |
<form class="chart-ui-container"> | |
<div class="chart-form__radio"> | |
<label id="dataChangeOne" class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="line">Line Order</label> | |
</div> | |
<div class="chart-form__radio"> | |
<label id="dataChangeTwo" class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="bar">Bar Order</label> | |
</div> | |
<div class="chart-form__radio"> | |
<label id="dataChangeTwo" class="chart-form__radio-label"><input class="chart-form__radio-input" type="radio" name="dataset" value="date">Date Order</label> | |
</div> | |
</form> | |
</div> | |
</section> | |
<script src="pareto-chart.js"></script> | |
<script src="pareto-chart-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
document.addEventListener("DOMContentLoaded", function(){ | |
// set global variables | |
var path = ''; | |
var dataFile = 'placeholder-dataset.csv'; | |
var elemContainer = ['#paretoChart']; | |
var uiEl = '.chart-ui-container input'; | |
var cssFile = 'pareto-chart.css'; | |
var globalDataX = 'header_five_date'; | |
var oneDataY = 'header_two_amount'; | |
var twoDataY = 'header_three_amount'; | |
// instantiate constructor methods | |
var paretoChart = new ParetoChart({ | |
elem:document.querySelector(elemContainer[0]), | |
globalDataX:'header_five_date', | |
oneDataY:'header_two_amount', | |
twoDataY:'header_three_amount', | |
data: path + dataFile, | |
transSpeed:350 | |
}); | |
// fire chart and events | |
// chartInit(instance, element, dataPath) | |
chartInit(paretoChart, elemContainer, dataFile); | |
function chartInit(chartInst, elem, dataFile){ | |
d3.csv((path + dataFile), function(data) { | |
// convert defined header values to number | |
var parseTime = d3.timeParse("%d/%m/%Y"); | |
data.forEach(function(d) { | |
d[globalDataX] = parseTime(d[globalDataX]); | |
d[oneDataY] = +d[oneDataY]; | |
d[twoDataY] = +d[twoDataY]; | |
}); | |
chartInst.setData(data); | |
var inputs = document.querySelectorAll(elem + ' ' + uiEl); | |
for (var i = 0; i < inputs.length; i++) { | |
inputs[i].addEventListener('click', function(){ | |
var value = this.value; | |
if (value === 'line') { | |
data.sort(function(a,b){ | |
return d3.ascending(+a[twoDataY], +b[twoDataY]) | |
}); | |
} else if (value === 'bar') { | |
data.sort(function(a,b){ | |
return d3.ascending(+a[oneDataY], +b[oneDataY]) | |
}); | |
} else if (value === 'date') { | |
data.sort(function(a,b){ | |
return d3.ascending(+a[globalDataX], +b[globalDataX]) | |
}); | |
} | |
chartInst.setData(data); | |
}); | |
} | |
}); | |
} | |
// include resize event | |
d3.select(window).on('resize', function(){ | |
paretoChart.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); | |
} | |
styleLink(); | |
}); |
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; | |
/*stroke:#aeaeae; | |
stroke-width:1;*/ | |
} | |
.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: 100% | |
margin:0 auto; | |
padding: 0 0 0 0; | |
text-align: center; | |
} | |
.chart-ui-container .chart-form__radio { | |
display: inline-block; | |
padding: 0; | |
margin-right: 1rem; | |
} | |
.chart-ui-container .chart-form__radio-label { | |
display: inline-block; | |
padding: 0 .15rem; | |
font-size: .8rem; | |
} | |
.chart-ui-container .chart-form__radio-input { | |
margin-right: .5rem; | |
cursor: pointer; | |
outline:none; | |
} |
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 ParetoChart = function(opts){ | |
this.globalDataX = this.globalDataX || opts.globalDataX; | |
this.oneDataY = this.oneDataY || opts.oneDataY; | |
this.twoDataY = this.twoDataY || opts.twoDataY; | |
this.element = opts.elem.querySelector('.plot-wrap.w-svg'); | |
} | |
ParetoChart.prototype.setData = function(newData){ | |
this.data = newData; | |
this.draw(); | |
} | |
ParetoChart.prototype.draw = function(){ | |
this.margin = { | |
top:40, | |
left:20, | |
right:20, | |
bottom:80 | |
}; | |
this.width = this.element.offsetWidth - this.margin.left - this.margin.right; | |
this.height = this.width / 3 - (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.margin.left},${this.margin.top})`); | |
this.createOneScales() | |
this.createTwoScales() | |
this.addGrey() | |
this.addOneAxis() | |
this.addTwoAxis() | |
this.addRect(); | |
this.addLine() | |
this.addDots() | |
this.addOneLabels() | |
this.addTwoLabels() | |
this.cleanUp() | |
this.addMouseEvent() | |
} | |
ParetoChart.prototype.createOneScales = function() { | |
var self = this | |
this.xScaleGlobal = d3.scaleBand() | |
.rangeRound([0,this.width]) | |
.domain(this.data.map(function(d) { return d[self.globalDataX]; })) | |
.paddingInner(0.15); | |
this.yScaleOne = d3.scaleLinear() | |
.domain([0, d3.max(this.data, function(d){ return d[self.oneDataY];})]) | |
.range([this.height,0]); | |
} | |
ParetoChart.prototype.createTwoScales = function() { | |
var self = this | |
this.yScaleTwo = d3.scaleLinear() | |
.domain([0, d3.max(this.data, function(d){ return d[self.twoDataY];})]) | |
.range([this.height,0]); | |
} | |
ParetoChart.prototype.addOneAxis = function(){ | |
var self = this | |
this.xAxisOne = d3.axisBottom(this.xScaleGlobal) | |
.tickFormat(d3.timeFormat("%a %Y")); | |
this.yAxisOne = d3.axisLeft() | |
.scale(this.yScaleOne) | |
.ticks(8) | |
.tickFormat(d3.format("")) | |
.tickSize(-this.width); | |
this.plot.append("g.x-axis") | |
.call(this.xAxisOne) | |
.attr("transform","translate(0," + this.height + ")"); | |
this.plot.append("g.y-axis-bar") | |
.call(this.yAxisOne); | |
} | |
ParetoChart.prototype.addTwoAxis = function(){ | |
var self = this | |
this.yAxisTwo = d3.axisRight() | |
.scale(this.yScaleTwo) | |
.ticks(8) | |
.tickFormat(d3.format("")) | |
.tickSize(this.width); | |
this.plot.append("g.y-axis-line") | |
.call(this.yAxisTwo); | |
} | |
ParetoChart.prototype.addDots = function() { | |
var self = this | |
this.gDot = this.plot.selectAll('.g-comp-dot') | |
.data(this.data) | |
.enter() | |
.append('g.g-comp-dot') | |
.append("circle.comp-dot") | |
.attr('fill','brown') | |
.attr("r",3) | |
.attr("cx",function(d){ | |
return self.xScaleGlobal(d[self.globalDataX])+(self.xScaleGlobal.bandwidth()/2); | |
}) | |
.attr('cy', this.height) | |
.transition().delay(function(d, i) { return i * 15; }) | |
.attr("cy",function(d){ | |
return self.yScaleTwo(d[self.twoDataY]); | |
}); | |
} | |
ParetoChart.prototype.addLine = function() { | |
var interpolateTypes = [ | |
d3.curveLinear, // 1 | |
d3.curveStepBefore, // 2 | |
d3.curveStepAfter, // 3 | |
d3.curveBasis, // 4 | |
d3.curveBasisOpen, // 5 | |
d3.curveBasisClosed, // 6 | |
d3.curveBundle, // 7 | |
d3.curveCardinal, // 8 | |
d3.curveCardinal, // 9 | |
d3.curveCardinalOpen, // 10 | |
d3.curveCardinalClosed, // 11 | |
d3.curveNatural // 12 | |
]; | |
var self = this | |
this.lineGen = d3.line() | |
.x( function(d){ return self.xScaleGlobal(d[self.globalDataX])+(self.xScaleGlobal.bandwidth()/2); }) | |
.y( function(d){ return self.yScaleTwo(d[self.twoDataY]); }) | |
.curve(interpolateTypes[0]); | |
this.gLine = this.plot | |
.append("path.line-path") | |
.attr("d", this.lineGen(this.data)) | |
.attr('fill','none') | |
.attr('stroke','brown') | |
.attr('stroke-width',1); | |
} | |
ParetoChart.prototype.addRect = function() { | |
var self = this | |
this.gRects = this.plot.selectAll('.g-comp-rect') | |
.data(this.data) | |
.enter() | |
.append('g.g-comp-rect') | |
.append('rect.comp-rect') | |
.style('fill', this.lineColor || 'salmon') | |
.attr("x",function(d){ | |
return self.xScaleGlobal(d[self.globalDataX]); | |
}) | |
.attr('y', this.height) | |
.transition().delay(function(d, i) { return i * 15; }) | |
.attr("y",function(d){ | |
return self.yScaleOne(d[self.oneDataY]); | |
}) | |
.attr('width',this.xScaleGlobal.bandwidth()) | |
.attr('height', function(d){ | |
return self.height - self.yScaleOne(d[self.oneDataY]); | |
}); | |
} | |
ParetoChart.prototype.addOneLabels = function(){ | |
var self = this | |
this.plot.selectAll('.g-comp-rect') | |
.append("text.bar-label") | |
.attr("x", function(d){ | |
return self.xScaleGlobal(d[self.globalDataX])+(self.xScaleGlobal.bandwidth()/2); | |
}) | |
.attr("y",function(d){ | |
return self.yScaleOne(d[self.oneDataY]); | |
}) | |
.attr("dy", "-10px") | |
.attr("text-anchor","middle") | |
.attr('fill','salmon') | |
.attr('font-size','10px') | |
.text(function(d) { return d[self.oneDataY]; }); | |
} | |
ParetoChart.prototype.addTwoLabels = function(){ | |
var self = this | |
this.plot.selectAll('.g-comp-rect') | |
.append("text.line-label") | |
.attr("x", function(d){ | |
return self.xScaleGlobal(d[self.globalDataX])+(self.xScaleGlobal.bandwidth()/2); | |
}) | |
.attr("y",function(d){ | |
return self.yScaleTwo(d[self.twoDataY]); | |
}) | |
.attr("dy", "-10px") | |
.attr("text-anchor","middle") | |
.attr('fill','brown') | |
.attr('font-size','10px') | |
.text(function(d) { return d[self.twoDataY]; }); | |
} | |
ParetoChart.prototype.addMouseEvent = function () { | |
var self = this; | |
this.plot.selectAll('rect.comp-rect') | |
.on('mouseenter', function(d){ | |
var thisData = d; | |
self.gLine.transition(50).style('opacity','.25'); | |
d3.selectAll('rect.comp-rect, .g-comp-dot').transition(50).style('opacity',function (d,i) { | |
return (d === thisData) ? 1.0 : 0.25; | |
}); | |
}) | |
.on('mouseleave', function(d){ | |
self.gLine.transition(50).style('opacity','1'); | |
d3.selectAll('rect.comp-rect, .g-comp-dot').transition(50).style('opacity',function () { | |
return 1.0; | |
}); | |
}); | |
} | |
ParetoChart.prototype.addGrey = function(){ | |
var self = this | |
this.plot.selectAll('.g-comp-rect') | |
.data(this.data) | |
.enter() | |
.append('rect.bg-bar') | |
.style('fill', this.lineColor || '#f3f3f3') | |
.attr("x",function(d){ | |
return self.xScaleGlobal(d[self.globalDataX]); | |
}) | |
.attr('y', 0) | |
.attr('width',this.xScaleGlobal.bandwidth()) | |
.attr('height', this.height); | |
} | |
ParetoChart.prototype.cleanUp = function(){ | |
var self = this | |
this.domain = this.plot.selectAll('.domain').style('display','none'); | |
this.yBarTick = this.plot.selectAll('.y-axis-bar .tick line') | |
.attr('stroke','#e0e0e0') | |
.attr('stroke-width',1); | |
this.yLineTick = this.plot.selectAll('.y-axis-line .tick line').attr('display','none'); | |
this.xText = this.plot.selectAll('.x-axis .tick text') | |
.attr('text-anchor','end') | |
.attr('y', function(d) { return self.xScaleGlobal.bandwidth() - (self.xScaleGlobal.bandwidth()+3); }) | |
.attr('x',-10) | |
.attr("transform", "rotate(-90)"); | |
} | |
ParetoChart.prototype.resize = function(){ | |
console.log('sdc') | |
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
header_one_name | header_two_amount | header_three_amount | header_four_text_string | header_five_date | |
---|---|---|---|---|---|
Mahatma Gandhi | 50 | 91 | faucibus | 30/04/2013 | |
Anwar Sadat | 64 | 444 | viverra | 20/11/2017 | |
Nikola JuriçiÛˆ | 13 | 68 | non | 23/08/2015 | |
Sargon the Great | 30 | 76 | purus | 15/11/2015 | |
Toyotomi Hideyoshi | 73 | 270 | sed | 27/01/2015 | |
Ronald Reagan | 95 | 495 | amet | 17/02/2015 | |
Salah al-Din | 97 | 367 | tellus | 27/11/2013 | |
Alfred the Great | 71 | 124 | quisque | 20/10/2016 | |
CYRUS the GREAT | 31 | 32 | duis | 15/02/2015 | |
Niccolí_ Machiavelli | 87 | 80 | fusce | 16/05/2013 | |
Darius The Great | 20 | 69 | euismod | 28/02/2015 | |
Vladimir Lenin | 30 | 247 | massa | 15/07/2013 | |
Vladimir Putin | 35 | 373 | commodo | 13/04/2013 | |
Harry S. Truman | 2 | 400 | duis | 19/04/2013 | |
Vladimir Lenin | 48 | 364 | eu | 15/03/2017 | |
Augustus Caesar | 22 | 245 | egestas | 21/04/2015 | |
Ho Chi Minh | 9 | 286 | purus | 24/03/2015 | |
Josip Broz Tito | 64 | 414 | sed | 17/08/2014 | |
Alexander The Great | 42 | 147 | venenatis | 24/09/2015 | |
Queen Isabella of Spain | 8 | 48 | ut | 17/04/2017 | |
Nelson Mandela | 93 | 290 | leo | 23/06/2017 | |
Hannibal | 98 | 490 | enim | 16/11/2015 | |
Tupac Yupanqui | 79 | 292 | enim | 29/09/2016 | |
Empress Jingu | 10 | 197 | nisi | 16/03/2016 | |
Sun Tzu | 27 | 375 | viverra | 16/05/2015 | |
Thomas Jefferson | 99 | 104 | libero | 21/10/2015 | |
Benito Mussolini | 1 | 402 | adipiscing | 19/09/2017 | |
Julius Caesar | 80 | 183 | pharetra | 13/11/2014 | |
Emperor Meiji | 44 | 2 | semper | 31/12/2014 | |
Che Guevara | 3 | 221 | at | 28/02/2016 | |
atilla the hun | 89 | 70 | id | 19/02/2014 | |
Sultan II. Abdulhamid Khan | 10 | 352 | id | 25/08/2015 | |
Queen Victoria | 77 | 357 | laoreet | 24/05/2013 | |
Hammurabi | 71 | 207 | lobortis | 17/07/2017 | |
Benjamin Franklin | 36 | 39 | eu | 4/3/2013 | |
T. E. Lawrence of Arabia | 58 | 261 | commodo | 5/7/2014 | |
William the Conqueror | 88 | 85 | laoreet | 6/11/2017 | |
Fidel Castro | 5 | 341 | quam | 12/4/2016 | |
Margaret Thatcher | 19 | 120 | nibh | 5/9/2016 | |
William I. | 16 | 387 | volutpat | 8/6/2015 | |
Charles de Gaulle | 99 | 320 | viverra | 11/9/2013 | |
Ashoka the Great | 23 | 207 | quisque | 3/10/2017 | |
Flavius Odoacer | 60 | 20 | nisl | 5/11/2015 | |
Moses | 26 | 1 | lectus | 5/2/2015 | |
Winston Churchill | 55 | 328 | justo | 5/7/2017 | |
Theoderic the Great | 47 | 416 | volutpat | 5/2/2018 | |
James Monroe | 27 | 318 | quisque | 7/9/2014 | |
Frederick the Great | 73 | 294 | netus | 7/10/2014 | |
Franklin D. Roosevelt | 7 | 44 | quis | 1/11/2016 | |
John Adams | 71 | 455 | tristique | 12/9/2014 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FYI, see https://bl.ocks.org/timproDev/f87388942ca951c092a97c70f07fc979 for visual rendering of this