Skip to content

Instantly share code, notes, and snippets.

@Fil
Last active Jul 15, 2017
Embed
What would you like to do?
Redux + D3 in the browser
license: mit

State management with redux and d3, in the browser thanks to unpkg.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/redux@3.6.0/dist/redux.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
// Feel free to change or delete any of the code you see in this editor!
var svg = d3.select("body").append("svg")
.attr("width", 360)
.attr("height", 300)
svg.append("text")
.text("****")
.attr("y", 100)
.attr("x", 120)
.style("font-size", 36)
.style("font-family", "monospace")
d3.select("body").append("button")
.html('Reset')
.on('click', () => store.dispatch({ type: 'RESET' }));
d3.select("body").append("button")
.html('Zero')
.on('click', () => store.dispatch({ type: 'ZERO' }));
const initialstate = { iteration: 0, counter: 0 };
function counter(_state = initialstate, action = null) {
let state = snapshot(_state); // snapshot == clone
switch (action.type) {
case 'INCREMENT':
state.iteration ++;
state.counter ++;
return state;
case 'DECREMENT':
state.iteration ++;
state.counter --;
return state;
case 'ZERO':
state.iteration ++;
state.counter = 0;
return state;
case 'RESET':
return initialstate;
default:
return _state;
}
}
// Create a Redux store holding the state of your app.
// Its API is { subscribe, dispatch, getState }.
let store = Redux.createStore(counter);
// You can use subscribe() to update the UI in response to state changes.
// Normally you'd use a view binding library (e.g. React Redux) rather than subscribe() directly.
// However it can also be handy to persist the current state in the localStorage.
store.subscribe(() => {
var state = store.getState();
svg.select("text")
.text(`${state.iteration}: ${state.counter}`)
}
);
// The only way to mutate the internal state is to dispatch an action.
// The actions can be serialized, logged or stored and later replayed.
d3.interval(() => {
store.dispatch({ type: Math.random()>0.5 ?'INCREMENT' : 'DECREMENT' });
}, 100);
// deep cloning function excerpted from underscore.js
function snapshot (obj) {
if(obj == null || typeof(obj) != 'object') {
return obj;
}
var temp = new obj.constructor();
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
temp[key] = snapshot(obj[key]);
}
}
return temp;
};
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment