Skip to content

Instantly share code, notes, and snippets.

@eesur
Last active November 27, 2017 14:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eesur/872bf0ccbc4dee64b27925f82aea0a0c to your computer and use it in GitHub Desktop.
Save eesur/872bf0ccbc4dee64b27925f82aea0a0c to your computer and use it in GitHub Desktop.
d3 | Redux action
// #1a1a1a : #a634a0
(function () {
var d3 = window.d3
var Redux = window.Redux
// Create a Redux store holding the state of the app
// Its API is { subscribe, dispatch, getState }.
var store = Redux.createStore(active)
var initialstate = {
fill: '#1a1a1a',
ref: null
}
var xScale = d3.scaleLinear()
.domain([0, 10])
.range([40, 960])
var svg = d3.select('#vis')
svg.selectAll('circle')
.data(d3.range(10))
.enter().append('circle')
.attr('cx', function (d) { return xScale(d); })
.attr('cy', 100)
.attr('r', 30)
.attr('class', function (d) { return ("circle-" + d); })
.attr('fill', '#1a1a1a')
.on('click', function (d) { return store.dispatch({ type: 'SELECTED', ref: d }); })
d3.select('.btn-primary')
.on('click', function () { return store.dispatch({ type: 'RESET', ref: null }); })
function active (_state, action) {
if ( _state === void 0 ) _state = initialstate;
if ( action === void 0 ) action = null;
var state = snapshot(_state) // snapshot == clone
switch (action.type) {
case 'SELECTED':
console.log('action received for circle: ', action.ref)
state.fill = '#e5f015'
state.ref = action.ref
return state
case 'RESET':
return initialstate
default:
return _state
}
}
// 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(function () {
var state = store.getState()
svg.selectAll('circle')
.attr('fill', initialstate.fill)
.filter((".circle-" + (state.ref)))
.attr('fill', state.fill)
})
// 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
};
}())
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- http://www.basscss.com/ -->
<link href="https://unpkg.com/basscss@8.0.2/css/basscss.min.css" rel="stylesheet">
<style>
body {
background: #a634a0;
font-size: 16px;
font-family: -apple-system, BlinkMacSystemFont, Consolas, monaco, monospace;
}
button.btn {
font-family : inherit;
font-size: 16px;
letter-spacing: 2px;
font-weight: 700;
font-weight: 500;
cursor: pointer;
display: inline-block;
padding: .5rem 1rem;
height: auto;
border: 1px solid transparent;
vertical-align: middle;
-webkit-appearance: none;
color: inherit;
background-color: transparent;
text-decoration: none;
}
button.btn-primary {
color: #fff;
background-color: #6b2167;
border-radius: 3px;
}
button.btn-primary:hover {
box-shadow: inset 0 0 0 20rem #952e90;
}
</style>
</head>
<body>
<header class="pl2">
<p>Click on circle to set state via a Redux action</p>
</header>
<svg width="960" height="200">
<g id="vis" transform="translate(10, 10)"></g>
</svg>
<nav class="pl2">
<button class="btn btn-primary">RESET</button>
</nav>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.min.js"></script>
<!-- d3 code -->
<script src=".script-compiled.js" charset="utf-8"></script>
</body>
</html>
// #1a1a1a : #a634a0
(function () {
const d3 = window.d3
const Redux = window.Redux
// Create a Redux store holding the state of the app
// Its API is { subscribe, dispatch, getState }.
const store = Redux.createStore(active)
const initialstate = {
fill: '#1a1a1a',
ref: null
}
const xScale = d3.scaleLinear()
.domain([0, 10])
.range([40, 960])
const svg = d3.select('#vis')
svg.selectAll('circle')
.data(d3.range(10))
.enter().append('circle')
.attr('cx', d => xScale(d))
.attr('cy', 100)
.attr('r', 30)
.attr('class', d => `circle-${d}`)
.attr('fill', '#1a1a1a')
.on('click', (d) => store.dispatch({ type: 'SELECTED', ref: d }))
d3.select('.btn-primary')
.on('click', () => store.dispatch({ type: 'RESET', ref: null }))
function active (_state = initialstate, action = null) {
let state = snapshot(_state) // snapshot == clone
switch (action.type) {
case 'SELECTED':
console.log('action received for circle: ', action.ref)
state.fill = '#e5f015'
state.ref = action.ref
return state
case 'RESET':
return initialstate
default:
return _state
}
}
// 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(() => {
const state = store.getState()
svg.selectAll('circle')
.attr('fill', initialstate.fill)
.filter(`.circle-${state.ref}`)
.attr('fill', state.fill)
})
// deep cloning function excerpted from underscore.js
function snapshot (obj) {
if (obj == null || typeof (obj) !== 'object') {
return obj
}
const temp = new obj.constructor()
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
temp[key] = snapshot(obj[key])
}
}
return temp
};
}())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment