Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Creating D3 Components

Creating D3 Components

Who doesn’t love a good chart? When done correctly, charts can expose beauty in any form of data. Chris Price, creator of D3FC talks us through the logical leaps and the painful doubling-backs of building charts on D3. Working in financial services, it’s no surprise that charts form a part of the apps he creates. It’s a journey of pain, joy, frustration and enlightenment.

Frontend NE

July 07, 2016
Tweet

More Decks by Frontend NE

Other Decks in Programming

Transcript

  1. DOM abstraction manipulation selection.text('inner text') .attr('class', 'class-name') .style({ height: 'auto'

    }) .each(function(data) { var element = this; // ... }) .append('span');
  2. layout algorithms scales var scale = d3.scale.linear() .domain([-10, 10]) .range([0,

    500]); scale(-5); // 125 scale.invert(125); // -5 scale.ticks(3); // [-10, 0, 10]
  3. layout algorithms specialised layouts var layout = d3.layout.pie() .padAngle(Math.PI/10); layout([3,1,2]);

    // [ { // "data":3, // "value":3, // "padAngle":0.314..., // "startAngle":0, // "endAngle":2.984... // }, ... ]
  4. SVG helpers axis renderers var scale = d3.linear.scale() .domain([-10, 10])

    .range([0, 100]); var axis = d3.svg.axis() .scale(scale); d3.select('svg') .call(axis);
  5. SVG helpers path data generators var line = d3.svg.line(); line([[0,0],[50,50]]);

    // "M0,0L50,50" d3.select('svg') .append('path') .datum([[0,0],[50,50]]) .attr('d', line); // <path d="M0,0L50,50"></path>
  6. miscellaneous data/time formatting var format = d3.time.format("%a, %e %B %Y");

    format(new Date(2015, 4, 7)); // "Thu, 7 May 2015" var d = format.parse("Fri, 8 May 2015"); d.toString(); // "Fri May 08 2015 00:00:00 GMT+0000 (GMT)" d3.time.year.ceil(d, 1); // "Fri Jan 01 2016 00:00:00 GMT+0000 (GMT)"
  7. data join the data var data = [ { name:

    'Adams', rank: 'Captain' }, { name: 'Krill', rank: 'Commander' }, { name: 'Ryback', rank: 'Chief Petty Officer' } ];
  8. data join selection // ... function render() { var container

    = d3.select('ul'); container.selectAll('li'); requestAnimationFrame(render); } // ...
  9. data join the join // ... var container = d3.select('ul');

    container.selectAll('li') .data(data); requestAnimationFrame(render); // ...
  10. data join update selection // ... var updateSelection = container.selectAll('li')

    .data(data); updateSelection.text(function(d) { return d.name + ' (' + d.rank + ')'; }); // ...
  11. data join update selection <h1>USS Missouri Crew List</h1> <ul> <li>Adams

    (Captain)</li> <li>Krill (Commander)</li> <li>Ryback (Chief Petty Officer)</li> </ul>
  12. data join add an item to the data var data

    = [ { name: 'Adams', rank: 'Captain' }, { name: 'Krill', rank: 'Commander' }, { name: 'Ryback', rank: 'Chief Petty Officer' }, { name: 'Strannix', rank: 'Civilian' } ];
  13. data join ...no change <h1>USS Missouri Crew List</h1> <ul> <li>Adams

    (Captain)</li> <li>Krill (Commander)</li> <li>Ryback (Chief Petty Officer)</li> </ul>
  14. data join enter selection // ... var updateSelection = container.selectAll('li')

    .data(data); updateSelection.enter() .append('li'); updateSelection.text(function(d) { return d.name + ' (' + d.rank + ')'; }); // ...
  15. data join a change! <h1>USS Missouri Crew List</h1> <ul> <li>Adams

    (Captain)</li> <li>Krill (Commander)</li> <li>Ryback (Chief Petty Officer)</li> <li>Strannix (Civilian)</li> </ul>
  16. data join remove an item from the data var data

    = [ { name: 'Krill', rank: 'Commander' }, { name: 'Ryback', rank: 'Chief Petty Officer' }, { name: 'Strannix', rank: 'Civilian' } ];
  17. data join a change... <h1>USS Missouri Crew List</h1> <ul> <li>Krill

    (Commander)</li> <li>Ryback (Chief Petty Officer)</li> <li>Strannix (Civilian)</li> <li>Strannix (Civilian)</li> </ul>
  18. data join exit selection // ... updateSelection.enter() .append('li'); updateSelection.text(function(d) {

    return d.name + ' (' + d.rank + ')'; }); updateSelection.exit() .remove(); // ...
  19. data join a change! <h1>USS Missouri Crew List</h1> <ul> <li>Krill

    (Commander)</li> <li>Ryback (Chief Petty Officer)</li> <li>Strannix (Civilian)</li> </ul>
  20. data join spoilers <h1>USS Missouri Crew List</h1> <ul> <li>Ryback (Chief

    Petty Officer)</li> </ul> var data = [ { name: 'Ryback', rank: 'Chief Petty Officer' } ];
  21. components just functions function caseyRyback(selection) { selection.text('Another cold day in

    Hell.'); } function dramaticEffect(selection) { selection.style('fontWeight', 'bold'); } var selection = d3.select('span'); caseyRyback(selection); dramaticEffect(selection);
  22. components invoked with call function caseyRyback(selection) { selection.text('Another cold day

    in Hell.'); } function dramaticEffect(selection) { selection.style('fontWeight', 'bold'); } var selection = d3.select('span') .call(caseyRyback) .call(dramaticEffect);
  23. components factories function caseyRybackFactory() { function caseyRyback(selection) { selection.text('Another cold

    day in Hell.'); } return caseyRyback; } var component = caseyRybackFactory(); d3.select('span') .call(component);
  24. components configurable function caseyRybackFactory() { var quote = 'Another cold

    day in Hell.'; function caseyRyback(selection) { selection.text(quote); } caseyRyback.quote = function(value) { if (!arguments.length) { return quote; } quote = value; return caseyRyback; }; return caseyRyback; }
  25. d3fc a toolkit for rapidly developing bespoke charts embraces d3

    small and composable prioritises simplicity a curated and consistent set of examples