
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