Skip to content

Instantly share code, notes, and snippets.

@fogonwater
Last active December 5, 2017 00:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fogonwater/7bd0d65211cc7f1ff624d025baa63baf to your computer and use it in GitHub Desktop.
Save fogonwater/7bd0d65211cc7f1ff624d025baa63baf to your computer and use it in GitHub Desktop.
Earnings calendar
license: mit
person_group annual_salary range day date category note
Typical Pacific Woman 39878 365.0 31/12/17 1
Typical Māori Woman 43680 333.2 30/11/17 1
Typical Asian Woman 44889 324.3 21/11/17 1
Typical European Woman 50486 288.3 16/10/17 1
Typical Pacific Man 40950 355.4 22/12/17 1
Typical Māori Man 45377 320.8 17/11/17 1
Typical Asian Man 46800 311.0 08/11/17 1
Typical European Man 55751 261.1 19/09/17 1
Information Architect 135000 150 107.8 18/04/17 2
IT Management 125000 160 116.4 27/04/17 2
Business Intelligence Analyst 115000 137 126.6 07/05/17 2
Construction Project Manager 105000 110 138.6 19/05/17 2
Accounting Manager 100000 100 145.6 26/05/17 2
General Manager 95000 183 153.2 03/06/17 2
Programmer 95000 137 153.2 03/06/17 2
Architect 85000 80 171.2 21/06/17 2
Web Designer 85000 128 171.2 21/06/17 2
Accountant 75000 80 194.1 14/07/17 2
Communications & PR 72000 80 202.2 22/07/17 2
Bank Branch Staff 65000 65 223.9 12/08/17 2
Public Servant 65000 90/65 223.9 12/08/17 2
Interior Designer 62000 68 234.8 23/08/17 2
Electrician 60000 45 242.6 31/08/17 2
Plumber 60000 38 242.6 31/08/17 2
Machine Operator 55000 30 264.6 22/09/17 2
Journalist 55000 47 264.6 22/09/17 2
Welder 53000 33 274.6 02/10/17 2
Secondary Teacher 50000 60 291.1 19/10/17 2
Glazier 50000 30 291.1 19/10/17 2
Sign Writer 48000 38 303.2 31/10/17 2
Forester 47000 33 309.7 06/11/17 2
Primary Teacher 47000 43 309.7 06/11/17 2
Construction Worker 45000 30 323.5 20/11/17 2
Store Manager 45000 30 323.5 20/11/17 2
Hospitality Manager 42000 45 346.6 13/12/17 2
Handy-person 42000 33 346.6 13/12/17 2
Office Administrator 40000 25 363.9 30/12/17 2
Butcher 40000 23 363.9 30/12/17 2
Chef 39000 28 373.2 09/01/18 2
Data Entry 37000 19 393.4 29/01/18 2
Cleaner 37000 30 393.4 29/01/18 2
Waiting Staff 35000 20 415.9 20/02/18 2
Tour Guide 35000 35 415.9 20/02/18 2
Kitchen Staff 32000 17 454.9 31/03/18 2
Retail Assistant 32000 20 454.9 31/03/18 2
Fonterra CEO 8320000 1.7 02/01/17 3 https://www.stuff.co.nz/business/farming/97212718/fonterra-ceo-theo-spierings-paid-832m-this-year
Spark CEO 2741215 5.3 06/01/17 3 http://www.nzherald.co.nz/business/news/article.cfm?c_id=3&objectid=11898297
Freightways CEO 1050116 13.9 14/01/17 3 http://www.nzherald.co.nz/business/news/article.cfm?c_id=3&objectid=11898296
Restaurant Brands CEO 699999 20.8 21/01/17 3 http://www.nzherald.co.nz/business/news/article.cfm?c_id=3&objectid=11898298
Xero CEO 395000 36.8 06/02/17 3 http://www.nzherald.co.nz/business/news/article.cfm?c_id=3&objectid=11898299
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-annotation/2.1.0/d3-annotation.min.js"></script>
<style>
body { margin:0;top:0;right:0;bottom:0;left:0; font: 14px sans-serif;}
</style>
</head>
<body>
<script>
var width = 670,
height = 2800,
svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height),
cent_line_x = width / 2 - 20,
start_day = new Date(2017, 0, 1),
end_day = new Date(2018, 3, 1),
days = d3.timeDays(start_day, end_day),
y = d3.scaleTime()
.range([10, height-10])
.domain(d3.extent(days, function(d) { return d; })),
dateParser = d3.timeParse("%d/%m/%y");
// build up our queue
var q = d3.queue()
.defer(d3.csv, 'earnings.csv')
.await(visualize);
function visualize(errors, earnings) {
//earnings = earnings.filter(function(d) { return d.Use === '1' })
earnings.forEach(function (d) {
d.date = dateParser(d.date)
d.annual_salary = +d.annual_salary
})
earnings.sort(function(x, y){ return d3.descending(x.annual_salary, y.annual_salary) })
months = days.filter(function(d) { return d.getDate() === 1 })
var profession_nest = d3.nest()
.key(function(d) { return d.category + ':' + d.date; })
.rollup(function(leaves) { return {
'count': leaves.length,
'date': leaves[0].date,
'category': leaves[0].category,
'title': dateLabel(leaves[0].date) + ' – ' + dollarLabels(leaves[0].annual_salary),
'label': leaves.map(function(d) {return d.person_group}).join(', '),
'leaves':leaves
};})
.entries(earnings);
const annotations = profession_nest.map(function(d, i){
return {
note: {
label: d.value.title,
title: d.value.label,
wrap: 250,
align: 'middle',
lineType:'vertical'
},
connector: {end: 'dot'},
x: cent_line_x,
y: y(d.value.date),
dy: 0,
dx: d.value.category === '2' ? 100 : -100,
color: col(d.value.category)
};
})
// build the annotations
const makeAnnotations = d3.annotation()
.type(d3.annotationLabel) //annotationCalloutElbow
.notePadding(10)
.annotations(annotations)
svg.append("line")
.style("stroke", "#999")
.attr("x1", cent_line_x)
.attr("y1", y(start_day))
.attr("x2", cent_line_x)
.attr("y2", y(end_day));
// draw the day markers for 1st of tha month
var day_markers = svg.selectAll("day_markers")
.data(months)
.enter().append("line")
.attr("x1", cent_line_x-3)
.attr("y1", function(d) { return y(d); })
.attr("x2", cent_line_x+3)
.attr("y2", function(d) { return y(d); })
.style("fill", "none")
.style("stroke", '#222');
var day_markers = svg.selectAll("day_markers")
.data(days)
.enter().append("line")
// emphasise if it's the 1st of tha month...
.attr("x1", function(d) {
return d.getDate() === 1 ? cent_line_x-3 : cent_line_x-1;
})
.attr("y1", function(d) { return y(d); })
.attr("x2", function(d) {
return d.getDate() === 1 ? cent_line_x+3 : cent_line_x+1;
})
.attr("y2", function(d) { return y(d); })
.style("fill", "none")
.style("stroke", function(d) {
return d.getDate() === 1 ? '#222' : "#999";
});
var month_labels = svg.selectAll("month_labels")
.data(months)
.enter().append("text")
.attr("x", cent_line_x-15)
.attr("y", function(d) { return y(d); })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.attr("transform", null)
.text(function(d) { return dateLabel(d); });
// append the annotations to our svg
d3.select("svg")
.append("g")
.attr("class", "annotation-group")
.call(makeAnnotations)
}
function col(category) {
const cols = {
1: '#E8336D',
2: '#19323C',
3: '#006477'
}
return cols[category]
}
function dateLabel(dt) {
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return monthNames[dt.getMonth()] + ' ' + dt.getDate();
}
function dollarLabels(num) {
if (num >= 1000000) {
return '$' + (num / 1000000).toFixed(1) + 'm'
}
return '$' + Math.round(num / 1000) + 'k'
}
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment