Skip to content

Instantly share code, notes, and snippets.

Created July 6, 2016 16:53
Show Gist options
  • Save anonymous/5cd6e118186d5e429d6a1fa9da03668c to your computer and use it in GitHub Desktop.
Save anonymous/5cd6e118186d5e429d6a1fa9da03668c to your computer and use it in GitHub Desktop.
JS Bin // source http://jsbin.com/jozihiluki
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.min.js"></script>
<script src="https://wzrd.in/standalone/deep-freeze"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<style>
#tabs span {
border: 1px solid black;
border-radius: 7px 7px 0 0;
padding: 3px;
cursor: pointer;
}
#tabs span.active {
background-color: lightgray;
}
</style>
</head>
<body>
<div id="tabs">
<span id="model0" class="active">base</span>
<!--<span id="model1" class="active">derived1</span>-->
</div>
<br/>
<p id="year">
Year:
<span>2014</span>
<button>Set</button>
</p>
<p>
<span>foo:</span>
<input id="sankey-chart" type="range" min="-50" max="150" value="25"/>
<span id="sankey-value"></span>
</p>
<p>
<span>total:</span>
<span id="total-value"></span>
</p>
<script id="jsbin-javascript">
/* jshint esnext: true */
/* jshint asi: true */
/* jshint laxcomma: true */
/*
ES6: (state = [], action) => { ... }
ES5: function(state, action) { if (!state) state = []; ... }
Functions with a single expression using ES6 arrow functions don't need {}:
[1,2,3].map(elem => elem * 2) // returns [2,4,6]
The const keyword declares a constant. Reusing the same name will throw an error:
const foo = 'bar'
const foo = 'baz' // throws "SyntaxError: Identifier 'foo' has already been declared"
*/
const { createStore, combineReducers } = Redux;
const extractId = (id) => parseInt(id.match(/\d+/g)[0])
const sankeyChart = document.getElementById('sankey-chart')
, sankeyValue = document.getElementById('sankey-value')
, totalValue = document.getElementById('total-value')
const defaultYear = document.querySelector('#year span')
, setYear = document.querySelector('#year button')
//------------------------------------------------------------------------------
var forecastId = 0;
const forecastModel = (state = [], action) => {
switch (action.type) {
case 'ADD_MODEL':
return state.map(e => { e.active = false; return e }).concat({
id: forecastId++,
active: true,
defaultYear: action.defaultYear || state[0].defaultYear,
drivers: !state[0] ? action.drivers :
Object.assign({}, state[0].drivers, action.drivers || {})
})
case 'SELECT_MODEL':
return state.map(e => {
e.active = e.id === action.id ? true : false
return e
})
case 'UPDATE_MODEL':
const modelIndex = state.findIndex(e => e.active)
return state.slice(0, modelIndex)
.concat([{
id: state[modelIndex].id,
active: true,
defaultYear: action.defaultYear ||
state[modelIndex].defaultYear,
drivers: Object.assign({}, state[0].drivers, action.drivers || {})
}])
.concat(state.slice(modelIndex + 1))
case 'DELETE_MODEL':
return modelIndex === 0 ? state
: state.slice(0, modelIndex)
.concat(state.slice(modelIndex + 1))
default:
return state
}
}
forecastStore = createStore(forecastModel)
// render the view
forecastStore.subscribe(() => {
const tabs = forecastStore.getState().map(e => {
return `<span id="model${e.id}" class="${e.active ? 'active' : ''}" onClick="selectModel(event)">` +
`model${e.id}` +
`</span>`
}).join()
document.getElementById('tabs').innerHTML = tabs
const activeModel = forecastStore.getState().find(e => e.active)
sankeyChart.value = activeModel.drivers.foo
defaultYear.innerHTML = activeModel.defaultYear
totalValue.innerHTML = activeModel.drivers.total()
if (activeModel.id === 0)
setYear.setAttribute('disabled', 'disabled')
else
setYear.removeAttribute('disabled')
//console.log(forecastStore.getState(), activeModel)
})
// dispatch base model
forecastStore.dispatch({
type: 'ADD_MODEL',
active: true,
defaultYear: 2016,
drivers: {
foo: 22,
total: function() { return this.foo * 3 }
}
})
function selectModel(event) {
const modelId = extractId(event.target.id)
forecastStore.dispatch({
type: 'SELECT_MODEL',
id: modelId
})
console.log('foo' )
}
const sankey = (state = sankeyChart.value, action) => {
switch (action.type) {
case 'SANKEY_DRAG':
return action.sankeyValue
default:
return state
}
}
const sankeyStore = createStore(sankey)
sankeyStore.subscribe(() => {
sankeyValue.innerHTML = sankeyStore.getState()
})
sankeyStore.dispatch({
type: 'SANKEY_DRAG',
sankeyValue: sankeyChart.value
})
// sankey chart arm dragging
sankeyChart.addEventListener('input', (event) => {
sankeyStore.dispatch({
type: 'SANKEY_DRAG',
sankeyValue: event.target.value
})
})
// sankey chart arm let go
sankeyChart.addEventListener('mouseup', (event) => {
if (forecastStore.getState().find(e => e.active).id === 0) {
forecastStore.dispatch({
type: 'ADD_MODEL',
drivers: {
foo: parseInt(sankeyChart.value)
}
})
}
else {
forecastStore.dispatch({
type: 'UPDATE_MODEL',
drivers: {
foo: parseInt(sankeyChart.value)
}
})
}
console.log('blur')
})
/*
const todo = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
id: action.id,
text: action.text,
completed: false
};
case 'TOGGLE_TODO':
return state.id !== action.id ? state : {
...state,
completed: !state.completed
};
default:
return state;
}
};
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
];
case 'TOGGLE_TODO':
return state.map(t => todo(t, action));
default:
return state;
}
}
const visibilityFilter = (state = 'SHOW_ALL', action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter;
default:
return state;
}
}
const todoApp = combineReducers({
todos,
visibilityFilter
});
const store = createStore(todos);
store.dispatch({
type: 'ADD_TODO',
id:0,
text: 'Learn Redux'
});
*/
</script>
<script id="jsbin-source-javascript" type="text/javascript">/* jshint esnext: true */
/* jshint asi: true */
/* jshint laxcomma: true */
/*
ES6: (state = [], action) => { ... }
ES5: function(state, action) { if (!state) state = []; ... }
Functions with a single expression using ES6 arrow functions don't need {}:
[1,2,3].map(elem => elem * 2) // returns [2,4,6]
The const keyword declares a constant. Reusing the same name will throw an error:
const foo = 'bar'
const foo = 'baz' // throws "SyntaxError: Identifier 'foo' has already been declared"
*/
const { createStore, combineReducers } = Redux;
const extractId = (id) => parseInt(id.match(/\d+/g)[0])
const sankeyChart = document.getElementById('sankey-chart')
, sankeyValue = document.getElementById('sankey-value')
, totalValue = document.getElementById('total-value')
const defaultYear = document.querySelector('#year span')
, setYear = document.querySelector('#year button')
//------------------------------------------------------------------------------
var forecastId = 0;
const forecastModel = (state = [], action) => {
switch (action.type) {
case 'ADD_MODEL':
return state.map(e => { e.active = false; return e }).concat({
id: forecastId++,
active: true,
defaultYear: action.defaultYear || state[0].defaultYear,
drivers: !state[0] ? action.drivers :
Object.assign({}, state[0].drivers, action.drivers || {})
})
case 'SELECT_MODEL':
return state.map(e => {
e.active = e.id === action.id ? true : false
return e
})
case 'UPDATE_MODEL':
const modelIndex = state.findIndex(e => e.active)
return state.slice(0, modelIndex)
.concat([{
id: state[modelIndex].id,
active: true,
defaultYear: action.defaultYear ||
state[modelIndex].defaultYear,
drivers: Object.assign({}, state[0].drivers, action.drivers || {})
}])
.concat(state.slice(modelIndex + 1))
case 'DELETE_MODEL':
return modelIndex === 0 ? state
: state.slice(0, modelIndex)
.concat(state.slice(modelIndex + 1))
default:
return state
}
}
forecastStore = createStore(forecastModel)
// render the view
forecastStore.subscribe(() => {
const tabs = forecastStore.getState().map(e => {
return `<span id="model${e.id}" class="${e.active ? 'active' : ''}" onClick="selectModel(event)">` +
`model${e.id}` +
`</span>`
}).join()
document.getElementById('tabs').innerHTML = tabs
const activeModel = forecastStore.getState().find(e => e.active)
sankeyChart.value = activeModel.drivers.foo
defaultYear.innerHTML = activeModel.defaultYear
totalValue.innerHTML = activeModel.drivers.total()
if (activeModel.id === 0)
setYear.setAttribute('disabled', 'disabled')
else
setYear.removeAttribute('disabled')
//console.log(forecastStore.getState(), activeModel)
})
// dispatch base model
forecastStore.dispatch({
type: 'ADD_MODEL',
active: true,
defaultYear: 2016,
drivers: {
foo: 22,
total: function() { return this.foo * 3 }
}
})
function selectModel(event) {
const modelId = extractId(event.target.id)
forecastStore.dispatch({
type: 'SELECT_MODEL',
id: modelId
})
console.log('foo' )
}
const sankey = (state = sankeyChart.value, action) => {
switch (action.type) {
case 'SANKEY_DRAG':
return action.sankeyValue
default:
return state
}
}
const sankeyStore = createStore(sankey)
sankeyStore.subscribe(() => {
sankeyValue.innerHTML = sankeyStore.getState()
})
sankeyStore.dispatch({
type: 'SANKEY_DRAG',
sankeyValue: sankeyChart.value
})
// sankey chart arm dragging
sankeyChart.addEventListener('input', (event) => {
sankeyStore.dispatch({
type: 'SANKEY_DRAG',
sankeyValue: event.target.value
})
})
// sankey chart arm let go
sankeyChart.addEventListener('mouseup', (event) => {
if (forecastStore.getState().find(e => e.active).id === 0) {
forecastStore.dispatch({
type: 'ADD_MODEL',
drivers: {
foo: parseInt(sankeyChart.value)
}
})
}
else {
forecastStore.dispatch({
type: 'UPDATE_MODEL',
drivers: {
foo: parseInt(sankeyChart.value)
}
})
}
console.log('blur')
})
/*
const todo = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
id: action.id,
text: action.text,
completed: false
};
case 'TOGGLE_TODO':
return state.id !== action.id ? state : {
...state,
completed: !state.completed
};
default:
return state;
}
};
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
];
case 'TOGGLE_TODO':
return state.map(t => todo(t, action));
default:
return state;
}
}
const visibilityFilter = (state = 'SHOW_ALL', action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter;
default:
return state;
}
}
const todoApp = combineReducers({
todos,
visibilityFilter
});
const store = createStore(todos);
store.dispatch({
type: 'ADD_TODO',
id:0,
text: 'Learn Redux'
});
*/</script></body>
</html>
/* jshint esnext: true */
/* jshint asi: true */
/* jshint laxcomma: true */
/*
ES6: (state = [], action) => { ... }
ES5: function(state, action) { if (!state) state = []; ... }
Functions with a single expression using ES6 arrow functions don't need {}:
[1,2,3].map(elem => elem * 2) // returns [2,4,6]
The const keyword declares a constant. Reusing the same name will throw an error:
const foo = 'bar'
const foo = 'baz' // throws "SyntaxError: Identifier 'foo' has already been declared"
*/
const { createStore, combineReducers } = Redux;
const extractId = (id) => parseInt(id.match(/\d+/g)[0])
const sankeyChart = document.getElementById('sankey-chart')
, sankeyValue = document.getElementById('sankey-value')
, totalValue = document.getElementById('total-value')
const defaultYear = document.querySelector('#year span')
, setYear = document.querySelector('#year button')
//------------------------------------------------------------------------------
var forecastId = 0;
const forecastModel = (state = [], action) => {
switch (action.type) {
case 'ADD_MODEL':
return state.map(e => { e.active = false; return e }).concat({
id: forecastId++,
active: true,
defaultYear: action.defaultYear || state[0].defaultYear,
drivers: !state[0] ? action.drivers :
Object.assign({}, state[0].drivers, action.drivers || {})
})
case 'SELECT_MODEL':
return state.map(e => {
e.active = e.id === action.id ? true : false
return e
})
case 'UPDATE_MODEL':
const modelIndex = state.findIndex(e => e.active)
return state.slice(0, modelIndex)
.concat([{
id: state[modelIndex].id,
active: true,
defaultYear: action.defaultYear ||
state[modelIndex].defaultYear,
drivers: Object.assign({}, state[0].drivers, action.drivers || {})
}])
.concat(state.slice(modelIndex + 1))
case 'DELETE_MODEL':
return modelIndex === 0 ? state
: state.slice(0, modelIndex)
.concat(state.slice(modelIndex + 1))
default:
return state
}
}
forecastStore = createStore(forecastModel)
// render the view
forecastStore.subscribe(() => {
const tabs = forecastStore.getState().map(e => {
return `<span id="model${e.id}" class="${e.active ? 'active' : ''}" onClick="selectModel(event)">` +
`model${e.id}` +
`</span>`
}).join()
document.getElementById('tabs').innerHTML = tabs
const activeModel = forecastStore.getState().find(e => e.active)
sankeyChart.value = activeModel.drivers.foo
defaultYear.innerHTML = activeModel.defaultYear
totalValue.innerHTML = activeModel.drivers.total()
if (activeModel.id === 0)
setYear.setAttribute('disabled', 'disabled')
else
setYear.removeAttribute('disabled')
//console.log(forecastStore.getState(), activeModel)
})
// dispatch base model
forecastStore.dispatch({
type: 'ADD_MODEL',
active: true,
defaultYear: 2016,
drivers: {
foo: 22,
total: function() { return this.foo * 3 }
}
})
function selectModel(event) {
const modelId = extractId(event.target.id)
forecastStore.dispatch({
type: 'SELECT_MODEL',
id: modelId
})
console.log('foo' )
}
const sankey = (state = sankeyChart.value, action) => {
switch (action.type) {
case 'SANKEY_DRAG':
return action.sankeyValue
default:
return state
}
}
const sankeyStore = createStore(sankey)
sankeyStore.subscribe(() => {
sankeyValue.innerHTML = sankeyStore.getState()
})
sankeyStore.dispatch({
type: 'SANKEY_DRAG',
sankeyValue: sankeyChart.value
})
// sankey chart arm dragging
sankeyChart.addEventListener('input', (event) => {
sankeyStore.dispatch({
type: 'SANKEY_DRAG',
sankeyValue: event.target.value
})
})
// sankey chart arm let go
sankeyChart.addEventListener('mouseup', (event) => {
if (forecastStore.getState().find(e => e.active).id === 0) {
forecastStore.dispatch({
type: 'ADD_MODEL',
drivers: {
foo: parseInt(sankeyChart.value)
}
})
}
else {
forecastStore.dispatch({
type: 'UPDATE_MODEL',
drivers: {
foo: parseInt(sankeyChart.value)
}
})
}
console.log('blur')
})
/*
const todo = (state, action) => {
switch (action.type) {
case 'ADD_TODO':
return {
id: action.id,
text: action.text,
completed: false
};
case 'TOGGLE_TODO':
return state.id !== action.id ? state : {
...state,
completed: !state.completed
};
default:
return state;
}
};
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
];
case 'TOGGLE_TODO':
return state.map(t => todo(t, action));
default:
return state;
}
}
const visibilityFilter = (state = 'SHOW_ALL', action) => {
switch (action.type) {
case 'SET_VISIBILITY_FILTER':
return action.filter;
default:
return state;
}
}
const todoApp = combineReducers({
todos,
visibilityFilter
});
const store = createStore(todos);
store.dispatch({
type: 'ADD_TODO',
id:0,
text: 'Learn Redux'
});
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment