JSFiddle - React, Tailwind, and code Playground

by djacu2

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter2/1.5.4/crossfilter.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/4.2.7/dc.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
    <title>dc.js - Series Chart Example</title>
    <meta charset="UTF-8">
    <!-- <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"> -->
    <!-- <link rel="stylesheet" type="text/css" href="../css/dc.css"/> -->
</head>
<body>

<div class="container">
  <div id="hair-color-chart"></div>
</div>

</body>

<pre id="hairdata">
Date,Hair Color,Age...

CSS

pre {
   display: none;
 }

 body {
   background: #EEE;
   color: #222;
   width: 100%;
   font-family: 'Exo 2', sans-serif;
 }

.dc-chart path.line {
  fill: none;
  }

JavaScript

function createCumulativeGroupForSeries(source_group) {
	return {
		all: function() {
			var cumulate = {};
			return source_group.all().map(function(d) {
				if (cumulate[d.key[1]]) {
					cumulate[d.key[1]] += d.value;
				} else {
					cumulate[d.key[1]] = d.value;
				}
				return { key: d.key, value: cumulate[d.key[1]] };
			});
		}
	};
}

var parseDate = d3.timeParse("%m/%d/%y");
var dataDateRange = [parseDate('01/01/21'), parseDate('01/05/21')];


var hairData = d3.csvParse(d3.select("#hairdata").text())
var cf = crossfilter(hairData);
var hairDim = cf.dimension(d => {
	return [
  	parseDate(d.Date).valueOf(),
    d['Hair Color'],
    d['Age Group'] // comment this column in and out to see the switch between smooth lines and steps
  ]
});
var hairGroup = hairDim.group().reduceSum(d => +d.Value);


var seriesChart = new dc.SeriesChart("#hair-color-chart");
seriesChart
	.width(600)
  .height(300)
	.chart(function(c) { return new dc.LineChart(c).curve(d3.curveLinear); })
  .x(d3.scaleTime().domain(dataDateRange))
  .yAxisLabel("Cumulative Value")
  .xAxisLabel("Date")
	.dimension(hairDim)
	.group(createCumulativeGroupForSeries(hairGroup))
  .seriesAccessor(d => d.key[1])
  .keyAccessor(d => d.key[0])
  .valueAccessor(d => +d.value)
  .legend(dc.legend().x(60).y(10).itemHeight(13).gap(5).horizontal(1).legendWidth(70).itemWidth(70));
seriesChart.margins().left += 10;
seriesChart.xAxis().ticks(5);
seriesChart.xAxis().tickFormat(d3.timeFormat('%m/%d/%y'));
  
dc.renderAll();