Built with blockbuilder.org
forked from SpaceActuary's block: Mini Chart
forked from SpaceActuary's block: Mini Charts
license: mit |
Built with blockbuilder.org
forked from SpaceActuary's block: Mini Chart
forked from SpaceActuary's block: Mini Charts
group | year | amount1 | amount2 | amount3 | |
---|---|---|---|---|---|
ABC | 2010 | 11124 | 50.236 | 0.558825264 | |
ABC | 2011 | 11433 | 51.577 | 0.589679841 | |
ABC | 2012 | 11914 | 49.006 | 0.583857484 | |
ABC | 2013 | 11734 | 48.706 | 0.571516204 | |
ABC | 2014 | 12222 | 50.496 | 0.617162112 | |
ABC | 2015 | 11943 | 52.802 | 0.630614286 | |
XYZ | 2010 | 13349 | 51.241 | 0.68401611 | |
XYZ | 2011 | 11204 | 56.735 | 0.63565894 | |
XYZ | 2012 | 10603 | 40.675 | 0.43127703 | |
XYZ | 2013 | 9387 | 44.81 | 0.42063147 | |
XYZ | 2014 | 10144 | 59.08 | 0.59930752 | |
XYZ | 2015 | 11226 | 44.354 | 0.497918 | |
Total | 2010 | 12248 | 50.437 | 0.61775238 | |
Total | 2011 | 11313 | 52.609 | 0.59516562 | |
Total | 2012 | 11319 | 47.34 | 0.53584146 | |
Total | 2013 | 10609 | 47.927 | 0.50845754 | |
Total | 2014 | 11102 | 52.213 | 0.57966873 | |
Total | 2015 | 11616 | 51.112 | 0.59371699 |
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet' type='text/css'> | |
<style> | |
body { | |
margin: 0;position:fixed;top:0;right:0;bottom:0;left:0; | |
font-family: 'Montserrat', sans-serif; | |
font-size: 14px; | |
} | |
div { | |
display: inline; | |
margin: 20px 0px 0px 20px; | |
} | |
.spark { | |
fill: none; | |
stroke: steelblue; | |
stroke-width: 1.5px; | |
} | |
.point { | |
fill: steelblue; | |
stroke: #fff; | |
stroke-width: 3px; | |
} | |
.label, | |
.change, | |
.axis, | |
.main { | |
text-anchor: middle; | |
alignment-baseline: middle; | |
fill: #aaa; | |
} | |
.change, | |
.main { | |
text-anchor: middle; | |
alignment-baseline: middle; | |
fill: #333; | |
} | |
line.axis { | |
stroke: #aaa; | |
stroke-width: 1.5px; | |
} | |
</style> | |
</head> | |
<body> | |
<script> | |
console.clear(); | |
var changeFormat = d3.format(".1f"), | |
numberFormat = d3.format(",.0f"); | |
d3.csv("data.csv", function(raw){ | |
var data_ABC = raw.filter(function(d){ return d.group == "ABC"}), | |
data_XYZ = raw.filter(function(d){ return d.group == "XYZ"}), | |
data_Total = raw.filter(function(d){ return d.group == "Total"}); | |
var miniChart1 = miniChart() | |
.xValue(function(d){ return +d.year; }) | |
.yValue(function(d){ return +d.amount1; }) | |
.numberFormat(d3.format(",.0f")); | |
var miniChart2 = miniChart() | |
.xValue(function(d){ return +d.year; }) | |
.yValue(function(d){ return +d.amount2; }) | |
.numberFormat(d3.format(".2f")); | |
var miniChart3 = miniChart() | |
.xValue(function(d){ return +d.year; }) | |
.yValue(function(d){ return +d.amount3; }) | |
.numberFormat(d3.format(".1%")); | |
d3.select("body").append("div") | |
.datum(data_ABC) | |
.call(miniChart1); | |
d3.select("body").append("div") | |
.datum(data_ABC) | |
.call(miniChart2); | |
d3.select("body").append("div") | |
.datum(data_ABC) | |
.call(miniChart3); | |
d3.select("body").append("div") | |
.datum(data_XYZ) | |
.call(miniChart1); | |
d3.select("body").append("div") | |
.datum(data_XYZ) | |
.call(miniChart2); | |
d3.select("body").append("div") | |
.datum(data_XYZ) | |
.call(miniChart3); | |
d3.select("body").append("div") | |
.datum(data_Total) | |
.call(miniChart1); | |
d3.select("body").append("div") | |
.datum(data_Total) | |
.call(miniChart2); | |
d3.select("body").append("div") | |
.datum(data_Total) | |
.call(miniChart3); | |
}); | |
function dataPrep(raw, xValue, yValue) { | |
var rough = [{x: NaN, y: NaN}]; | |
//console.log("rough 1",rough); | |
raw.forEach(function(d, i, data){ | |
rough.push({ | |
x: xValue(d, i, data), | |
y: yValue(d, i, data) | |
}); | |
}); | |
//console.log("rough 2", rough); | |
var dataPairs = d3.pairs(rough); | |
//console.log("dataPairs",dataPairs) | |
var data = dataPairs.map(function(d){ | |
var d0 = d[0], | |
d1 = d[1]; | |
d1.y_delta = (d1.y / d0.y) - 1; | |
return d1; | |
}); | |
//console.log("data 3",data); | |
return data; | |
} | |
function miniChart() { | |
var margin = {top: 20, bottom: 80, left: 80, right: 20}, | |
height = 170 - margin.top - margin.bottom, // default height | |
width = 280 - margin.left - margin.right, // default width | |
changeFormat = d3.format(".1f"), | |
numberFormat = d3.format(",.0f"), | |
xValue = function(d, i){ return i; }, | |
yValue = function(d, i){ return i; }, | |
xScale = d3.scalePoint(), | |
yScale = d3.scaleLinear(), | |
line = d3.line() | |
.x(function(d, i, data){ return xScale(d.x); }) | |
.y(function(d, i, data){ return yScale(d.y); }); | |
function chart(selection) { | |
selection.each(function(raw){ | |
var chartData = dataPrep(raw, xValue, yValue); | |
console.table(chartData); | |
var yExt = d3.extent(chartData, function(d){ return d.y; }); | |
xScale | |
.domain(chartData.map(function(d){ return d.x; })) | |
.range([0, width]); | |
yScale | |
.domain(yExt).nice() | |
.range([height, 0]); | |
// Select the svg element, if it exists. | |
var svg = d3.select(this).selectAll("svg").data([chartData]); | |
// Otherwise, create the skeletal chart. | |
var svgEnter = svg.enter().append("svg") | |
svgEnter.append("g").append("g").attr("class", "y axis"); | |
// Update the outer dimensions. | |
svg = svgEnter.merge(svg) | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom); | |
/* | |
svg.insert("rect") | |
.attr("fill", "#ddd") | |
.attr("opacity", 0.2) | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom); | |
svg.insert("rect") | |
.attr("fill", "#aaa") | |
.attr("opacity", 0.2) | |
.attr("x", margin.left) | |
.attr("y", margin.top) | |
.attr("width", width) | |
.attr("height", height); | |
*/ | |
// Update the inner dimensions. | |
var g = svg.select("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
// Update the Y Axis | |
var yAxis = g.select(".y.axis") | |
.attr("transform", "translate(" + (-margin.left / 2) + "," + 0 + ")"); | |
// Update the lines | |
var spark = g.append("path").datum(chartData) | |
.attr("class", "spark") | |
.attr("d", line); | |
// Update the points | |
var points = g.selectAll("circle.point").data(chartData); | |
points.enter() | |
.append("circle").attr("class", "point") | |
.merge(points) | |
.attr("cx", function(d, i, data){ return xScale(d.x); }) | |
.attr("cy", function(d, i, data){ return yScale(d.y); }) | |
.attr("r", 5) | |
var labels = svg.selectAll("text.label").data(chartData); | |
labels.enter() | |
.append("text").attr("class", "label") | |
.merge(labels) | |
.text(function(d){ return d.x; }) | |
.attr("transform", "translate(" + margin.left + "," + | |
(height+margin.top) + ")") | |
.attr("x", function(d){ return xScale(d.x); }) | |
.attr("y", 20) | |
var changes = svg.selectAll("text.change") | |
.data(chartData.filter(function(d){ return !isNaN(d.y_delta); })); | |
changes.enter() | |
.append("text").attr("class", "change") | |
.merge(changes) | |
.text(function(d){ return changeFormat(d.y_delta * 100); }) | |
.attr("transform", "translate(" + margin.left + "," + | |
(height+margin.top) + ")") | |
.attr("x", function(d){ return xScale(d.x); }) | |
.attr("y", 40) | |
yAxis.append("text").attr("class", "axis max") | |
.text(numberFormat(yExt[1])) | |
.attr("y", yScale(yExt[1])); | |
yAxis.append("line").attr("class", "axis") | |
.attr("x1", 0) | |
.attr("y1", yScale(yExt[1]) + 10) | |
.attr("x2", 0) | |
.attr("y2", yScale(yExt[0]) - 10); | |
yAxis.append("text").attr("class", "axis min") | |
.text(numberFormat(yExt[0])) | |
.attr("y", yScale(yExt[0])); | |
svg.append("text").text("YOY % Chg").attr("class", "main") | |
.attr("transform", "translate(" + 0 + "," + (height+margin.top) + ")") | |
.attr("x", 50) | |
.attr("y", 40); | |
}); | |
} | |
chart.width = function(_) { | |
if (!arguments.length) return width; | |
width = _; | |
return chart; | |
}; | |
chart.height = function(_) { | |
if (!arguments.length) return height; | |
height = _; | |
return chart; | |
}; | |
chart.xValue = function(_) { | |
if (!arguments.length) return xValue; | |
xValue = _; | |
return chart; | |
}; | |
chart.yValue = function(_) { | |
if (!arguments.length) return yValue; | |
yValue = _; | |
return chart; | |
}; | |
chart.numberFormat = function(_) { | |
if (!arguments.length) return numberFormat; | |
numberFormat = _; | |
return chart; | |
}; | |
chart.changeFormat = function(_) { | |
if (!arguments.length) return changeFormat; | |
changeFormat = _; | |
return chart; | |
}; | |
return chart; | |
} | |
</script> | |
</body> |