Donut Chart WiP

Just a test of pie/donut chart. Relearning d3

by Trever Shick

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-transition/1.1.1/d3-transition.min.js"></script>
<script>
  const toplevel_data = ["test"];

  var data = [{
      id: 'a',
      label: 'a',
      value: 5,
      color: 'red'
    },
    {
      id: 'b',
      label: 'b',
      value: 7,
      color: 'blue'
    },
  ];


  function changeData() {
    data[0].value++;
    data[0].color = 'purple';
    data.push({
      id: 'd',
      label: 'b',
      value: 7,
      color: 'green'
    });
    toplevel_data[0] = "hackery";
    drawIt();
  }

</script>
<div id="graph" style="border:1px solid blue;width:100%;height:200px;position:relative;">
</div>
<div style="clear:both">
  <button onClick="changeData()">
    change
  </button>
</div>
<script>

</script>

JavaScript 1.7

const d3Selection = d3;
const d3Transition = d3;
const d3Shape = d3;


function drawIt() {
  render(el, data);
}
const value = x => x.value;

const defaultOffsets = {
  top: 0,
  left: 0
};
const defaultMargin = 0;


/**
 * @param { object } element Reference to parent div
 *
 * @param { array } [data = []] Array of data for the chart
 * @param { string } [data.label = index] Text displayed for bar label
 * @param { number } data.value Value of the bar
 * @param { string } [data.color] only used if color function is not provided
 *
 * @param { object } configuration The chart configuration
 * @param { number } configuration.width Total width of the parent div
 * @param { number } configuration.height Total height of the parent div
 * @param { object } [configuration.margin = defaultMargin] Margin around the chart
 * @param { number } [configuration.offsets.top]
 * @param { number } [configuration.offsets.bottom]
 * @param { function } [configuration.colorFunction] A function that will be called with datum and index and returns a color
 */
const render = (element, data = [], configuration = {}) => {
  const {
    width = element.getBoundingClientRect().width
  } = configuration;
  const {
    height = element.getBoundingClientRect().height
  } = configuration;
  const {
    margin = defaultMargin
  } = configuration;
  const {
    offset = defaultOffsets
  } = configuration;

  const config = {
    width,
    height,
    margin,
    offset,
  };

  const transform = () => {
    // Create the container.
    const xPos = width / 2 + offset.left;
    const yPos = height / 2 + offset.top;
    return `translate(${xPos}, ${yPos})`;
  }

  // force creation of the svg
  const root = d3.select(element);
  const s = root.selectAll('svg')
    .data([config]);

  const svg = s.enter()
    .append('svg')
    .merge(s)
    .attr('height', c => c.height)
    .attr('width', c => c.width);

  // determine the radius of the pie
  const radius = Math.min(
    width - 2 * margin,
  ...