JSFiddle - React, Tailwind, and code Playground
by levvsha
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.js"></script>
<form>
<label><input type="radio" name="mode" value="multiples" checked> Multiples</label>
<label><input type="radio" name="mode" value="stacked"> Stacked</label>
</form>
CSS
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
width: 960px;
}
text {
font: 10px sans-serif;
}
.axis path {
display: none;
}
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.group-label {
font-weight: bold;
text-anchor: end;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
JavaScript
var tsvString = `group date value
1 2008-01 10
1 2008-04 8
1 2008-07 14
1 2008-10 9
1 2009-01 10
1 2009-04 8
1 2009-07 14
1 2009-10 9
2 2008-01 3
2 2008-04 3.5
2 2008-07 5
2 2008-10 11
2 2009-01 3
2 2009-04 3.5
2 2009-07 4.5
2 2009-10 10.5
3 2008-01 10
3 2008-04 8
3 2008-07 14
3 2008-10 9
3 2009-01 10
3 2009-04 8
3 2009-07 14
3 2009-10 9
4 2008-01 3
4 2008-04 3.5
4 2008-07 5
4 2008-10 11
4 2009-01 3
4 2009-04 3.5
4 2009-07 4.5
4 2009-10 10.5`;
var parseDate = d3.timeParse("%Y-%m"),
formatYear = d3.format("02d"),
formatDate = function(d) { return "Q" + ((d.getMonth() / 3 | 0) + 1) + formatYear(d.getFullYear() % 100); };
var margin = {top: 10, right: 20, bottom: 20, left: 60},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var y0 = d3.scaleBand()
.rangeRound([height, 0])
.padding(.2);
var y1 = d3.scaleLinear();
var x = d3.scaleBand()
.rangeRound([0, width])
.padding(.1);
var xAxis = d3.axisBottom()
.scale(x)
.tickFormat(formatDate);
var nest = d3.nest()
.key(function(d) { return d.group; });
var data = d3.tsvParse(tsvString);
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});
var dataByGroup = nest.entries(data);
var keys = data.columns.slice(1);
var color = d3.scaleOrdinal(d3.schemeCategory10);
var svg = d3.select("body").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 + ")");
x.domain(dataByGroup[0].values.map(function(d) { return d.date; }));
y0.domain(dataByGroup.map(function(d) { return d.key; }));
y1.domain([0, d3.max(data, function(d) { return d.value; })]).range([y0.bandwidth(), 0]);
var stack = d3.stack()
.keys(keys)(data);
var group = svg.selectAll(".group")
.data(dataByGroup)
.enter().append("g")
.attr("class", "group")
.attr("transform", function(d) { return...