xxxxxxxxxx
<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()
.curve(d3.curveCatmullRom.alpha(0.5))
.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>
https://d3js.org/d3.v4.min.js