State management with redux and d3, in the browser thanks to unpkg.
Last active
July 15, 2017 15:47
-
-
Save Fil/47678a37cc46fee9b3ed4769c31914e7 to your computer and use it in GitHub Desktop.
Redux + D3 in the browser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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