Basic architecture of a chart component

  • Chart components should be a class with an idempotent draw menthod.
class MyComponentChart {
  draw() {
    // idempotent d3 stuff...
  }
}
  • Configuration should be set with getter-setter methods. (We have three for most charts.)
class MyComponentChart {
  // Selected root element of the chart
  selection(selector){
    if(!selector) return this._selection;
    this._selection = d3.select(selector);
    return this;
  }

  // Display props like colors and arbitrary data
  props(obj) {
    // ...
  }

  // Chart data!
  data(arr) {
    // ...
  }

  draw() {
    this.selecion()
      .appendSelect('svg');
    //...
  }
}
  • Configuration should support defaults.
import merge from 'lodash/merge';

class MyComponentChart {
  defaultProps = {
    stroke: '#333',
    fill: 'orange',
  }

  props(obj){
    // If no props set, return defaults
    if(!obj) return this._props || this.defaultProps;
    // If props set, merge with current props or defaults
    this._props = merge(
      this._props || this.defaultProps,
      obj
    );

    return this;
  }

  draw() {
    const { fill } = this.props();

    this.selecion()
      .appendSelect('svg');
      .attr('background', fill)

    //...
  }
}

// In use...
const chart = new MyComponentChart();

chart.props({ fill: 'blue' });

chart.props();
// { fill: 'blue', stroke: '#333' }