D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
rjweise
Full window
Github gist
Personal project: 10,000 hours tracking
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>The 10,000 hour rule for data visualization - RJ Weise on NoTime2Read</title> <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> <style type="text/css"> body { background-color: rgb(253, 232, 221); font-family: Helvetica, Arial, sans-serif, Georgia, serif; width: 100%; margin: 10px, 10px, 10px, 10px; color: black; } h1 { font-size: 24px; font-family: Helvetica, sans-serif; color: rgb(90, 90, 90); } #Header { width: 90%; } p { font-size: 14px; font-family: Georgia, serif; max-width: 90%; word-wrap: break-word; } #logo { width: 25px; position: fixed; top: 0; right: 0; } svg { background-color: rgb(253, 232, 221); font-size: 14px; font-family: Georgia, serif; margin-top: 20px; } path:hover { stroke: rgb(242,107,33); } rect:hover { fill: rgb(242,107,33); } .axis path, .axis line { fill: none; stroke: black; shape-rendering: crispEdges; } .axis text { font-family: Georgia, sans-serif; font-size: 11px; stroke: none; fill: black; } .label { font-size: 11px; font-family: Georgia; stroke: none; fill: black; } </style> </head> <body> <h1 ID="Header">The 10,000 hour rule on my data visualization experience</h1> <div ID="logo"> <img src="https://rjweise.neocities.org/logoRJW2.png" alt="Logo NT2R RJ" style="width:25px;height:25px"> </div> <p>After taking part in the Information Visualization MOOC by the University of Indiana, and the D3 MOOC at the Knight Center for Journalism I got curious how many hours I have spent in my career on work related to data visualization. I created a simple table in which I estimated my experience in number of hours worked per year, the productivity on the job (actual work excluding meetings, flex days, training and such) and what percentage of these productive hours were applicable to count towards data visualization.<br /><br /> The following graph shows three cumulative-hours-lines: one for a bare minimum estimate, one based on generous estimates, and a last line showing the average between the two. The bar graph at the bottom shows the average (non-cumulative) hours per year.</p> <script type="text/javascript"> //Majority of code based on Knight D3 MOOC, module 6, example 4, by @alignedleft (Scott Murray) // Setting Dimensions and padding of the SVG var w = 960; var h = 600; var padding = [ 20, 120, 20, 60 ]; //Top, right, bottom, left // Setting up date formatting and years var dateFormat = d3.time.format("%Y"); // Setting up scales (range is pixels) var xScale = d3.time.scale() .range([ padding[3], w - padding[1] - 30]); var yScale = d3.scale.linear() .range([ padding[0], h - padding[2] ]); // Configuring the axis generators var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .ticks(15) .tickFormat(function(d) { return dateFormat(d); }); var yAxis = d3.svg.axis() .scale(yScale) .orient("left") .ticks(20); // Configuring the minimum value line generator var linemin = d3.svg.line() .x(function(d) { return xScale(dateFormat.parse(d.year)); }) .y(function(d) { return yScale(d.mincumu); }); // Configuring the maximum value line generator var linemax = d3.svg.line() .x(function(d) { return xScale(dateFormat.parse(d.year)); }) .y(function(d) { return yScale(d.maxcumu); }); // Configuring a reference line generator var lineref = d3.svg.line() .x(function(d) { return xScale(dateFormat.parse(d.year)); }) .y(function(d) { return yScale(10000); }); //configuring a reference area for 10,000 hours var arearef = d3.svg.area() .x(function(d) { return xScale(dateFormat.parse(d.year)); }) .y(function(d) { return yScale(10000); }) .y0(function(d) { return yScale(0); }); // Configuring an average line generator var lineavg = d3.svg.line() .x(function(d) { return xScale(dateFormat.parse(d.year)); }) .y(function(d) { return yScale((+d.maxcumu + +d.mincumu)/2) //, console.log((+d.maxcumu + +d.mincumu) / 2) ; }); // Creating the empty SVG canvas var svg = d3.select("body") .append("svg") .attr("width", w) .attr("height", h); // Loading the 10000hours data - mincumu d3.csv("10000hoursValuesYear.csv", function(Dataset) { // Using the data to determine the min and max values, for setting scale domains (domains is data) xScale.domain([ d3.min(Dataset, function(d) { return dateFormat.parse(d.year); }), d3.max(Dataset, function(d) { return dateFormat.parse(d.year) //, console.log(d.year) ; }) ]); yScale.domain([ d3.max(Dataset, function(d) { return +d.maxcumu +2000 //, console.log(d.maxcumu) ; }), 0 ]); //Adding circles at intersections // var circles = svg.selectAll("circle") // .data(Dataset) // .enter() // .append("circle"); // circles.attr("cx", function(d) { // return xScale(dateFormat.parse(d.year)); // }) // .attr("cy", function(d) { // return yScale(d.maxcumu); // }) // .attr("r", 4) // .attr("fill", "steelblue") // .attr("opacity", "0.7") // .append("title") // .text(function(d) { // return d.year + "'s life satisfaction score is " + d.mincumu + ", and " + d.maxcumu + "% report good health"; // }); //Append the reference area for 10,000 hours to the svg svg.data([Dataset]) .append("path") .attr("d", arearef) .attr("fill", "dimgray") .attr("opacity", 0.1) .append("title") //.text("10.000 hours reference line") ; //Adding bars for average of min. and max total hours var rects = svg.selectAll("rect") .data(Dataset) .enter() .append("rect"); rects.attr("x", function(d) { return xScale(dateFormat.parse(d.year)) - 5;}) .attr("y", function(d) { return yScale(((+d.minttlhrs + +d.maxttlhrs) / 2));}) .attr("height", function(d) { return (h - padding[2] - yScale(((+d.minttlhrs + +d.maxttlhrs) / 2))); }) .attr("width", "10") .attr("fill", "rgb(242,107,33)") .append("title") .text(function(d) { return "Avg. hours (" + d.year + "): " + d3.round(((+d.minttlhrs + +d.maxttlhrs) / 2),1)+ ")"; }) // .text(function(d) { // return yScale(((+d.minttlhrs + +d.maxttlhrs) / 2)); // }) ; //Set stroke-width of the reference line var REFsw = 3; //Append the reference line to the svg svg.data([Dataset]) .append("path") .attr("d", lineref) .attr("fill", "none") .style("stroke-dasharray", ("5, 4")) .attr("stroke", "grey") .attr("stroke-width", REFsw) .attr("opacity", 0.5) .append("title") .text("10.000 hours reference line") ; //Append the min. value line to the svg svg.data([ Dataset ]) .append("path") //.attr("class", "mincumu") .attr("d", linemin) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 2) .attr("opacity", 0.7) .append("title") .text("Minimum number of hours"); //Append the max. value line to the svg svg.data([ Dataset ]) .append("path") //.attr("class", "maxcumu") .attr("d", linemax) .attr("fill", "none") .attr("stroke", "steelblue") .attr("stroke-width", 2) .attr("opacity", 0.7) .append("title") .text("Maximum number of hours"); //Append the reference line to the svg svg.data([ Dataset ]) .append("path") //.attr("class", "maxcumu") .attr("d", lineavg) .attr("fill", "none") .style("stroke-dasharray", ("10, 5")) .attr("stroke", "rgb(242,107,33)") .attr("stroke-width", 2) .attr("opacity", 0.5) .append("title") .text("Average number of hours"); //Axes svg.append("g") .attr("class", "axis") .attr("transform", "translate(0," + (h - padding[2]) + ")") .call(xAxis) .append("text") .attr("class", "label") .attr("x", w-padding[1] + 10) // .attr("x", w-padding[1]) .attr("y", -10) //.style("text-anchor", "end") .style("font-size", "20") //.text("Years"); svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + (padding[3]) + ",0)") .call(yAxis) .append("text") .attr("class", "label") .attr("y", padding[2]-5) .style("text-anchor", "left") .style("font-size", "20") .text("Hours"); //line labels //calculating the values for min., max., average (nr.) and average (string) line labels var MAXdisp = d3.format(",")(d3.round((Dataset[17].maxcumu),1)); var MINdisp = d3.format(",")(d3.round((Dataset[17].mincumu),1)); var AVGcalc = d3.round((((( +Dataset[17].maxcumu + +Dataset[17].mincumu) / 2)))); var AVGdisp = d3.format(",")(d3.round((((( +Dataset[17].maxcumu + +Dataset[17].mincumu) / 2))),1)); //Appending labels to end of min., max. and average lines svg.append("text") .attr("class", "label") .attr("x", w - padding[1] - 15) .attr("y", yScale(Dataset[17].maxcumu)) .text(function(d) { return (MAXdisp + " cum. hours (max.)"); }); svg.append("text") .attr("class", "label") .attr("x", w - padding[1] - 15) .attr("y", yScale(Dataset[17].mincumu)) .text(function(d) { return (MINdisp + " cum. hours (min.)"); }); svg.append("text") .attr("class", "label") .attr("x", w - padding[1] - 15) .attr("y", yScale(AVGcalc)) .text(function(d) { return (AVGdisp + " cum. hours (avg.)"); }); //Adding label for 10,000 hours svg.append("text") .attr("class", "label") .attr("x", w - padding[1] - 15 ) .attr("y", yScale(10000) + REFsw/4) .text("10,000 hours"); ; //Adding some annotation where lines cross 10,000 ref. line // svg.append("text") // .attr("class", "label") // .attr("width", "100px") // .attr("x", 610) // .attr("y", yScale(10000)) // .text("Minimum estimate crossess reference line in 2010"); // ; }); //End Dataset data load function </script> <p><br />From Wikipedia: "<i>Gladwell repeatedly mentions the "10,000-Hour Rule", claiming that the key to success in any field is, to a large extent, a matter of practicing a specific task for a total of around 10,000 hours.</i></p> </body> </html>
Modified
http://d3js.org/d3.v3.min.js
to a secure url
https://d3js.org/d3.v3.min.js