d3.js + immutable.js = ?

Chris Price / @100pxls

HIP
HOP
1 BILLION $

HIP

HIP
HOP

WHAT'S HIP IN JS?

REACT

VIRTUAL DOM

const root = () => 
             <ul className="my-list">
               <li>Text Content</li>
             </ul>;

ReactDOM.render(root, 
  document.getElementById('example'));

COMPONENT TREE OF PROPERTIES

class Avatar extends React.Component {
  render() {
    return (
      <div>
        <Pic username={this.props.user} />
        {this.props.user}
      </div>
    );
  }
}

ReactDOM.render(
  <Avatar user="pwh" />,
  document.getElementById('example')
);

FLUX

UNI-DIRECTIONAL DATA-FLOW

https://facebook.github.io/flux/docs/overview.html

REDUX

"MORE" 

dom = fn(model)
model = fn(model, action)

"reducer"

"pure"

HOP-PING BACK TO D3.JS

IDEMPOTENT DOM RENDERING

const root = function(container) {
  const ul = container.selectAll('ul')
    .data([null])
    .enter()
    .append('ul')
    .classed('my-list')
    .append('li')
    .text('Text Content');
};

d3.select('#element')
  .call(root);

COMPONENT TREES OF PROPERTIES

const avatar = function(selection) {
  const div = selection.selectAll('div')
    .data((data) => [data]);

  div.enter()
    .append('div');

  div.datum((d) => { user: d.user })
    .call(pic)
    .text((d) => d.user);
};

d3.select('#element')
  .datum({ user: 'pwh' })
  .call(avatar);

UNI-DIRECTIONAL DATA-FLOW

event/action

logic

rendered result

model

function componentFactory() {
  var event = d3.dispatch('customevent');

  function component(selection) {
    d3.select(this)
      .classed('active', function(d) {
        return d.toggle;
      })
      .on('click.component', function() {
          event.customevent.apply(
            this, arguments);
      });
  }
  d3.rebind(component, event, 'on');

  return component;
}
var model = {
  toggle: false
};

var rootComponent = componentFactory()
  .on('customevent', function() {
    model.toggle = !model.toggle;
    render();
  });

function render() {
  d3.select('#element')
    .datum(model)
    .call(rootComponent);
}

render();

IMMUTABLE.JS

var list = Immutable.List.of(1, 2, 3);

list.get(0);                // 1

list.set(0, 2); 
list.get(0);                // 1

var list2 = list.set(0, 2);
list === list2;             // false
list.get(0);                // 2

var list3 = list.set(0, 1);
list === list3;             // true
var map = Immutable.Map({ a: 1, b: 2 });

map.get('a');                // 1

map.set('a', 2);
map.get('a');                // 1

var map2 = map.set('a', 2);
map === map2;                // false
map.get('a');                // 2

var map3 = map.set('a', 1);
map === map3;                // true
var Record = Immutable.Record({ a: 1, b: 2 });

var record = Record();

record.get('a');              // 1
record.a;                     // 1

var record2 = record.set('a', 3);

// Can't do this
// record.a = '3';

PERFORMANCE SILVER-BULLET

dom = fn(model)

...this can't change

if these haven't changed...

dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)
dom = fn(model)

CONFESSION

d3.js + immutable.js = ?

CONCLUSIONS

 

 

 

 

 

 

 

 

 

 

 

 

IMMUTABLE.JS IS VIRAL!

 

D3.JS PERMITS IDEMPOTENT DOM RENDERING
(ALTHOUGH IT IS A VERBOSE SYNTAX)

D3.JS APPS CAN BE BUILT FROM A COMPONENT TREE

 

 

 

UNI-DIRECTIONAL DATA-FLOW POSSIBLE WITH DISCIPLINE AND EVENTS

 

 

IMMUTABLE.JS OFFERS A MECHANISM FOR MANAGING PERFORMANCE

(AS YOUR APP GROWS)

 

d3.js + immutable.js = T.D3FC.IO

Chris Price / @100pxls

d3.js + immutable.js = ?

By Chris Price

d3.js + immutable.js = ?

A talk given at d3.js London Meetup

  • 1,620