// #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 }; }())