DC.JS

Example of creating an external chart and attaching it to the dc.js chart registry.<

HTML

<!DOCTYPE html>
<html lang="en">

  <head>
    <title>dc.js - Custom Chart Example</title>
    <meta charset="UTF-8">
    <link rel="stylesheet" type="text/css" href="//dc-js.github.io/dc.js/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="//unpkg.com/dc@4/dist/style/dc.css" />

    <script src="//d3js.org/d3.v5.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter2/1.4.4/crossfilter.min.js"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/dc/3.2.1/dc.min.js"></script>
    <script src="//npmcdn.com/d3-horizon-chart/build/d3-horizon-chart.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/linq.js/2.2.0.2/linq.js"></script>
  </head>

  <body>

    <div class="container">
      <div id="test-overview"></div>
      <br />
      <div id="test-hc"></div>

    </div>
  </body>

</html>

CSS

body {
        margin: 0;
        padding: 0;
    }

    .horizon {
        border-top: solid 1px #000;
        border-bottom: solid 1px #000;
        overflow: hidden;
        position: relative;
    }

    .horizon + .horizon {
        border-top: none;
    }

    .horizon canvas {
        display: block;
        image-rendering: pixelated;
    }

  .horizon .title,
  .horizon .value {
      bottom: 0;
      line-height: 30px;
      margin: 0 6px;
      position: absolute;
      font-family: sans-serif;
      text-shadow: 0 1px 0 rgba(255,255,255,.5);
      white-space: nowrap;
  }

  .horizon .title {
      left: 0;
  }

  .horizon .value {
      right: 0;
  }

JavaScript

class dcChart {
  constructor(parent, groupByKeyName, valueKeyName, group) {
    this._group = null;
    this._dimension = null;
    
    this._groupByKeyIdx = groupByKeyName;
    this._valueKeyName = valueKeyName;

    this._root = d3.select(parent);
    dc.registerChart(this, group);
  }
  
  cf(data) {
    this._cf = data;
    return this;
  }
  
  dimension(data) {
    this._dimension = data;
    return this;
  }
  
  group(data) {
    this._group = data;
    return this;
  }

  render() {
    console.log("called once");
    this.redraw();
  }

  redraw() {
  		this._root.html(this._dimension.hasCurrentFilter() + " " + this._group.all().length)
      console.log(this._dimension.hasCurrentFilter())
      console.log(this._group.all())
  }
 

}

function loadStockData(stock, callback) {
  d3.csv('https://bost.ocks.org/mike/cubism/intro/stocks/' + stock + '.csv').then(function(rows) {
    rows = rows.map(function(d) {
      return [d3.timeParse(d.Date), +d.Open];
    }).filter(function(d) {
      return d[1];
    }).reverse();

    var date = rows[0][0],
      compare = rows[400][1],
      value = rows[0][1],
      values = [],
      indices = [];

    rows.forEach(function(d, i) {
      values.push(value = (d[1] - compare) / compare);
      indices.push(i);
    });


    callback({
      'stock': stock,
      'values': values,
      'indices': indices
    });
  });
}

var promises = [];
['AAPL', 'GOOG', 'MSFT'].forEach(function(stock) {
  promises.push(new Promise(function(resolve, reject) {
    var r = loadStockData(stock, resolve);
  }));
});

Promise.all(promises).then(function(stocks) {
  console.log(stocks);

  var data = [];

  for(var i = 0; i < stocks.length; i++) {
    for(var j= 0; j < stocks[i].indices.length; j++) {
        data.push({ 'idx':stocks[i].indices[j], 'name': stocks[i].stock, 'value': stocks[i].values[j] })
    }
  }
  
  var ndx, runDimension, runGroup, overviewRunDimension, overviewRunGroup;
  ndx = crossfilter(data);
 ...