D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
pstuffa
Full window
Github gist
Running IX
<!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 12px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } </style> <body> <h1 id="title">Numbers of Runs by Day of Week</h1> <div id="dropdown"></div> <div id="chart"></div> <div id="mouseover"> </div> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="//d3js.org/d3-scale-chromatic.v0.3.min.js"></script> <script> var margin = {top: 20, right: 20, bottom: 30, left: 40}, width = 960 - margin.left - margin.right, height = 400 - margin.top - margin.bottom; var x = d3.scaleBand() .padding([.1]) .rangeRound([0, width]); var y = d3.scaleLinear() .range([height, 0]); var numberFormat = d3.format(",d") var svg = d3.select("#chart").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.tsv("running.tsv", function(error, data) { if (error) throw error; data.forEach(function(d) { d["Distance"] = +d["Distance"]; d["Elevation Gain"] = +d["Elevation Gain"]; d["Avg HR"] = +d["Avg HR"]; d["Max HR"] = +d["Max HR"]; }); var dateOrder = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] // Aggregate data var nestedData = d3.nest() .key(function(d) { return d["Day of Week"]}) .rollup(function(leaves) { return { "Distance": d3.sum(leaves, function(d) { return d["Distance"]}), "Number of Runs": leaves.length, "Avg HR": d3.mean(leaves, function(d) { return d["Avg HR"]}), "Elevation Gain": d3.sum(leaves, function(d) { return d["Elevation Gain"]}), "Max HR": d3.max(leaves, function(d) { return d["Max HR"]}) } }) .entries(data); var options = ["Distance","Elevation Gain","Avg HR","Max HR"]; x.domain(d3.set(data.map(function(d) { return d["Day of Week"]; })).values().sort(function(a,b) { return dateOrder.indexOf(a) - dateOrder.indexOf(b); })); x.domain(dateOrder); y.domain(d3.extent(nestedData.map(function(d) { return d.value["Number of Runs"] }))).nice(); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)) svg.append("g") .attr("class", "y axis") .call(d3.axisLeft(y)) var color = d3.scaleOrdinal(d3.schemeSet3); // Add custom scales var elevationColor = d3.scaleLinear() .range(["white", "steelblue"]) .domain(d3.extent(nestedData.map(function(d) { return d.value["Elevation Gain"] }))) svg.selectAll(".bar") .data(nestedData) .enter().append("rect") .attr("class",function(d) { return "bar " + d.value["Day of Week"]; }) .attr("width", x.bandwidth()) .attr("height", function(d) { return height - y(d.value["Number of Runs"]); }) .attr("x", function(d) { return x(d.key); }) .attr("y", function(d) { return y(d.value["Number of Runs"]); }) // Adjusting by color .style("stroke", "#000") .style("fill", "steelblue") // .style("fill", function(d) { return elevationColor(d.value["Elevation Gain"]); }) .style("fill", function(d) { return color(d.key); }) // Adding interactions .on("mouseenter", function(d) { d3.select("#mouseover") .text(d.key + ": " + d.value["Number of Runs"] + " runs, " + numberFormat(d.value["Distance"]) + " miles ran, " + numberFormat(d.value["Elevation Gain"]) + " total elevation gain, and an average BPM of" + numberFormat(d.value["Avg HR"]) ) }) .on("mouseleave", function(d) { d3.select("#mouseover") .text(""); }) svg.selectAll(".bar-text") .data(nestedData) .enter().append("text") .attr("class",function(d) { return "bar-text " + d.value["Day of Week"]; }) .attr("x", function(d) { return x(d.key); }) .attr("y", function(d) { return y(d.value["Number of Runs"]); }) .attr("dy", -2) .text(function(d) { return numberFormat(d.value["Number of Runs"])}) // Add in other features, like a dropdown for different metrics var options = ["Number of Runs", "Elevation Gain","Distance","Avg HR","Max HR"]; var dropdown = d3.select("#dropdown") .append("select") .on("change", change); dropdown.selectAll("option") .data(options) .enter().append("option") .text(function(d) { return d; }); function change() { var column = this.value, text = column + " by Day of Week"; y.domain(d3.extent(nestedData.map(function(d) { return d.value[column] }))).nice(); d3.select("#title") .text(text) d3.selectAll(".bar") .transition() .duration(2000) .attr("height", function(d) { return height - y(d.value[column]); }) .attr("y", function(d) { return y(d.value[column]); }); d3.selectAll(".bar-text") .transition() .duration(2000) .attr("y", function(d) { return y(d.value[column]); }) .attr("dy", -2) .on("start", function repeat(d) { d3.active(this) .tween("text", function() { var that = d3.select(this), i = d3.interpolateNumber(that.text().replace(/,/g, ""), d.value[column]); return function(t) { that.text(numberFormat(i(t))); }; }) .transition() .delay(1500) .on("start", repeat); }); d3.select(".y") .transition() .call(d3.axisLeft(y)) .select(".label") .text(column) } }); </script>
https://d3js.org/d3.v4.min.js
https://d3js.org/d3-scale-chromatic.v0.3.min.js