Last active
July 28, 2017 11:56
-
-
Save pjsier/bbb5540138eb9b325cc8399b4488b560 to your computer and use it in GitHub Desktop.
Square Area 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
license: mit |
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> | |
<head> | |
<title>Square Area Chart</title> | |
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> | |
<meta charset='utf-8' /> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
} | |
#chart { | |
max-width: 600px; | |
max-height: 400px; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="chart"></div> | |
<script src="script.js"></script> | |
<script> | |
var chart = squareAreaChart(); | |
var data = [ | |
{data: 1024, label: "attempted"}, | |
{data: 558, label: "completed"}, | |
{data: 26, label: "call-ins"} | |
]; | |
function resize() { | |
if (d3.select("#chart svg").empty()) { | |
return; | |
} | |
var w = +d3.select("#chart").style("width").replace(/(px)/g, ""); | |
chart.width(w); | |
chart.height(w*(400/600)); | |
d3.select("#chart").call(chart); | |
} | |
document.addEventListener("DOMContentLoaded", function() { | |
d3.select("#chart").datum(data).call(chart); | |
d3.select(window).on('resize', resize); | |
}); | |
</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
function squareAreaChart() { | |
var margin = {top: 20, right: 20, bottom: 20, left: 20}, | |
width = 600, | |
height = 400, | |
dataValue = function(d) { return +d.data; }, | |
labelValue = function(d) { return d.label; }, | |
color = ["#fee0d2", "#fc9272", "#de2d26"]; | |
function chart(selection) { | |
selection.each(function(data) { | |
data = data.map(function(d) { | |
return { value: dataValue(d), label: labelValue(d) }; | |
}); | |
data.sort(function(a, b) { return b.value - a.value; }); | |
// Rect scale should be on squared height (for area, and height is more constrained) | |
var sqScale = d3.scaleLinear() | |
.range([0, Math.pow(height-margin.left-margin.right, 2)]); | |
var sqMax = d3.max(data, function(d) { return d.value; }); | |
sqScale.domain([0, sqMax]); | |
var svg = d3.select(this).selectAll("svg").data([data]); | |
var gEnter = svg.enter().append("svg").append("g"); | |
gEnter.append("g").attr("class", "rects") | |
.selectAll(".data-rects").data(data).enter() | |
.append("rect").attr("class", "data-rects"); | |
gEnter.selectAll("line.legend") | |
.data(data).enter() | |
.append("line").attr("class", "legend"); | |
gEnter.selectAll("text.legend") | |
.data(data).enter() | |
.append("text") | |
.attr("class", "legend") | |
.attr("font-size", 12); | |
var svg = selection.select("svg"); | |
svg.attr('width', width).attr('height', height); | |
var g = svg.select("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
g.selectAll(".data-rects") | |
.data(data) | |
.attr("x", function(d) { return Math.sqrt(sqScale(sqMax)) - Math.sqrt(sqScale(d.value)); }) | |
.attr("y", function(d) { return Math.sqrt(sqScale(sqMax)) - Math.sqrt(sqScale(d.value)); }) | |
.attr("width", function (d) { return Math.sqrt(sqScale(d.value)); }) | |
.attr("height", function (d) { return Math.sqrt(sqScale(d.value)); }) | |
.attr("fill", function (d, i) { return color[i]; }); | |
// Getting midpoint for legend | |
function legendY(d, i) { | |
var start = Math.sqrt(sqScale(sqMax)) - Math.sqrt(sqScale(d.value)); | |
if (i === (data.length - 1)) { | |
var diff = Math.sqrt(sqScale(d.value)); | |
} | |
else { | |
var diff = Math.sqrt(sqScale(d.value)) - Math.sqrt(sqScale(data[i+1].value)); | |
} | |
return start + (diff/2); | |
} | |
g.selectAll("line.legend") | |
.data(data) | |
.attr("x1", function() { return Math.sqrt(sqScale(sqMax)) + 10; }) | |
.attr("x2", function() { return Math.sqrt(sqScale(sqMax)) + 45; }) | |
.attr("y1", legendY) | |
.attr("y2", legendY) | |
.attr("stroke", "#000000") | |
.attr("stroke-width", 0.5); | |
g.selectAll("text.legend") | |
.data(data) | |
.attr("x", function() { return Math.sqrt(sqScale(sqMax)) + 50; }) | |
.attr("y", function(d, i) { return legendY(d, i) + 5; }) | |
.text(function(d) { return d3.format(",")(d.value) + " " + d.label; }); | |
}); | |
} | |
chart.margin = function(_) { | |
if (!arguments.length) return margin; | |
margin = _; | |
return chart; | |
}; | |
chart.width = function(_) { | |
if (!arguments.length) return width; | |
width = _; | |
return chart; | |
}; | |
chart.height = function(_) { | |
if (!arguments.length) return height; | |
height = _; | |
return chart; | |
}; | |
chart.dataValue = function(_) { | |
if (!arguments.length) return dataValue; | |
dataValue = _; | |
return chart; | |
}; | |
chart.labelValue = function(_) { | |
if (!arguments.length) return labelValue; | |
labelValue = _; | |
return chart; | |
}; | |
chart.color = function(_) { | |
if (!arguments.length) return color; | |
color = _; | |
return chart; | |
}; | |
return chart; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment