JSFiddle - React, Tailwind, and code Playground

by JaelB

HTML

<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.6/dc.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dc/3.0.6/dc.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

  <body>
    <div id='select'></div>
    <div id='stack'></div>
  </body>

</html>

JavaScript

var sel = dc.selectMenu('#select');
var stack = dc.barChart('#stack');

var timeFmt = d3.timeParse('%d-%b-%Y %H:%M');
var numberFormat = d3.format('.2f');

d3.csv('https://raw.githubusercontent.com/JaelB/Generic-DC.js-Chart/master/fiddle3.csv').then(function(data) {

  data.forEach(function(d) {
    d.date = timeFmt(d.date);
    d.avg = +numberFormat(d.avg);
  });

  var ndx = crossfilter(data);
  var all = ndx.groupAll();

  //////////////Dimensions and Groups//////////////////

  var ship = ndx.dimension(function(d) {
    return [d.name, d.code];
  });
  var voyage = ndx.dimension(function(d) {
    return d.no;
  });
  var subVoyage = ndx.dimension(function(d) {
    return [d.no, d.sub_no];
  });

  var XDimension = ndx.dimension(function(d) {
    return d.no;
  });

  var YDimension_before = XDimension.group().reduce(
    function(p, d) {
      p[d.sub_no] = (p[d.sub_no] || 0) + +d.avg;
      return p;
    },
    function(p, d) {
      p[d.sub_no] = (p[d.sub_no] || 0) - +d.avg;
      return p;
    },
    function() {
      return {};
    })


  var dateDimension = ndx.dimension(function(d) {
    return [d.date, d.no, d.sub_no, d.type];
  });
  var lineGroup = dateDimension.group().reduceSum(function(d) {
    if (d.type == 'X' || d.type == 'Y')
      return +d.main;
    else return null;
  });


  /////////External functions///////////
  function sel_stack(subvoy) {
    return function(dataItem) {
      return dataItem.value[subvoy];
    };
  }


  YDimension = remove_competely_empty_bins(YDimension_before);


  sel.dimension(ship)
    .group(ship.group())
    .controlsUseVisibility(true)
    .title(function(d) {
      return d.key[0] + '-' + d.key[1];
    })
    .promptText('Select');

  stack.width(550)
    .height(400)
    .dimension(XDimension)
    .group(YDimension, '1', sel_stack(1))
    .transitionDuration(500)
    .xUnits(dc.units.ordinal)
    .x(d3.scaleBand())
    .margins({
      left: 80,
      top: 20,
      right: 80,
      bottom: 80
    })
   ...