Last active
June 15, 2016 03:19
-
-
Save sifbuilder/b53925d96274bedf022c6e7633e3fe1c to your computer and use it in GitHub Desktop.
the big listener, irritating game but needed template to probe #d3js transitions coordinating through unwired #redux store
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
the big listener, irritating game but needed template to probe #d3js transitions coordinating through unwired #redux store |
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
<html> | |
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> | |
<head></head> | |
<body> | |
<div id="container"></div> | |
<script src="https://d3js.org/d3.v4.0.0-alpha.44.min.js"></script> | |
<script> | |
/* */ | |
/* d3rings-actions-court.js */ | |
/* */ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsActionsCourt = global.d3ringsActionsCourt || {}))); | |
}(this, function (exports) { 'use strict'; | |
// ____________________ keyMirror | |
// https://github.com/STRML/keyMirror | |
var keyMirror = function(obj, prefix) { | |
var ret = {}; | |
var key; | |
if (!(obj instanceof Object && !Array.isArray(obj))) { | |
throw new Error('keyMirror(...): Argument must be an object.'); | |
} | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
ret[key] = prefix + key; | |
} | |
} | |
return ret; | |
}; | |
// ____________________ action TYPES | |
var cttsCourt = { | |
FETCH_RECORDS: '', | |
KEYB_DISPATCH: '', | |
PROCESS_KEYB_KEYS: '', | |
RELEASE_KEYBKEY: '', | |
RESET_KEYS_EVENTS: '', | |
RESIZE_HEIGHT: '', | |
RESIZE_WIDTH: '', | |
SET_KEYBKEY: '', | |
SET_MODE: '', | |
SET_NOTICE: '', | |
SET_VIEW: '', | |
START_KEYS_EVENTS: '', | |
START_KEYBKEY_EVENTS: '', | |
UPDATE_MOUSE_POS: '', | |
} | |
var ActionTypes = keyMirror(cttsCourt, '') | |
// ____________________ actions COURT | |
var ActionCreators = { | |
resizeHeight(payload) { | |
return { | |
type: ActionTypes.RESIZE_HEIGHT, | |
payload: payload | |
} | |
}, | |
resizeWidth(payload) { | |
return { | |
type: ActionTypes.RESIZE_WIDTH, | |
payload: payload | |
} | |
}, | |
releaseKeybKey(e) { | |
return { | |
type: ActionTypes.RELEASE_KEYBKEY, | |
keyCode: e.keyCode, | |
} | |
}, | |
setKeybKey(e) { | |
return { | |
type: ActionTypes.SET_KEYBKEY, | |
keyCode: e.keyCode, | |
} | |
}, | |
processKeybKeys(payload) { | |
return { | |
type: ActionTypes.PROCESS_KEYB_KEYS, // processKeybKeys | |
payload: payload, | |
} | |
}, | |
setMode(payload) { | |
return { | |
type: ActionTypes.SET_MODE, // setMode | |
payload: payload, | |
} | |
}, | |
setNotice(notice) { | |
return { | |
type: ActionTypes.SET_NOTICE, | |
notice: notice, | |
} | |
}, | |
setView(payload) { | |
return { | |
type: ActionTypes.SET_VIEW, | |
payload: payload, | |
} | |
}, | |
startKeybKeyEvents() { | |
return { | |
type: ActionTypes.START_KEYBKEY_EVENTS // startKeybKeyEvents | |
} | |
}, | |
updateMousePos(svg) { | |
return { | |
type: ActionTypes.UPDATE_MOUSE_POS, | |
svg: svg, | |
} | |
}, | |
} | |
exports.ActionTypes = ActionTypes; | |
exports.ActionCreators = ActionCreators; | |
})); | |
/* */ | |
/* d3rings-actions-debug.js */ | |
/* */ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsActionsDebug = global.d3ringsActionsDebug || {}))); | |
}(this, function (exports) { 'use strict'; | |
// ____________________ keyMirror | |
// https://github.com/STRML/keyMirror | |
var keyMirror = function(obj, prefix) { | |
var ret = {}; | |
var key; | |
if (!(obj instanceof Object && !Array.isArray(obj))) { | |
throw new Error('keyMirror(...): Argument must be an object.'); | |
} | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
ret[key] = prefix + key; | |
} | |
} | |
return ret; | |
} | |
// ____________________ action TYPES | |
var cttsDebug = { | |
SET_DEBUGMODE: '', | |
SET_FPS: '', | |
SWITCH_DEBUGMODE: '', | |
} | |
var ActionTypes = keyMirror(cttsDebug, '') | |
// ____________________ actions DEBUG | |
var ActionCreators = { | |
setDebugMode(debugMode) { | |
return { | |
type: ActionTypes.SET_DEBUG_MODE, | |
debugMode: debugMode, | |
} | |
}, | |
setFps(fps) { | |
return { | |
type: ActionTypes.SET_FPS, | |
fps: fps, | |
} | |
}, | |
switchDebugMode(payload) { | |
return { | |
type: ActionTypes.SWITCH_DEBUGMODE, | |
payload: payload, | |
}; | |
}, | |
} | |
exports.ActionTypes = ActionTypes | |
exports.ActionCreators = ActionCreators | |
})); | |
/* */ | |
/* d3rings-actions.js */ | |
/* */ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsActionsLanes = global.d3ringsActionsLanes || {}))); | |
}(this, function (exports) { 'use strict'; | |
// ____________________ keyMirror | |
// https://github.com/STRML/keyMirror | |
var keyMirror = function(obj, prefix) { | |
var ret = {}; | |
var key; | |
if (!(obj instanceof Object && !Array.isArray(obj))) { | |
throw new Error('keyMirror(...): Argument must be an object.'); | |
} | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
ret[key] = prefix + key; | |
} | |
} | |
return ret; | |
} | |
var cttsLanes = { | |
DELETE_LANE: '', | |
SET_LANE: '', | |
SET_LANES: '', | |
SET_MESSAGES: '', | |
SET_RECORDS: '', | |
SET_RECORDS_COLLECTION: '', | |
SET_RECORDS_FETCHED: '', | |
UPDATE_MESSAGES: '', | |
WALK_DOWN_RECORDS: '', | |
WALK_UP_RECORDS: '', | |
} | |
var ActionTypes = keyMirror(cttsLanes, '') | |
// ____________________ actions LANES | |
var ActionCreators = { | |
decreaseCursorLow() { | |
return { | |
type: ActionTypes.DECREASE_CURSOR_LOW, | |
} | |
}, | |
decreaseCursorHigh() { | |
return { | |
type: ActionTypes.DECREASE_CURSOR_HIGH, | |
} | |
}, | |
deleteLane(lane) { | |
return { | |
type: ActionTypes.DELETE_LANE, | |
lane: lane, | |
} | |
}, | |
setRecordsFetched(areRecordsFetched) { | |
return { | |
type: ActionTypes.SET_RECORDS_FETCHED, | |
areRecordsFetched: areRecordsFetched, | |
} | |
}, | |
setRecords(argObj) { // SET_RECORDS | |
return { | |
type: ActionTypes.SET_RECORDS, | |
itemSpan: argObj.itemSpan, | |
mode: argObj.currentMode, | |
} | |
}, | |
setRecordsCollection(obj) { // SET_RECORDS_COLLECTION | |
return { | |
type: ActionTypes.SET_RECORDS_COLLECTION, | |
recordsCollection: obj.recordsCollection | |
} | |
}, | |
setLane(lane) { | |
return { | |
type: ActionTypes.SET_LANE, | |
lane: lane, | |
} | |
}, | |
setLanes(lanes) { | |
return { | |
type: ActionTypes.SET_LANES, | |
lanes: lanes, | |
} | |
}, | |
setMessages(messages) { | |
return { | |
type: ActionTypes.SET_MESSAGES, | |
messages: messages, | |
} | |
}, | |
updateMessages(messages) { | |
return { | |
type: ActionTypes.UPDATE_MESSAGES, | |
cursorLow: cursorLow, | |
cursorHigh: cursorHigh, | |
} | |
}, | |
walkDownRecords(payload) { // WALK_DOWN_RECORDS | |
return { | |
type: ActionTypes.WALK_DOWN_RECORDS, | |
payload: payload, | |
} | |
}, | |
walkUpRecords(payload) { // WALK_UP_RECORDS | |
return { | |
type: ActionTypes.WALK_UP_RECORDS, | |
payload: payload, | |
} | |
}, | |
} | |
exports.ActionTypes = ActionTypes | |
exports.ActionCreators = ActionCreators | |
})); | |
/* */ | |
/* d3rings-actions-particles.js */ | |
/* */ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsActionsParticles = global.d3ringsActionsParticles || {}))); | |
}(this, function (exports) { 'use strict'; | |
// ____________________ keyMirror | |
// https://github.com/STRML/keyMirror | |
var keyMirror = function(obj, prefix) { | |
var ret = {}; | |
var key; | |
if (!(obj instanceof Object && !Array.isArray(obj))) { | |
throw new Error('keyMirror(...): Argument must be an object.'); | |
} | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
ret[key] = prefix + key; | |
} | |
} | |
return ret; | |
} | |
var cttsParticles = { | |
CREATE_PARTICLES: '', | |
INTRODUCE_PARTICLES: '', | |
START_PARTICLES: '', | |
START_TICKER: '', | |
STOP_PARTICLES: '', | |
STOP_TICKER: '', | |
TICK_PARTICLES: '', | |
} | |
var ActionTypes = keyMirror(cttsParticles, '') | |
// ____________________ actions PARTICLES | |
var ActionCreators = { | |
createParticles(obj) { | |
var action = { | |
type: ActionTypes.CREATE_PARTICLES, // createParticles | |
particlesPerTick: obj.particlesPerTick, | |
x: obj.x, | |
y: obj.y, | |
randNormal: obj.randNormal, | |
randNormal2: obj.randNormal2, | |
xInit: obj.xInit, | |
xEnd: obj.xEnd, | |
lanes: obj.lanes, | |
particlesGenerating: obj.particlesGenerating, | |
currentView: obj.currentView, | |
} | |
return action | |
}, | |
introduceParticles(obj) { | |
return { | |
type: ActionTypes.INTRODUCE_PARTICLES, // introduceParticles | |
particlesPerTick: obj.particlesPerTick, | |
x: obj.x, | |
y: obj.y, | |
randNormal: obj.randNormal, | |
randNormal2: obj.randNormal2, | |
xInit: obj.xInit, | |
xEnd: obj.xEnd, | |
lanes: obj.lanes, | |
particlesGenerating: obj.particlesGenerating, | |
currentView: obj.currentView, | |
} | |
}, | |
startParticles() { | |
return { | |
type: ActionTypes.START_PARTICLES | |
} | |
}, | |
startTicker() { | |
return { | |
type: ActionTypes.START_TICKER | |
}; | |
}, | |
stopTicker() { | |
return { | |
type: ActionTypes.STOP_TICKER | |
}; | |
}, | |
stopParticles() { | |
return { | |
type: ActionTypes.STOP_PARTICLES | |
} | |
}, | |
tickParticles(arg) { | |
return { | |
type: ActionTypes.TICK_PARTICLES, // tickParticles | |
width: arg.width, | |
height: arg.height, | |
gravity: arg.gravity, | |
lanes: arg.lanes, | |
} | |
}, | |
} | |
exports.ActionTypes = ActionTypes | |
exports.ActionCreators = ActionCreators | |
})); | |
/* */ | |
/* d3rings-actions-whirls.js */ | |
/* */ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsActionsWhirls = global.d3ringsActionsWhirls || {}))); | |
}(this, function (exports) { 'use strict'; | |
// ____________________ keyMirror | |
// https://github.com/STRML/keyMirror | |
var keyMirror = function(obj, prefix) { | |
var ret = {}; | |
var key; | |
if (!(obj instanceof Object && !Array.isArray(obj))) { | |
throw new Error('keyMirror(...): Argument must be an object.'); | |
} | |
for (key in obj) { | |
if (obj.hasOwnProperty(key)) { | |
ret[key] = prefix + key; | |
} | |
} | |
return ret; | |
} | |
var consts = { | |
DELETE_RANG: '', | |
INIT_RANGS: '', | |
SET_DURATION: '', | |
SET_RANG: '', | |
SET_RANGS: '', | |
STOP_RANGS: '', | |
UPDATE_RANGS_DURATION: '', | |
UPDATE_RANGS_NUMBER: '', | |
INTRODUCE_RINGS: '', | |
CREATE_RINGS: '', | |
DELETE_RING: '', | |
START_RINGS: '', | |
START_RINGS_TICKER: '', | |
STOP_RINGS: '', | |
STOP_TICKER: '', | |
TICK_RING: '', | |
TICK_RINGS: '', | |
} | |
var ActionTypes = keyMirror(consts, '') | |
// ____________________ actions RANGS | |
var ActionCreators = { | |
deleteRang(rang) { | |
return { | |
type: ActionTypes.DELETE_RANG, | |
rang: rang, | |
} | |
}, | |
startRangs() { | |
return { | |
type: ActionTypes.INIT_RANGS, | |
startRangs: true, | |
} | |
}, | |
setDuration(duration) { | |
return { | |
type: ActionTypes.SET_DURATION, | |
duration: duration, | |
} | |
}, | |
stopRangs() { | |
return { | |
type: ActionTypes.STOP_RANGS | |
} | |
}, | |
setRang(rang) { | |
return { | |
type: ActionTypes.SET_RANG, | |
rang: rang, | |
} | |
}, | |
setRangs(rangs) { | |
return { | |
type: ActionTypes.SET_RANGS, | |
rangs: rangs, | |
} | |
}, | |
updateRangsDuration(obj) { | |
return { | |
type: ActionTypes.UPDATE_RANGS_DURATION, | |
rangsAlways: obj.rangsAlways, | |
rangsHitsIndex: obj.rangsHitsIndex, | |
} | |
}, | |
updateRangsNumber(obj) { | |
return { | |
type: ActionTypes.UPDATE_RANGS_NUMBER, | |
rangsAlways: obj.rangsAlways, | |
rangsHitsIndex: obj.rangsHitsIndex, | |
} | |
}, | |
introduceRings(obj) { | |
return { | |
type: ActionTypes.INTRODUCE_RINGS, // introduceRings | |
ringsPerTick: obj.ringsPerTick, | |
x: obj.x, | |
y: obj.y, | |
randNormal: obj.randNormal, | |
randNormal2: obj.randNormal2, | |
xInit: obj.xInit, | |
xEnd: obj.xEnd, | |
rangs: obj.rangs, | |
ringsGenerating: obj.ringsGenerating, | |
} | |
}, | |
createRings(obj) { | |
return { | |
type: ActionTypes.CREATE_RINGS, // createRings | |
ringsPerTick: obj.ringsPerTick, | |
x: obj.x, | |
y: obj.y, | |
r: obj.r, | |
randNormal: obj.randNormal, | |
randNormal2: obj.randNormal2, | |
rangs: obj.rangs, | |
ringsGenerating: obj.ringsGenerating, | |
} | |
}, | |
deleteRing(ring) { | |
return { | |
type: ActionTypes.DELETE_RING, | |
ring: ring, | |
} | |
}, | |
startRings() { | |
return { | |
type: ActionTypes.START_RINGS | |
} | |
}, | |
startRingsTicker() { | |
return { | |
type: ActionTypes.START_RINGS_TICKER | |
}; | |
}, | |
stopRingsTicker() { | |
return { | |
type: ActionTypes.STOP_RINGS_TICKER | |
}; | |
}, | |
tickRing(arg) { | |
return { | |
type: ActionTypes.TICK_RING, // tickRing | |
ring: { | |
id: arg.id, | |
rid: arg.rid, | |
cx: arg.cx, | |
cy: arg.cy, | |
r0: arg.r0, | |
r: arg.r, | |
vector: arg.vector, | |
t: arg.t, | |
tn: arg.tn, | |
rang: arg.rang, | |
} | |
} | |
}, | |
stopRings() { | |
return { | |
type: ActionTypes.STOP_RINGS | |
} | |
}, | |
} | |
exports.ActionTypes = ActionTypes | |
exports.ActionCreators = ActionCreators | |
})); | |
/* */ | |
/* d3rings-actions.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3ringsActionsCourt = require('./d3rings-actions-court.js') | |
var d3ringsActionsDebug = require('./d3rings-actions-debug.js') | |
var d3ringsActionsLanes = require('./d3rings-actions-lanes.js') | |
var d3ringsActionsParticles = require('./d3rings-actions-particles.js') | |
var d3ringsActionsWhirls = require('./d3rings-actions-whirls.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsActions = global.d3ringsActions || {}))); | |
}(this, function (exports) { 'use strict'; | |
// ____________________ merge_objects | |
function merge_objects(ctt1,ctt2){ | |
var i, obj = {} | |
for (i = 0; i < arguments.length; i++) { | |
Object.assign(obj, arguments[i]) | |
} | |
return obj; | |
} | |
var ActionTypes = merge_objects( | |
d3ringsActionsCourt.ActionTypes, | |
d3ringsActionsDebug.ActionTypes, | |
d3ringsActionsLanes.ActionTypes, | |
d3ringsActionsParticles.ActionTypes, | |
d3ringsActionsWhirls.ActionTypes | |
) | |
var ActionCreators = merge_objects( | |
d3ringsActionsCourt.ActionCreators, | |
d3ringsActionsDebug.ActionCreators, | |
d3ringsActionsLanes.ActionCreators, | |
d3ringsActionsParticles.ActionCreators, | |
d3ringsActionsWhirls.ActionCreators | |
) | |
exports.ActionTypes = ActionTypes; | |
exports.ActionCreators = ActionCreators; | |
})); | |
/* */ | |
/* d3rings-controls.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsControls = global.d3ringsControls || {}))); | |
}(this, function (exports) { 'use strict'; | |
/* ------------- */ | |
/* timeControls */ | |
/* ------------- */ | |
function timeControls(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
// ____________________ timer | |
function timer() {} | |
// ____________________ start | |
timer.start = function start() { | |
var started = false | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
// listeners[i]() | |
} | |
return timer | |
} | |
// ____________________ subscribe | |
timer.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
d3.timer(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return timer | |
} | |
/* ------------- */ | |
/* stepControls */ | |
/* ------------- */ | |
function stepControls(payload) { | |
var store = payload.store | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
// ____________________ stepper | |
function stepper() {} | |
// ____________________ start | |
stepper.start = function start() { | |
var periodFactor = store.getState().reducerConfig.periodFactor | |
var beatTime = store.getState().reducerConfig.beatTime | |
var periodTime = periodFactor * beatTime // items added | |
var itemSpan = store.getState().reducerConfig.itemSpan | |
var tickspan = store.getState().reducerConfig.tickspan | |
var vLow = store.getState().reducerLanes.messagesCursorLow | |
var vHigh = store.getState().reducerLanes.messagesCursorHigh | |
var tickfn = setInterval(function() { | |
var currentMode = store.getState().reducerCourt.currentMode | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i]() | |
} | |
}, periodTime) | |
return stepper | |
} | |
// ____________________ subscribe | |
stepper.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
// return stepper | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return stepper | |
} | |
/* ------------- */ | |
/* tickControls */ | |
/* ------------- */ | |
function tickControls(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
// ____________________ ticker | |
function ticker() {} | |
// ____________________ start | |
ticker.start = function start() { | |
var started = false | |
var main = function(timestamp) { | |
window.requestAnimationFrame(main) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i]() | |
} | |
} | |
if (!started) { | |
started = true | |
main() | |
} | |
return ticker | |
} | |
// ____________________ subscribe | |
ticker.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return ticker | |
} | |
/* ------------- */ | |
/* mouseDownControls */ | |
/* ------------- */ | |
function mouseDownControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('mousedown', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
// return controlApi | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* touchStartControls */ | |
/* ------------- */ | |
function touchStartControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('touchstart', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
// return controlApi | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* mouseMoveControls */ | |
/* ------------- */ | |
function mouseMoveControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('mousemove', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* touchMoveControls */ | |
/* ------------- */ | |
function touchMoveControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('touchmove', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* mouseUpControls */ | |
/* ------------- */ | |
function mouseUpControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('mouseup', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
// return controlApi | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* touchEndControls */ | |
/* ------------- */ | |
function touchEndControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('touchend', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* mouseLeaveControls */ | |
/* ------------- */ | |
function mouseLeaveControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('mouseleave', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
// return controlApi | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* mouseEnterControls */ | |
/* ------------- */ | |
function mouseEnterControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
function controlAction(svg) { | |
var e = d3.event | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](svg) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start(svg) { | |
svg.on('mouseenter', function() {controlAction(this)}) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* keyDownControl */ | |
/* ------------- */ | |
function keyDownControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
var controlAction = function controlAction(e) { | |
pauseEvent(e) | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](e) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start() { | |
document.addEventListener("keydown", controlAction, false) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
// return controlApi | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* keyReleaseControl */ | |
/* ------------- */ | |
function keyReleaseControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
var controlAction = function controlAction(e) { | |
pauseEvent(e); | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i](e) | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start() { | |
document.addEventListener("keyup", controlAction, false) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
/* ------------- */ | |
/* keyPressControl */ | |
/* ------------- */ | |
function keyPressControl(payload) { | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
// ____________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
function pauseEvent(e){ | |
if(e.stopPropagation) e.stopPropagation(); | |
if(e.preventDefault) e.preventDefault(); | |
e.cancelBubble=true; | |
e.returnValue=false; | |
return false; | |
} | |
var controlAction = function controlAction(e) { | |
pauseEvent(e); | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i]() | |
} | |
} | |
// ____________________ controlApi | |
function controlApi() {} | |
// ____________________ start | |
controlApi.start = function start() { | |
document.addEventListener("keypress", controlAction, false) | |
return controlApi | |
} | |
// ____________________ subscribe | |
controlApi.subscribe = function subscribe (listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
return controlApi | |
} | |
exports.keyDownControl = keyDownControl | |
exports.keyReleaseControl = keyReleaseControl | |
exports.mouseDownControl = mouseDownControl | |
exports.touchStartControl = touchStartControl | |
exports.mouseMoveControl = mouseMoveControl | |
exports.touchMoveControl = touchMoveControl | |
exports.mouseUpControl = mouseUpControl | |
exports.touchEndControl = touchEndControl | |
exports.mouseLeaveControl = mouseLeaveControl | |
exports.mouseEnterControl = mouseEnterControl | |
exports.stepControls = stepControls | |
exports.tickControls = tickControls | |
exports.timeControls = timeControls | |
})); | |
/* */ | |
/* d3rings-reducer-config.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsActions = require('./d3rings-actions.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducerConfig = global.d3ringsReducerConfig || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ CONFIG | |
var initialStateConfig = { | |
modes: {autoMode: 'autoMode', walkMode: 'walkMode'}, | |
modeLabels: {autoMode: 'auto', walkMode: 'walk'}, | |
views: ['lanesView', 'ringsView'], | |
gravity: 0.5, | |
randNormal: d3.randomNormal(1.3, 2), | |
randNormal2: d3.randomNormal(0.5, 1.8), | |
containerElem: '#container', | |
containerId: 'svgid', | |
tickspan: 60, | |
beatTime: 500, | |
fadeFactor: 3, // times beat - fade items | |
periodFactor: 4, // times beat - add items | |
ringDefaultRadio: 6.33, | |
vstep: 50, | |
itemSpan: 6, | |
itemProps: ['to', 'from'], | |
itemVal: 'msg', | |
recordsCollection_000: [ | |
{id: "1", from: "customer", to: "barrista1", msg: "place order"}, | |
{id: "2", from: "barrista1", to: "register", msg: "enter order"}, | |
{id: "3", from: "register", to: "barrista1", msg: "give total"}, | |
{id: "4", from: "barrista1", to: "barrista1", msg: "get cup making sure that it is fine for purpose"}, | |
{id: "5", from: "barrista1", to: "barrista2", msg: "give cup"}, | |
{id: "6", from: "barrista1", to: "customer", msg: "request money"}, | |
{id: "7", from: "customer", to: "barrista1", msg: "pay order"}, | |
{id: "8", from: "barrista2", to: "barrista2", msg: "get chai mix"}, | |
{id: "9", from: "barrista2", to: "barrista2", msg: "add flavor"}, | |
{id: "10", from: "barrista2", to: "barrista2", msg: "add milk"}, | |
{id: "11", from: "barrista2", to: "barrista2", msg: "add ice"}, | |
{id: "12", from: "barrista2", to: "barrista2", msg: "swirl"}, | |
{id: "13", from: "barrista2", to: "customer", msg: "give tasty beverage"}, | |
{id: "14", from: "customer", to: "tasty beverage", msg: "sip"}, | |
{id: "15", from: "tasty beverage", to: "customer", msg: "burn"}, | |
{id: "16", from: "customer", to: "customer", msg: "cry"}, | |
{id: "17", from: "customer", to: "manager", msg: "complain"}, | |
{id: "18", from: "manager", to: "barrista1", msg: "fire"}, | |
{id: "19", from: "manager", to: "barrista2", msg: "fire"}, | |
], | |
recordsCollection: [ | |
{id: "1", from: "app", to: "store", msg: "create store"}, | |
{id: "2", from: "store", to: "store", msg: "subscribe lanes listener"}, | |
{id: "3", from: "store", to: "store", msg: "subscribe particles listener"}, | |
{id: "4", from: "app", to: "app", msg: "start kbd controller"}, | |
{id: "5", from: "app", to: "app", msg: "start mouse controller"}, | |
{id: "6", from: "ticker", to: "ticker", msg: "subscribe tickParticles"}, | |
{id: "7", from: "ticker", to: "ticker", msg: "subscribe setRecords"}, | |
{id: "8", from: "ticker", to: "ticker", msg: "start auto"}, | |
{id: "9", from: "store", to: "reducer", msg: "dispatch setRecords action"}, | |
{id: "10", from: "reducer", to: "reducer", msg: "apply action logic"}, | |
{id: "11", from: "reducer", to: "store", msg: "return new state"}, | |
{id: "12", from: "ticker", to: "ticker", msg: "run listeners"}, | |
{id: "13", from: "renderer", to: "UI", msg: "render lanes"}, | |
{id: "14", from: "UI", to: "app", msg: "trigger left arrow event"}, | |
{id: "15", from: "store", to: "reducer", msg: "dispatch setMode action"}, | |
{id: "16", from: "reducer", to: "reducer", msg: "run action"}, | |
{id: "17", from: "reducer", to: "store", msg: "return new state"}, | |
{id: "18", from: "ticker", to: "ticker", msg: "run listeners"}, | |
{id: "19", from: "UI", to: "app", msg: "send down arrow event"}, | |
{id: "20", from: "store", to: "reducer", msg: "dispatch setRecods action"}, | |
{id: "21", from: "reducer", to: "reducer", msg: "run action and get record"}, | |
{id: "22", from: "reducer", to: "reducer", msg: "return new set"}, | |
{id: "23", from: "ticker", to: "ticker", msg: "run listeners"}, | |
{id: "24", from: "renderer", to: "UI", msg: "render lanes"}, | |
{id: "25", from: "UI", to: "app", msg: "send right arrow event"}, | |
{id: "26", from: "store", to: "reducer", msg: "dispatch setMode action"}, | |
{id: "27", from: "reducer", to: "reducer", msg: "run action"}, | |
{id: "28", from: "reducer", to: "reducer", msg: "return new mode auto"}, | |
{id: "29", from: "ticker", to: "ticker", msg: "run listeners with new state"}, | |
{id: "30", from: "renderer", to: "UI", msg: "render auto lanes"}, | |
{id: "31", from: "store", to: "reducer", msg: "dispatch createParticles action"}, | |
{id: "32", from: "reducer", to: "reducer", msg: "run action"}, | |
{id: "33", from: "reducer", to: "store", msg: "return new state with particles"}, | |
{id: "34", from: "ticker", to: "ticker", msg: "run particles listeners"}, | |
{id: "35", from: "renderer", to: "UI", msg: "render particles"}, | |
], | |
} | |
function reducerConfig(state = initialStateConfig, action) { | |
if (action == null) return state | |
var ActionTypes = d3ringsActions.ActionTypes | |
switch (action.type) { | |
default: | |
return state; | |
} | |
} | |
exports.reducerConfig = reducerConfig; | |
})); | |
/* */ | |
/* d3rings-reducer.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsActions = require('./d3rings-actions-court.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducerCourt = global.d3ringsReducerCourt || {}))); | |
}(this, function (exports) { 'use strict'; | |
// http://stackoverflow.com/questions/31381129/assign-new-id-attribute-to-each-element-created | |
function guid() { | |
function _p8(s) { | |
var p = (Math.random().toString(16)+"000000000").substr(2,8); | |
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ; | |
} | |
return _p8() + _p8(true) + _p8(true) + _p8(); | |
} | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ COURT | |
var initialStateCourt = { | |
leftBorder: 0, // | |
svgHeight: 400, // | |
svgWidth: 600, // | |
keys: [], | |
keysEvents: {}, | |
notice: 'auto lanes', | |
currentMode: 'autoMode', | |
currentView: 'ringsView', | |
arrowKeysStarted: false, | |
keybKeyEventsStarted: false, | |
tickerStarted: false, | |
lastTick: 0, | |
mousePos: [200, 300], | |
} | |
function reducerCourt(state = initialStateCourt, action) { | |
if (action == null) return state | |
var ActionTypes = d3ringsActions.ActionTypes | |
switch (action.type) { | |
case ActionTypes.START_KEYBKEY_EVENTS: // startKeybKeyEvents | |
// console.log('START_KEYBKEY_EVENTS') | |
return Object.assign({}, state, { | |
keybKeyEventsStarted: true | |
}) | |
case ActionTypes.SET_KEYBKEY: // setKeybkey | |
// console.log('SET_KEYBKEY') | |
var ks = state.keys | |
ks[action.keyCode] = true | |
return Object.assign({}, state, { | |
keys: ks | |
}) | |
case ActionTypes.RELEASE_KEYBKEY: // releaseKeybkey | |
// console.log('RELEASE_KEYBKEY') | |
var ks = state.keys | |
ks[action.keyCode] = false | |
return Object.assign({}, state, { | |
keys: ks | |
}) | |
case ActionTypes.PROCESS_KEYB_KEYS: // processKeybKeys | |
// console.log('PROCESS_KEYB_KEYS state keys', state.keys) | |
var keyEvents = Object.assign({}, state.keyEvents) | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = state.keys | |
if (keys[ctrlKeyCode] !== true && keys[altKeyCode] == true && keys[vKeyCode] == true) { // alt-v | |
keyEvents.altvKey = guid() | |
} | |
if (keys[ctrlKeyCode] !== true && keys[altKeyCode] !== true && keys[vKeyCode] == true) { // v | |
keyEvents.vKey = guid() | |
} | |
if (keys[leftArrow] == true) { // leftArrow | |
keyEvents.leftArrow = guid() | |
} | |
if (keys[rightArrow] == true) { // rightArrow | |
keyEvents.rightArrow = guid() | |
} | |
if (keys[upArrow] == true) { // upArrow | |
keyEvents.upArrow = guid() | |
} | |
if (keys[downArrow] == true) { // downArrow | |
keyEvents.downArrow = guid() | |
} | |
return Object.assign({}, state, { | |
keyEvents: keyEvents | |
}) | |
case ActionTypes.SET_MODE: | |
// console.log('SET_MODE') | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var currentMode = state.currentMode | |
var newMode = currentMode | |
if (keys[leftArrow] == true) { // leftArrow | |
newMode = 'walkMode' | |
} | |
if (keys[rightArrow] == true) { // rightArrow | |
newMode = 'autoMode' | |
} | |
if (keys[upArrow] == true) { // upArrow | |
if (currentMode == 'autoMode') { | |
newMode = 'walkMode' | |
} | |
} | |
if (keys[downArrow] == true) { // downArrow | |
if (currentMode == 'autoMode') { | |
newMode = 'walkMode' | |
} | |
} | |
return Object.assign({}, state, { | |
currentMode: newMode | |
}) | |
case ActionTypes.SET_VIEW: // setView // views currentView | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var views = action.payload.views | |
var currentView = action.payload.currentView | |
var currentViewIndex = views.indexOf(currentView) | |
var newViewIndex = currentView | |
if (keys[vKeyCode] == true && keys[altKeyCode] == true) { // alt-v | |
newViewIndex = views[Math.abs(currentViewIndex + 1) % views.length] | |
} | |
return Object.assign({}, state, { | |
currentView: newViewIndex, | |
}); | |
case ActionTypes.SET_NOTICE: | |
// console.log('SET_NOTICE') | |
return Object.assign({}, state, { | |
notice: action.notice, | |
}); | |
case ActionTypes.START_TICKER: | |
// console.log('START_TICKER') | |
return Object.assign({}, state, { | |
tickerStarted: true | |
}); | |
case ActionTypes.STOP_TICKER: | |
// console.log('STOP_TICKER') | |
return Object.assign({}, state, { | |
tickerStarted: false | |
}); | |
case ActionTypes.UPDATE_MOUSE_POS: | |
var coords = d3.mouse(action.svg) | |
var x = coords[0] | |
var y = coords[1] | |
return Object.assign({}, state, { | |
mousePos: [x, y] | |
}); | |
case ActionTypes.RESIZE_WIDTH: | |
// console.log('RESIZE_WIDTH') | |
var svgWidth = state.svgWidth | |
var delta = 10 | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var newSvgWidth = svgWidth | |
if (keys[rightArrow] == true && keys[ctrlKeyCode] == true) { // rightArrow-Ctrl | |
newSvgWidth = svgWidth + delta | |
} | |
if (keys[leftArrow] == true && keys[ctrlKeyCode] == true) { // lefftArrow-Ctrl | |
newSvgWidth = svgWidth - delta | |
} | |
return Object.assign({}, state, { | |
svgWidth: newSvgWidth | |
}) | |
case ActionTypes.RESIZE_HEIGHT: | |
// console.log('RESIZE_HEIGHT') | |
var svgHeight = state.svgHeight | |
var delta = 10 | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var newSvgHeight = svgHeight | |
if (keys[upArrow] == true && keys[ctrlKeyCode] == true) { // upArrow-Ctrl | |
newSvgHeight = svgHeight + delta | |
} | |
if (keys[downArrow] == true && keys[ctrlKeyCode] == true) { // downArrow-Ctrl | |
newSvgHeight = svgHeight - delta | |
} | |
return Object.assign({}, state, { | |
svgHeight: newSvgHeight | |
}) | |
default: | |
return state; | |
} | |
} | |
exports.reducerCourt = reducerCourt; | |
})); | |
/* */ | |
/* d3rings-reducer-debug.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsActions = require('./d3rings-actions-debug.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducerDebug = global.d3ringsReducerDebug || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ DEBUG | |
var initialStateDebug = { | |
debugMode: true, | |
debugTickerStarted: false, | |
rfps: 60, | |
fps: 0, | |
fpsMax: 0, | |
timeStamp: 0, | |
timeLastFrame: 0, | |
tickLastFrame: 0, | |
} | |
function reducerDebug(state = initialStateDebug, action) { | |
if (action == null) return state | |
var ActionTypes = d3ringsActions.ActionTypes | |
switch (action.type) { | |
case ActionTypes.SET_FPS: | |
return setFps(state, action) | |
case ActionTypes.SWITCH_DEBUGMODE: | |
return switchDebugMode(state, action) | |
default: | |
return state; | |
} | |
} | |
function setFps(state, action) { | |
// tbc | |
var timeLastFrame0 = state.timeLastFrame | |
var tickLastFrame0 = state.tickLastFrame | |
var timeLastFrame = performance.now() | |
var tickLastFrame = tickLastFrame0 + 1 | |
var timeDelta = timeLastFrame - timeLastFrame0 | |
var fps0 = state.fps | |
var fpsMax = state.fpsMax | |
var fps = (timeLastFrame != 0) ? parseFloat(Math.round(1000 / timeDelta)).toFixed(0) : 0 | |
var fpsMax = Math.max(fpsMax, fps) | |
return Object.assign({}, state, { | |
fps: fps, | |
fpsMax: fpsMax, | |
debugTickerStarted: true, | |
timeLastFrame: timeLastFrame, | |
tickLastFrame: tickLastFrame | |
}) | |
} | |
function switchDebugMode(state, action) { | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var debugMode = state.debugMode | |
var newdebugMode = debugMode | |
if (keys[dKeyCode] == true && keys[altKeyCode] == true) { // alt-d | |
newdebugMode = !state.debugMode | |
} | |
return Object.assign({}, state, { | |
debugMode: newdebugMode | |
}) | |
} | |
exports.reducerDebug = reducerDebug; | |
})); | |
/* */ | |
/* d3rings-reducer-lanes.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsActions = require('./d3rings-actions-lanes.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducerLanes = global.d3ringsReducerLanes || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ LANES | |
var initialStateLanes = { | |
lanes: [], | |
lanesIndex: 0, | |
messages: [], | |
records: [], | |
keyEventsOnLanes: {}, | |
recordsCollection: [], | |
areRecordsFetched: false, | |
messagesCursorLow: 0, | |
messagesCursorHigh: 0, | |
} | |
function reducerLanes(state = initialStateLanes, action) { | |
if (action == null) return state | |
var ActionTypes = d3ringsActions.ActionTypes | |
switch (action.type) { | |
case ActionTypes.DELETE_LANE: // deleteLane | |
var lanes = state.lanes | |
var ls = lanes.filter(function( obj ) { | |
return obj.id !== action.lane.id; | |
}) | |
var r = Object.assign({}, state, | |
{lanes: ls}, | |
{lanesIndex: ls.length} | |
) | |
return r | |
case ActionTypes.SET_LANE: // setLane | |
var lanes = state.lanes | |
var ls = {} | |
var result = lanes.filter(function( obj ) { | |
return obj.id == action.lane.id; | |
}); | |
if (result.length === 0) { // add | |
ls = {lanes: [ | |
{ | |
id: action.lane.id, | |
name: action.lane.name, | |
x: action.lane.x | |
}, | |
...lanes | |
]} | |
} else { // edit | |
ls = {lanes: lanes.map(lane => | |
lane.id === action.lane.id ? | |
Object.assign({}, lane, { id: action.lane.id, name: action.lane.name, x: action.lane.x }) : | |
lane | |
)} | |
} | |
var r = Object.assign({}, state, | |
ls, | |
{ | |
lanesIndex: ls.lanes.length | |
}) | |
return r | |
case ActionTypes.SET_LANES: // setLanes | |
// console.log('SET_LANES') | |
return Object.assign({}, state, { | |
lanes: action.lanes, | |
lanesIndex: Object.keys(action.lanes).length | |
}) | |
case ActionTypes.FETCH_RECORDS: // fetchRecords | |
// console.log('FETCH_RECORDS') | |
var processRecord = function processRecord(d) { | |
d.amount = +d.amount; | |
d.risk = +d.risk; | |
d.valueOf = function value() { | |
return this.amount; | |
} | |
return d; | |
} | |
var processData = function processData(error, dataCsv) { | |
if (store.getState().court.currentMode == 0) { // _tbd_ | |
++timeTick | |
++vLast | |
store.dispatch(actions.setMessages(store.getState().reducerConfig.recordsCollection.slice(0, | |
store.getState().reducerConfig.recordsCollection.length))) | |
} | |
} | |
d3.queue() | |
.defer(d3.csv, action.src, processRecord) | |
.await(processData) | |
return Object.assign({}, state); | |
case ActionTypes.SET_MESSAGES: | |
// console.log('SET_MESSAGES') | |
return Object.assign({}, state, { | |
messages: action.messages, | |
}) | |
case ActionTypes.SET_RECORDS_FETCHED: | |
// console.log('SET_RECORDS_FETCHED') | |
return Object.assign({}, state, { | |
areRecordsFetched: action.areRecordsFetched | |
}) | |
case ActionTypes.SET_RECORDS_COLLECTION: // setRecordsCollection | |
var r = state | |
if (state.areRecordsFetched == false) { | |
// console.log('SET_RECORDS_COLLECTION') | |
var r = Object.assign({}, state, { | |
recordsCollection: action.recordsCollection, | |
areRecordsFetched: true, | |
}) | |
} | |
return r | |
case ActionTypes.SET_RECORDS: | |
// console.log('SET_RECORDS') | |
var vLow = state.messagesCursorLow | |
var vHigh = state.messagesCursorHigh | |
var itemSpan = action.itemSpan | |
var mode = action.mode | |
var r = state | |
if (mode == 'autoMode') { | |
var records = state.recordsCollection | |
var numRecords = records.length | |
if (vHigh >= vLow) vHigh = vHigh + 1 // add one to upper border | |
if (vHigh > numRecords) vHigh = -1 // upper border | |
if (((vHigh - vLow) > itemSpan) // all spteps full | |
|| (vHigh == -1) // infinitum with vLow active | |
|| (vLow == -1) // get always from reset | |
) vLow = vLow + 1 // increase lower border | |
if (vLow > numRecords) vLow = -1 // reset at end of cycle | |
r = Object.assign({}, state, { | |
records: state.recordsCollection.slice(vLow, vHigh), | |
messagesCursorLow: vLow, | |
messagesCursorHigh: vHigh, | |
}) | |
} | |
return r | |
case ActionTypes.WALK_UP_RECORDS: // walkUpRecords | |
var keyEventsOnLanes = state.keyEventsOnLanes | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var vLow = state.messagesCursorLow | |
var vHigh = state.messagesCursorHigh | |
var itemSpan = action.payload.itemSpan | |
var currentMode = action.payload.mode | |
var r = state | |
if (currentMode == 'walkMode') { | |
if (keyEventsOnLanes.upArrow !== null && keyEventsOnLanes.upArrow !== action.payload.keyEvents.upArrow) { // upArrow | |
keyEventsOnLanes.upArrow = action.payload.keyEvents.upArrow | |
vLow = Math.max(0, --vLow) | |
r = Object.assign({}, state, keyEventsOnLanes) | |
r = Object.assign({}, state, { | |
records: state.recordsCollection.slice(vLow, vHigh), | |
messagesCursorLow: vLow, | |
messagesCursorHigh: vHigh, | |
}) | |
} | |
} | |
return r | |
case ActionTypes.WALK_DOWN_RECORDS: // walkDownRecords | |
var keyEventsOnLanes = state.keyEventsOnLanes | |
var altKeyCode = 18, ctrlKeyCode = 17 | |
var vKeyCode = 86, dKeyCode = 68, fKeyCode = 70 | |
var leftArrow = 37, rightArrow = 39, leftArrow = 37, upArrow = 38, downArrow = 40 | |
var keys = action.payload.keys | |
var vLow = state.messagesCursorLow | |
var vHigh = state.messagesCursorHigh | |
var itemSpan = action.payload.itemSpan | |
var currentMode = action.payload.currentMode | |
var r = Object.assign({}, state) | |
if (currentMode == 'walkMode') { | |
if (keyEventsOnLanes.downArrow !== null && keyEventsOnLanes.downArrow !== action.payload.keyEvents.downArrow) { // downArrow | |
keyEventsOnLanes.downArrow = action.payload.keyEvents.downArrow | |
r = Object.assign({}, state, keyEventsOnLanes) | |
if ((vHigh - vLow) >= itemSpan) ++vLow | |
++vHigh | |
r = Object.assign({}, state, { | |
records: state.recordsCollection.slice(vLow, vHigh), | |
messagesCursorLow: vLow, | |
messagesCursorHigh: vHigh, | |
}) | |
} | |
} | |
return r | |
default: | |
return state | |
} | |
} | |
exports.reducerLanes = reducerLanes; | |
})); | |
/* */ | |
/* d3rings-reducer-particles.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsActions = require('./d3rings-actions-particles.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducerParticles = global.d3ringsReducerParticles || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ PARTICLES | |
var initialStateParticles = { | |
particles: [], | |
particleIndex: 0, | |
particlesGenerating: true, | |
particlesIntroduced: false, | |
particlesPerTick: 10, | |
particleRadio: 9, | |
} | |
function reducerParticles(state = initialStateParticles, action) { | |
if (action == null) return state | |
var ActionTypes = d3ringsActions.ActionTypes | |
switch (action.type) { | |
case ActionTypes.START_PARTICLES: // startParticles | |
// console.log("START_PARTICLES") | |
return Object.assign({}, state, { | |
particlesGenerating: true | |
}) | |
case ActionTypes.STOP_PARTICLES: // stopParticles | |
// console.log("STOP_PARTICLES") | |
return Object.assign({}, state, { | |
// particlesGenerating: false | |
}); | |
case ActionTypes.INTRODUCE_PARTICLES: // introduceParticles | |
var newParticles = state.particles.slice(0) | |
var numberOfNewParticles = 5 * action.particlesPerTick | |
var currentView = action.currentView | |
var i | |
if ((state.particlesIntroduced == false) && (currentView == 'lanesView')) { | |
for (i = 0; i < numberOfNewParticles; i++) { | |
var particle = {id: state.particleIndex+i, | |
x: action.x, | |
y: action.y, | |
closestLaneDown: {id: 'init', x: action.xInit}, | |
closestLaneUp: {id: 'end', x: action.xEnd}, | |
} | |
particle.vector = [particle.id%2 ? - action.randNormal() : action.randNormal(), | |
- action.randNormal2() * 3.3]; | |
newParticles.unshift(particle); | |
} | |
return Object.assign({}, state, { | |
particles: newParticles, | |
particleIndex: state.particleIndex+i+1, | |
particlesIntroduced: true | |
}) | |
} else { | |
return state | |
} | |
case ActionTypes.CREATE_PARTICLES: // createParticles | |
var newParticles = state.particles.slice(0) | |
var numberOfNewParticles = action.particlesPerTick | |
var particlesGenerating = action.particlesGenerating | |
var currentView = action.currentView | |
if ((particlesGenerating == true) && (currentView == 'lanesView') ){ | |
for (var i = 0; i < numberOfNewParticles; i++) { | |
var ref = parseInt(action.x) | |
var closestLaneUp = action.lanes | |
.filter(function (d) {return d.x >= ref} ) | |
.reduce(function (prev, curr) { | |
return (Math.abs(curr.x - ref) < Math.abs(prev.x - ref) ? curr : prev); | |
}, {id: 'end', x: action.xEnd}) | |
var closestLaneDown = action.lanes | |
.filter(function (d) {return d.x <= ref} ) | |
.reduce(function (prev, curr) { | |
return (Math.abs(curr.x - ref) < Math.abs(prev.x - ref) ? curr : prev); | |
}, {id: 'init', x: action.xInit}) | |
var particle = {id: state.particleIndex+i, | |
x: action.x, | |
y: action.y, | |
closestLaneDown: closestLaneDown, | |
closestLaneUp: closestLaneUp, | |
}; | |
particle.vector = [particle.id%2 ? - action.randNormal() : action.randNormal(), | |
- action.randNormal2()*3.3]; | |
newParticles.unshift(particle); | |
} | |
return Object.assign({}, state, { | |
particles: newParticles, | |
particleIndex: state.particleIndex+i+1 | |
}) | |
} else { | |
return state | |
} | |
case ActionTypes.TICK_PARTICLES: // tickParticles | |
var laneXs = action.lanes | |
.map(function(l) { | |
var x = parseInt(l.x) | |
return x}) | |
var svgWidth = action.width | |
var svgHeight = action.height | |
var gravity = action.gravity | |
var movedParticles = state.particles | |
.filter(function (p) { | |
return (!(p.y > svgHeight)) | |
}) | |
.filter(function (p) { | |
return (!(p.y < 0)) | |
}) | |
.map(function (p) { | |
var vx = p.vector[0] | |
var vy = p.vector[1] | |
p.x += vx | |
p.y += vy | |
var ref = parseInt(p.x) | |
var laneUp = action.lanes | |
.filter(function(l) { | |
return (l.id == p.closestLaneUp.id) | |
}) | |
p.closestLaneUp.x = (laneUp.length > 0 ) ? +laneUp[0].x : +p.closestLaneUp.x | |
var laneDown = action.lanes | |
.filter(function(l) { | |
return (l.id == p.closestLaneDown.id) | |
}) | |
p.closestLaneDown.x = (laneDown.length > 0 ) ? +laneDown[0].x : +p.closestLaneDown.x | |
if (ref < (p.closestLaneDown.x + state.particleRadio) || ref > (p.closestLaneUp.x - state.particleRadio)) { | |
p.vector[0] = -p.vector[0] | |
} | |
p.vector[1] += gravity + 2 * gravity * (p.y - svgHeight) / svgHeight | |
return p | |
}); | |
return Object.assign({}, state, { | |
particles: movedParticles, | |
particleIndex: movedParticles.length, | |
}); | |
default: | |
return state; | |
} | |
} | |
exports.reducerParticles = reducerParticles; | |
})); | |
/* */ | |
/* d3rings-reducer-whirls.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsActions = require('./d3rings-actions-whirls.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducerWhirls = global.d3ringsReducerWhirls || {}))); | |
}(this, function (exports) { 'use strict'; | |
// http://stackoverflow.com/questions/31381129/assign-new-id-attribute-to-each-element-created | |
function guid() { | |
function _p8(s) { | |
var p = (Math.random().toString(16)+"000000000").substr(2,8); | |
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ; | |
} | |
return _p8() + _p8(true) + _p8(true) + _p8(); | |
} | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ RANGS | |
var initialStateThis = { | |
duration: 2500, | |
n: 3, | |
s0: 200, | |
s: 200, | |
rangs: [], | |
rangsNow: 0, | |
rangsAlways: 0, | |
startRangs: true, | |
rings: [], | |
ringsNew: [], | |
ringsIndex: 0, | |
ringsHits: 0, | |
rangsHitsIndex: 0, | |
rangsHits: [], | |
ringsIntroduced: false, | |
ringsPerTick: 3, | |
ringsRadio: 9, | |
ringsGenerating: true, | |
} | |
function reducerThis(state = initialStateThis, action) { | |
if (action == null) return state | |
var ActionTypes = d3ringsActions.ActionTypes | |
switch (action.type) { | |
case ActionTypes.DELETE_RANG: | |
var rangs = state.rangs | |
var items = rangs.filter(function( obj ) { | |
return obj.rid !== action.rang.rid; | |
}); | |
var r = Object.assign({}, state, | |
{rangs: items}, | |
{rangsNow: items.length} | |
); | |
return r | |
case ActionTypes.INIT_RANGS: | |
return Object.assign({}, state, { | |
startRangs: true | |
}) | |
case ActionTypes.STOP_RANGS: | |
// console.log('STOP_RANGS') | |
return Object.assign({}, state, { | |
// startRangs: false | |
}) | |
case ActionTypes.SET_RANG: // setRang | |
var rangs = state.rangs | |
var s0 = state.s0 | |
var rangsAlways = state.rangsAlways | |
var items = {} | |
var result = rangs.filter(function( obj ) { | |
return obj.id == action.rang.id; | |
}); | |
if (result.length === 0) { // add rang | |
items = {rangs: [ | |
{ | |
id: action.rang.id, | |
rid: action.rang.rid, | |
grid: action.rang.grid, | |
x: action.rang.x, | |
y: action.rang.y, | |
s: action.rang.s, | |
t: action.rang.t, | |
sn: action.rang.s, | |
s: s0, | |
}, | |
...rangs | |
]} | |
rangsAlways = rangsAlways + 1 | |
} else { // edit rang | |
items = {rangs: rangs.map(rang => | |
rang.rid === action.rang.rid ? | |
Object.assign({}, rang, { | |
rid: action.rang.rid, | |
grid: action.rang.grid, | |
x: action.rang.x, | |
y: action.rang.y, | |
s: action.rang.s, | |
sn: rang.s, | |
s0: s0, | |
}) : | |
rang | |
)} | |
} | |
var r = Object.assign({}, state, | |
items, | |
{rangsNow: items.rangs.length, | |
rangsAlways: rangsAlways} | |
) | |
return r | |
case ActionTypes.SET_RANGS: // setRangs | |
// console.log('SET_RANGS') | |
return Object.assign({}, state, { | |
rangs: action.rangs, | |
rangsNow: Object.keys(action.rangs).length | |
}) | |
case ActionTypes.UPDATE_RANGS_DURATION: // updateRangsDuration | |
var duration = state.duration | |
var hitsLostPct = Math.round(100 * (action.rangsAlways - action.rangsHitsIndex) / action.rangsAlways) || 0 | |
if (hitsLostPct < 20) duration = Math.min(Math.max((50 - hitsLostPct) * 20, 1500), 2500) | |
return Object.assign({}, state, { | |
duration: duration, | |
}) | |
case ActionTypes.UPDATE_RANGS_NUMBER: // updateRangsNumber | |
var n = state.n | |
var hitsLostPct = Math.round(100 * (action.rangsAlways - action.rangsHitsIndex) / action.rangsAlways) || 0 | |
var hitsPctBy10 = Math.floor((100 - hitsLostPct)/10) | |
var rangsMax = Math.max(hitsPctBy10, 2) | |
var rangsNumber = Math.min(rangsMax, 8) | |
return Object.assign({}, state, { | |
n: rangsNumber, | |
}) | |
case ActionTypes.CREATE_RINGS: // createRings | |
var _duration = state.duration | |
var _newRings = [] | |
var _ringsHits = state.ringsHits | |
var _rangsHits = state.rangsHits | |
var _rangsHitsIndex = state.rangsHitsIndex | |
if (action.ringsGenerating == true) { | |
var ringsRadio = state.ringsRadio | |
var idx = state.ringsIndex | |
var i, j | |
for (j = 0; j < action.rangs.length; ++j) { | |
var cx = action.x | |
var cy = action.y | |
function inSquare (cx, cy, xl, yl, xh, yh) { | |
if (cx > xl && cx < xh && cy > yl && cy < yh) return true | |
else return false | |
} | |
var xl = action.rangs[j].x | |
var yl = action.rangs[j].y | |
var xh = action.rangs[j].x + action.rangs[j].s | |
var yh = action.rangs[j].y + action.rangs[j].s | |
if (inSquare (cx, cy, xl, yl, xh, yh)) { | |
var rang = action.rangs[j] | |
var rid = rang.id | |
var grid = rang.grid | |
var t = rang.t | |
var s = rang.s | |
var s0 = rang.s0 | |
var r0 = (ringsRadio * s / s0) || 0 | |
var r = (ringsRadio * s / s0) || 0 | |
for (i = 0; i < action.ringsPerTick; i++) { | |
var ring = { | |
id: guid(), | |
cx: cx, | |
cy: cy, | |
r0: r0, | |
r: r, | |
rid: rid, | |
grid: grid, | |
rang: rang, | |
}; | |
ring.vector = [ring.id%2 ? - action.randNormal() : action.randNormal(), | |
- action.randNormal2()] | |
_newRings.unshift(ring) | |
} | |
_ringsHits = _ringsHits + 1 | |
if (_rangsHits.indexOf(grid) == -1) { | |
_rangsHits.push(grid) | |
} | |
_rangsHitsIndex = _rangsHits.length | |
} | |
} | |
var _ringsAll = state.rings.slice(0).concat(_newRings) | |
return Object.assign({}, state, { | |
rings: _ringsAll, | |
ringsNew: _newRings, | |
ringsIndex: _ringsAll.length, | |
ringsHits: _ringsHits, | |
rangsHits: _rangsHits, | |
rangsHitsIndex: _rangsHitsIndex, | |
}) | |
} else { | |
return state | |
} | |
case ActionTypes.DELETE_RING: // deleteRing | |
var rings = state.rings | |
var items = rings.filter(function( obj ) { | |
return obj.id !== action.ring.id; | |
}); | |
var r = Object.assign({}, state, | |
{rings: items}, | |
{ringsIndex: items.length} | |
) | |
return r | |
case ActionTypes.SET_DURATION: // setDuration | |
// console.log("SET_DURATION") | |
return Object.assign({}, state, { | |
duration: action.duration | |
}) | |
case ActionTypes.START_RINGS: // startRings | |
// console.log("START_RINGS") | |
return Object.assign({}, state, { | |
ringsGenerating: true | |
}) | |
case ActionTypes.STOP_RINGS: // stopRings | |
// console.log("STOP_RINGS") | |
return Object.assign({}, state, { | |
// ringsGenerating: false | |
}); | |
case ActionTypes.TICK_RING: // tickRing | |
var duration = state.duration | |
var ringsRadio = state.ringsRadio // init ring radio | |
var rangs = state.rangs | |
var ringsNew = [] | |
var hitRangs = rangs | |
.filter(function (d) { return (d.id == action.ring.rid) }) | |
if (hitRangs.length > 0) { | |
var rang = hitRangs[0] // rang by id | |
var speed = rang.s0/duration | |
var xe = rang.x + rang.s | |
var xw = rang.x | |
var yn = rang.y | |
var ys = rang.y + rang.s | |
var t = action.ring.t | |
var tn = action.ring.tn | |
var deltas = rang.s - rang.sn | |
var deltat = t - tn | |
var v = deltas/deltat || 0 | |
ringsNew = state.rings // get other rings | |
.reduce(function (a, d) { | |
if (d.id == action.ring.id) { | |
var randx = d.vector[0] | |
var randy = d.vector[1] | |
var dcx = d.cx | |
var dcy = d.cy | |
var dr = d.r | |
var dr0 = d.r0 | |
if (dr > deltas) { | |
if (dcx - dr < xw) randx = - randx | |
if (dcx + dr > xe) randx = randx + 2 * deltas | |
if (dcy - dr < yn) randy = - randy | |
if (dcy + dr > ys) randy = randy + 2 * deltas | |
var xnp1 = dcx + randx | |
var ynp1 = dcy + randy | |
d.tn = t | |
d.r = (1 - t) * dr0 | |
d.vector[0] = randx | |
d.vector[1] = randy | |
var xpose = Math.max(xw, xnp1) | |
var xpos = Math.min(xpose, xe) | |
var yposn = Math.max(yn, ynp1) | |
var ypos = Math.min(yposn, ys) | |
d.cx = xpos | |
d.cy = ypos | |
a.push(d) | |
} | |
return a | |
} else { | |
a.push(d) | |
return a | |
} | |
}, []) | |
} | |
return Object.assign({}, state, { | |
rings: ringsNew, | |
ringsIndex: ringsNew.length, | |
}) | |
default: | |
return state; | |
} | |
} | |
exports.reducer = reducerThis | |
})); | |
/* */ | |
/* d3rings-reducer.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3ringsReducerConfig = require('./d3rings-reducer-config.js') | |
var d3ringsReducerCourt = require('./d3rings-reducer-court.js') | |
var d3ringsReducerDebug = require('./d3rings-reducer-debug.js') | |
var d3ringsReducerLanes = require('./d3rings-reducer-lanes.js') | |
var d3ringsReducerParticles = require('./d3rings-reducer-particles.js') | |
var d3ringsReducerWhirls = require('./d3rings-reducer-whirls.js') | |
// var d3ringsReducerRangs = require('./d3rings-reducer-rangs.js') | |
// var d3ringsReducerRings = require('./d3rings-reducer-rings.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsReducer = global.d3ringsReducer || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ adapted from redux combineReducers | |
function combineReducers(reducers) { | |
var reducerKeys = Object.keys(reducers) | |
var finalReducers = {} | |
for (var i = 0; i < reducerKeys.length; i++) { | |
var key = reducerKeys[i] | |
if (typeof reducers[key] === 'function') { | |
finalReducers[key] = reducers[key] | |
} | |
} | |
var finalReducerKeys = Object.keys(finalReducers) | |
return function combination(state = {}, action) { | |
var hasChanged = false | |
var nextState = {} | |
for (var i = 0; i < finalReducerKeys.length; i++) { | |
var key = finalReducerKeys[i] | |
var reducer = finalReducers[key] | |
var previousStateForKey = state[key] | |
var nextStateForKey = reducer(previousStateForKey, action) | |
if (typeof nextStateForKey === 'undefined') { | |
var errorMessage = getUndefinedStateErrorMessage(key, action) | |
throw new Error(errorMessage) | |
} | |
nextState[key] = nextStateForKey | |
hasChanged = hasChanged || nextStateForKey !== previousStateForKey | |
} | |
return hasChanged ? nextState : state | |
} | |
} | |
// _____________ combined reducer | |
var reducer = combineReducers({ | |
reducerConfig: d3ringsReducerConfig.reducerConfig, | |
reducerCourt: d3ringsReducerCourt.reducerCourt, | |
reducerDebug: d3ringsReducerDebug.reducerDebug, | |
reducerLanes: d3ringsReducerLanes.reducerLanes, | |
reducerParticles: d3ringsReducerParticles.reducerParticles, | |
reducerWhirls: d3ringsReducerWhirls.reducer, | |
// reducerRangs: d3ringsReducerRangs.reducer, | |
// reducerRings: d3ringsReducerRings.reducer, | |
}) | |
var r = reducer() | |
exports.reducer = reducer; | |
})); | |
/* */ | |
/* d3rings-renderer-court.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsRendererCourt = global.d3ringsRendererCourt || {}))); | |
}(this, function (exports) { 'use strict'; | |
function renderer(payload) { | |
var store = payload.store | |
var actions = payload.actions | |
var newState = store.getState() | |
var state | |
doRender(newState) | |
function doRender(newState) { | |
if (state === newState) return | |
state = newState | |
var svgContainer = d3.select(state.reducerConfig.containerElem) | |
.selectAll('svg') | |
.data(['svg']) | |
var svgContainerNew = svgContainer.enter() | |
.append("svg") | |
.attr("id", state.reducerConfig.containerId) | |
.style('width', state.reducerCourt.svgWidth) | |
.style('height', state.reducerCourt.svgHeight) | |
.attr('class', 'bar-chart') // | |
.style('border', '1px solid red') | |
.style('color', 'blue') | |
.attr('viewbox',"0 0 3 2") | |
var svg = d3.select('svg') | |
var itemsGroup = d3.select('svg') | |
.selectAll('g.notices') // items | |
.data(['items']) | |
itemsGroup.enter() | |
.append("g") | |
.classed("notices", true) // items | |
// _________________________________ render Notice Update | |
var errorNotice = (state.reducerCourt.notice) ? state.reducerCourt.notice : "" | |
var noticeToShow = " " | |
var currentView = state.reducerCourt.currentView | |
var labelMode = state.reducerConfig.modeLabels[state.reducerConfig.modes[state.reducerCourt.currentMode]] | |
var size = parseInt(svg.style("width")) + " x " + parseInt(svg.style("height")) | |
var rangsNow = state.reducerWhirls.rangsNow | |
var particlesNow = state.reducerParticles.particleIndex | |
var ringsNow = state.reducerWhirls.ringsIndex | |
var startRangs = state.reducerWhirls.startRangs | |
var rangsAlways = state.reducerWhirls.rangsAlways | |
var ringsHits = state.reducerWhirls.ringsHits | |
var rangsHitsIndex = state.reducerWhirls.rangsHitsIndex | |
var framesPerSecond = state.reducerDebug.fps | |
var framesPerSecondMax = state.reducerDebug.fpsMax | |
var framesLostPct = (framesPerSecondMax == 0) ? 0 : Math.round(100 * (framesPerSecondMax - framesPerSecond) / framesPerSecondMax) | |
var hitsLostPct = Math.round(100 * (rangsAlways - rangsHitsIndex) / rangsAlways) || 0 | |
if (currentView == 'lanesView') { | |
var cmdsLanes = "down-arrow, right-arrow, alt-v" | |
noticeToShow = noticeToShow + | |
cmdsLanes + " - " + currentView + | |
" - n: " + particlesNow + | |
" - fps: " + framesPerSecond | |
} | |
if (currentView == 'ringsView') { | |
noticeToShow = noticeToShow + | |
((startRangs) ? '' : ' MOUSE PLEASE !!! ') + | |
' you already missed ' + hitsLostPct + ' % of your ' + rangsAlways + ' rings' + | |
' and ' + framesLostPct + ' % of your frames ' + | |
'!!! ' + | |
' (' + 'try alt-v' + ')' | |
} | |
var winWidthPixels = parseInt(svg.style("width")) | |
var winHeightPixels = parseInt(svg.style("height")) | |
var fontSizeHw = 2 + "hw" | |
var fontSize = winWidthPixels * 2/100 | |
var fontname = 'sans-serif' | |
var c=document.createElement('canvas'); | |
var ctx=c.getContext('2d'); | |
ctx.font = fontSize + 'px ' + fontname; | |
var noticeLength = ctx.measureText(noticeToShow).width | |
var vlocation = winHeightPixels - fontSize | |
var hlocation = winWidthPixels - noticeLength | |
// items elems | |
var itemsElems = svgContainer | |
.select("g.notices") | |
.selectAll("g.notice") | |
.data([noticeToShow]); | |
// items elems enter | |
var itemsElemsNew = itemsElems.enter() | |
.append("g") | |
.classed("notice", true) | |
itemsElemsNew.each(function(d, i) { | |
var itemElemNew = d3.select(this) | |
.append("text") | |
.classed("info", true) | |
.style("font-family", fontname) | |
.attr("x", function(d) { | |
return hlocation; }) | |
.attr("y", function(d) { | |
return vlocation | |
}) | |
.style("font-size", function(d, i) { | |
return fontSize | |
}) | |
.text(function(d) { return d }) | |
.style("fill-opacity", 1) | |
}) | |
// items elems update | |
itemsElems | |
.select('text') | |
.text(function(d) { return d }) | |
.attr("x", function(d) { | |
return hlocation; }) | |
.attr("y", function(d) { | |
return vlocation; }) | |
// items elems exit | |
itemsElems.exit() | |
.select('text') | |
.remove() | |
} // render | |
} | |
exports.renderer = renderer; | |
})); | |
/* */ | |
/* d3rings-renderer-lanes.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsRendererLanes = global.d3ringsRendererLanes || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ coordsUtils | |
function coordsUtils () { | |
function index_hcoord_pct(arr, index) { | |
return (index+1) * (100/(arr.length+1)); | |
} | |
function index_hcoord_pct_with_symbol(arr, index) { | |
return index_hcoord_pct(arr, index) + "%"; | |
} | |
function horizontal_center(x1, x2) { | |
if (x1 > x2) return (x2 - x1)/2 + x1 | |
else return (x1 - x2)/2 + x2 | |
} | |
function horizontal_percent_to_coord(svg, percent) { | |
// https://bugzilla.mozilla.org/show_bug.cgi?id=874811 // _e_ | |
if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { | |
var xScrollWidth = svg[0].parentNode.scrollWidth; | |
} else { | |
var xScrollWidth = svg.property("scrollWidth"); | |
} | |
return xScrollWidth * Number.parseFloat(percent)/100; | |
} | |
function horizontal_coord_to_percent(svg, length) { | |
var xScrollWidth = svg.property("scrollWidth"); | |
return Number.parseFloat(length) / xScrollWidth; | |
} | |
var publicAPI = { | |
hcoord_tagged_pct: function hcoord_tagged_pct(arr, val) { | |
return index_hcoord_pct_with_symbol(arr, arr.indexOf(val)); | |
}, | |
hcoord_pct: function hcoord_pct(arr, val) { | |
return index_hcoord_pct(arr, arr.indexOf(val)); | |
}, | |
hcenter_tagged_pct: function hcenter_tagged_pct(x1, x2) { | |
return horizontal_center(x1, x2) + "%"; | |
} | |
} | |
return publicAPI | |
} | |
// _____________ arrayUtils | |
function arrayUtils () { | |
function flattenArrByObjProp(a, p) { | |
return a.reduce(function(prevArr, currVal, i, a) { | |
if (prevArr.indexOf(currVal[p]) < 0) | |
var r = prevArr.push(currVal[p]) | |
return prevArr | |
}, []); | |
} | |
function union_arrays (x, y) { | |
var obj = {}; | |
for (var i = x.length-1; i >= 0; -- i) | |
obj[x[i]] = x[i]; | |
for (var i = y.length-1; i >= 0; -- i) | |
obj[y[i]] = y[i]; | |
var res = [] | |
for (var k in obj) { | |
if (obj.hasOwnProperty(k)) | |
res.push(obj[k]); | |
} | |
return res; | |
} | |
function array_names_from_props (arr, props) { | |
var r = props.reduce( function(prevArr, currVal, i, a) { | |
var q1 = flattenArrByObjProp(arr, currVal) | |
var q = union_arrays(prevArr, q1) | |
return q | |
}, []) | |
return r | |
} | |
var publicAPI = { | |
array_names_from_props: function array_names_from_props (arr, props) { | |
var r = props.reduce( function(prevArr, currVal, i, a) { | |
var q1 = flattenArrByObjProp(arr, currVal) | |
var q = union_arrays(prevArr, q1) | |
return q | |
}, []) | |
return r | |
}, | |
} | |
return publicAPI | |
} | |
// _____________ context | |
var stateLanes = { | |
reducerLanes: {} | |
} | |
var intransition = false | |
// _____________ renderer | |
function renderer(payload) { | |
var store = payload.store | |
var actions = payload.actions | |
var newState = store.getState() | |
// return on transition | |
if (intransition == true) return | |
// return on same data | |
if (JSON.stringify(stateLanes.reducerLanes.records) === JSON.stringify(newState.reducerLanes.records)) { | |
return | |
} | |
// store previous - will not change during renderer | |
var _runners0 = stateLanes.reducerLanes.records || [] | |
var state = stateLanes = newState | |
// hide on wrong views | |
var _opacity = 1 | |
var _currentView = state.reducerCourt.currentView | |
if (_currentView !== 'lanesView') _opacity = 0 | |
var _runners1 = state.reducerLanes.records | |
var _fadeTime = state.reducerConfig.fadeFactor * state.reducerConfig.beatTime | |
var _itemProps = state.reducerConfig.itemProps | |
// SVG | |
var svgContainer = d3.select('body') | |
.selectAll('svg') | |
.data(['lanes_svg'], function(d) { | |
return 'lanes_svg' | |
}) | |
var newSvgContainer = svgContainer | |
.enter() | |
.append("svg") | |
.attr("id", "lanes_svg") | |
var laneGroup = svgContainer | |
.selectAll('g.lane') | |
.data(['lane']) | |
.style('opacity', _opacity) | |
laneGroup.enter() | |
.append("g") | |
.classed("lane", true) | |
var runnersGroup = laneGroup | |
.selectAll('g.runners') | |
.data(['runners']) | |
runnersGroup.enter() | |
.append("g") | |
.classed("runners", true) | |
var lanesGroup = laneGroup | |
.selectAll('g.lanes') | |
.data(['lanes']) | |
lanesGroup.enter() | |
.append("g") | |
.classed("lanes", true) | |
var markerInstance = laneGroup.select(".runner-marker") | |
if (markerInstance.node() == null) { | |
laneGroup | |
.append("marker") | |
.attr("id", "runner-marker") | |
.attr("class", "runner-marker") | |
.attr("viewBox", "0 0 10 10") | |
.attr("refX", "10") | |
.attr("refY", "5") | |
.attr("markerWidth", "5") | |
.attr("markerHeight", "4") | |
.attr("orient", "auto") | |
.append("path") | |
.attr("class", "runner-arrow") | |
.attr("d", "M 0 0 L 10 5 L 0 10 z") | |
} | |
var _laneItems0 = arrayUtils() | |
.array_names_from_props(_runners0, _itemProps) | |
var _laneObjs0 = _laneItems0.map(function(d, i) { | |
return ({id: d, | |
name: d, | |
x0: parseFloat(coordsUtils().hcoord_pct(_laneItems0, d) | |
* parseInt(svgContainer.style("width")) / 100).toFixed(0)})}) | |
var _lanesObj0 = _laneItems0.reduce(function(total,d,currentIndex,arr) { | |
var o = {} | |
o[d] = {name: d, | |
x0: parseFloat(coordsUtils().hcoord_pct(_laneItems0, d) | |
* parseInt(svgContainer.style("width")) / 100).toFixed(0)} | |
return (Object.assign({}, total, o))}, {}) | |
var _laneItems1 = arrayUtils() | |
.array_names_from_props(_runners1, _itemProps) | |
var _laneObjs1 = _laneItems1.map(function(d, i) { | |
var x0 = 0 | |
if ( _lanesObj0.hasOwnProperty( d) ) { | |
x0 = _lanesObj0[d].x0 | |
} | |
return ({id: d, | |
name: d, | |
x0: x0})}) | |
// laneElems trasition | |
var d3ringsTransition = d3.transition() | |
.duration(_fadeTime) | |
.ease(d3.easeLinear) | |
// laneElements DATA | |
var laneElements = svgContainer | |
.select("g.lanes") | |
.selectAll("g.lane") | |
.data(_laneObjs1, function(d) { return d.id }) | |
// laneElements EXIT | |
laneElements.exit() | |
.transition(d3ringsTransition) | |
.style("opacity", function(d) { | |
store.dispatch(actions.deleteLane(d)) | |
return 0 | |
}) | |
.remove(function(){}) | |
// laneElements UPDATE texts | |
var laneTexts = laneElements.select("text") | |
.attr("text-anchor", "middle") | |
.attr("alignment-baseline", "middle") | |
.style("font-size", function(d, i) { | |
return parseInt(svgContainer.style("width")) * 2/100 | |
}) | |
.text(function(d) { return d.name }) | |
.attr("dy", "20") | |
.transition(d3ringsTransition) | |
.attr("x", function(d, i) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.name) | |
return r | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// laneElements UPDATE lines | |
var laneLines = laneElements.select("line") | |
.attr("x0", function(d, i) { | |
var r = parseFloat(coordsUtils().hcoord_pct(_laneItems0, d.name) | |
* parseInt(svgContainer.style("width")) / 100).toFixed(0) | |
return r | |
}) | |
.attr("y1", function() { | |
var text_bbox = this.parentNode.querySelector("text").getBBox(); | |
return text_bbox.y + text_bbox.height; | |
}) | |
.attr("y2", "100%") | |
.transition(d3ringsTransition) | |
.attrTween("x1", function(d, i, a) { | |
return function (t) { | |
var r = parseFloat(coordsUtils().hcoord_pct(_laneItems1, d.name) | |
* parseInt(svgContainer.style("width")) / 100).toFixed(0) | |
var x = parseFloat(parseInt(d.x0) + t * (r - parseInt(d.x0))).toFixed(0) | |
// dispatch lanes abscissa | |
var l = {name: d.name, id: d.id, x: x } | |
store.dispatch(actions.setLane(l)) | |
return x | |
} | |
}) | |
.attr("x2", function(d, i) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.name) | |
return r | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// newLaneElements ENTER | |
var newLaneElements = laneElements | |
.enter() | |
.append("g") | |
.classed("lane", true) | |
// newLaneElements ENTER text | |
newLaneElements.append("text") | |
.attr("class", "lane") | |
.attr("text-anchor", "middle") | |
.attr("alignment-baseline", "middle") | |
.style("font-family", "sans-serif") | |
.style("fill", "transparent") | |
.style("font-size", function(d, i) { | |
return parseInt(svgContainer.style("width")) * 2/100 | |
}) | |
.text(function(d) { return d.name }) | |
.attr("dy", "20") | |
.attr("x", function(d, i, a) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.name) | |
return r | |
}) | |
.transition(d3ringsTransition) | |
.style("fill", "black") | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// newLaneElements ENTER lines | |
newLaneElements.append("line") | |
.attr("class", "lane") | |
.attr("stroke", "lightgray") | |
.style("stroke-width", "1px") | |
.attr("stroke-width", 1) | |
.attr("x0", function(d, i) { | |
var r = parseFloat(coordsUtils().hcoord_pct(_laneItems0, d.name) | |
* parseInt(svgContainer.style("width")) / 100).toFixed(0) | |
return r | |
}) | |
.attr("x1", function(d, i, a) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.name) | |
var x = parseFloat(coordsUtils().hcoord_pct(_laneItems1, d.name) | |
* parseInt(svgContainer.style("width")) / 100).toFixed(0) | |
var l = {name: d.name, id: d.id, x: x } | |
store.dispatch(actions.setLane(l)) | |
return r | |
}) | |
.attr("x2", function(d, i, a) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.name) | |
return r | |
}) | |
.attr("y1", function(_d, i) { | |
var text_bbox = this.parentNode.querySelector("text").getBBox(); | |
return text_bbox.y + text_bbox.height; | |
}) | |
.attr("y2", function(d, i, a) { | |
var r = "100%" | |
return r | |
}) | |
// runnerElements | |
var runnerElements = svgContainer | |
.select("g.runners") | |
.selectAll("g.runner") | |
.data(_runners1, function(d, i) { return d.id || (d.id = ++i); }) | |
// runner elems UPDATE texts | |
runnerElements.select('text') | |
.transition(d3ringsTransition) | |
.attr("x", function(d, i) { | |
var r1 = coordsUtils().hcoord_pct(_laneItems1, d.from) | |
var r2 = coordsUtils().hcoord_pct(_laneItems1, d.to) | |
var r = coordsUtils().hcenter_tagged_pct(r1, r2) | |
return r | |
}) | |
.attr("y", function(d, i, s) { | |
var r = (i + 2) * state.reducerConfig.vstep - 10 | |
return r // (i+1)*10 | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// runnerElems UPDATE lines | |
runnerElements.select('line') | |
.transition(d3ringsTransition) | |
.attr("x1", function(d, i, a) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.from) | |
return r | |
}) | |
.attr("x2", function(d, i, a) { | |
var r = coordsUtils().hcoord_tagged_pct(_laneItems1, d.to) | |
return r | |
}) | |
.attr("y1", function(d, i) { | |
var r = (i + 2) * state.reducerConfig.vstep; | |
return r | |
}) | |
.attr("y2", function(d, i) { | |
var r = (i + 2) * state.reducerConfig.vstep; | |
return r | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// runnerElems UPDATE paths | |
runnerElements.select("path") | |
.transition(d3ringsTransition) | |
.attr("d", function(d, i) { | |
var x_pc = coordsUtils().hcoord_tagged_pct(_laneItems1, d.from) | |
var xScrollWidth = parseInt(svgContainer.style("width")) | |
var t = xScrollWidth * Number.parseFloat(x_pc)/100 | |
var x = t | |
var rx = 40 | |
var ry = 20 | |
var y = (i + 2)*50 - ry | |
var sweep_flag = 1 | |
var r = [ | |
"M", x, y, | |
"a", rx, ry, 0, 1, sweep_flag, 0, ry*2, | |
].join(" "); | |
return r | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// runnerElems ENTER | |
var newMessageElements = runnerElements | |
.enter() | |
.append("g") | |
.classed("runner", true) | |
// runnerElems ENTER TEXTs | |
newMessageElements.each(function(d, i) { | |
var new_runner = d3.select(this) | |
.append("text") | |
.attr("class", "runner") | |
.style("fill", "transparent") | |
.style("font-size", function(d, i) { | |
return parseInt(svgContainer.style("width")) * 2/100 | |
}) | |
.attr("dy", ".15em") | |
.attr("text-anchor", d.from == d.to ? "end" : "middle") | |
.attr("alignment-baseline", d.from == d.to ? "middle" : "autoMode") | |
.text(d.msg) | |
.attr("y", (i + 2) * state.reducerConfig.vstep - 10) | |
.attr("x", function() { | |
var x1 = coordsUtils().hcoord_pct(_laneItems1, d.from) | |
var x2 = coordsUtils().hcoord_pct(_laneItems1, d.to) | |
var r = coordsUtils().hcenter_tagged_pct(x1, x2) | |
return r | |
}) | |
.transition(d3ringsTransition) | |
.style("fill", "grey") | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
}) | |
// runnerElems ENTER PATHs | |
newMessageElements.each(function(d, i) { | |
var new_runner = d3.select(this) | |
if (d.from == d.to) { | |
new_runner.append("path") // new mPATHs | |
.attr("fill-opacity", 0) | |
.attr("stroke", "transparent") | |
.each(function(d) { | |
// this._current = d_to_arc(d, i); // store initial state | |
}) | |
.attr("d", function() { | |
var x_pc_to = coordsUtils().hcoord_pct(_laneItems1, d.to) | |
var xScrollWidth = parseInt(svgContainer.style("width")) | |
var t = xScrollWidth * Number.parseFloat(x_pc_to)/100 | |
var x = t | |
var rx = 40 | |
var ry = 20 | |
var y = (i + 2)*50 - ry | |
var sweep_flag = 1 | |
var r = [ | |
"M", x, y, | |
"a", rx, ry, 0, 1, sweep_flag, 0, ry*2, | |
].join(" "); | |
return r | |
}) | |
.transition(d3ringsTransition) | |
.attr("stroke", "grey") | |
.attr("fill", "grey") | |
.attrTween("marker-end", function(d) { | |
return function (t) { | |
if (t != 1) { | |
return null | |
} else { | |
return "url(#runner-marker)" | |
} | |
} | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
// runnerElems ENTER LINEs | |
} else { | |
var line = new_runner.append("line") | |
.attr("class", "runner") | |
.attr("stroke", "transparent") | |
.attr("stroke-width", 1) | |
.attr("y1", function() { | |
var r = (i + 2) * state.reducerConfig.vstep ; | |
return r | |
}) | |
.attr("y2", function() { | |
var r = (i + 2) * state.reducerConfig.vstep ; | |
return r | |
}) | |
.attr("x1", coordsUtils().hcoord_tagged_pct(_laneItems1, d.from)) | |
.attr("x2", coordsUtils().hcoord_tagged_pct(_laneItems1, d.to)) | |
.transition(d3ringsTransition) | |
.attr("stroke", "gray") | |
.attr("fill", "grey") | |
.attrTween("marker-end", function() { | |
return function (t) { | |
if (t != 1) { | |
return null | |
} else { | |
return "url(#runner-marker)" | |
} | |
} | |
}) | |
.on("start", function start() { | |
intransition = true | |
}) | |
.on("end", function end() { | |
intransition = false | |
}) | |
} | |
}); | |
// runnerElems EXIT | |
runnerElements.exit() | |
.transition() | |
.style("opacity", 0) | |
.remove() | |
} | |
exports.renderer = renderer; | |
})); | |
/* */ | |
/* d3rings-renderer-particles.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsRendererParticles = global.d3ringsRendererParticles || {}))); | |
}(this, function (exports) { 'use strict'; | |
// _____________ context | |
var stateParticles = { | |
reducerParticles: {} | |
} | |
var rendering = false | |
var intransition = false | |
// _______________________ renderer | |
function renderer(payload) { | |
var store = payload.store | |
var actions = payload.actions | |
var newState = store.getState() | |
if (rendering == true) return | |
if (newState.reducerParticles.particles.length == 0) return | |
rendering = true | |
var state = stateParticles= newState | |
var particleRadio = state.reducerParticles.particleRadio || 6.33 | |
var svgContainer = d3.select('body') | |
.selectAll('svg') | |
.data(['svgContainer']) | |
svgContainer | |
.enter() | |
.append("svg") | |
.attr("id", state.reducerConfig.container) | |
svgContainer | |
.style('width', state.reducerCourt.svgWidth) | |
.style('height', state.reducerCourt.svgHeight) | |
var itemsGroup = d3.select('svg') | |
.selectAll('g.particles') // items | |
.data(['items']) | |
itemsGroup.enter() | |
.append("g") | |
.classed("particles", true) // items | |
// _________________________________ render Particles | |
var color = d3.scalePlasma() | |
.domain([0, 1]) | |
var particleElements = svgContainer | |
.select("g.particles") | |
.selectAll("circle") | |
.data(state.reducerParticles.particles) | |
.attr('cx', function(d, i, a) { return d.x }) | |
.attr('cy', function(d, i, a) { return d.y }) | |
.attr('r', function(d, i, a) { return particleRadio }) | |
.style("fill", function (d) { | |
var r = d.closestLaneUp.x / (d.closestLaneUp.x - d.closestLaneDown.x) | |
return color( ((3*r)%10 / 10) + (Math.random()* 3 /10)) | |
}) | |
.style("fill-opacity", 0.2) | |
.style("stroke", "none") | |
var newParticleElements = particleElements | |
.enter() | |
.append("circle") | |
.attr('cx', function(d, i, a) { return d.x }) | |
.attr('cy', function(d, i, a) { return d.y }) | |
.attr('r', function(d, i, a) { return particleRadio }) | |
.style("fill", function (d) { | |
var r = d.closestLaneUp.x / (d.closestLaneUp.x - d.closestLaneDown.x) | |
return color( ((3*r)%10 / 10) + (Math.random()/10)) | |
}) | |
.style("stroke", "none") | |
particleElements.exit() | |
.remove() | |
rendering = false | |
} // renderer | |
exports.renderer = renderer; | |
})); | |
/* */ | |
/* d3rings-renderer-whirls.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
} | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsRendererWhirls = global.d3ringsRendererWhirls || {}))); | |
}(this, function (exports) { 'use strict'; | |
// http://stackoverflow.com/questions/31381129/assign-new-id-attribute-to-each-element-created | |
function guid() { | |
function _p8(s) { | |
var p = (Math.random().toString(16)+"000000000").substr(2,8); | |
return s ? "-" + p.substr(0,4) + "-" + p.substr(4,4) : p ; | |
} | |
return _p8() + _p8(true) + _p8(true) + _p8(); | |
} | |
// Adapted from https://github.com/tj/d3-dot | |
var gen = function(n, l, h, s) { | |
var data = [] | |
for (var i = n; i; i--) { | |
var grid = guid() | |
data.push({ | |
x: Math.random() * l | 0, | |
y: Math.random() * h | 0, | |
id: i, | |
rid: i, | |
grid: grid, | |
s: s | |
}) | |
} | |
return data | |
} | |
// _____________ context | |
var stateWhirls = { | |
reducerWhirls: {} | |
} | |
var intransition = false | |
var intransition_newRang = false | |
var intransition_updRang = false | |
var intransition_newRing = false | |
// _____________ renderer | |
function renderer(payload) { | |
var store = payload.store | |
var actions = payload.actions | |
var newState = store.getState() | |
// return on transition | |
if (intransition == true) return | |
var state = stateWhirls = newState | |
// return if not init - mouse hover | |
var _startRangs = state.reducerWhirls.startRangs | |
// hide on wrong views | |
var _opacity = 1 | |
var _currentView = state.reducerCourt.currentView | |
if (_currentView !== 'ringsView') _opacity = 0 | |
if (_startRangs == false) return | |
var _fadeTime = state.reducerConfig.fadeFactor * state.reducerConfig.beatTime | |
var _itemProps = state.reducerConfig.itemProps | |
var _duration = state.reducerWhirls.duration | |
var _n = state.reducerWhirls.n | |
var _s = state.reducerWhirls.s | |
var _width = state.reducerCourt.svgWidth | |
var _height = state.reducerCourt.svgHeight | |
var _svgid = state.reducerConfig.container | |
var _currentView = state.reducerCourt.currentView | |
// rings | |
var ringsRadio = state.reducerWhirls.ringsRadio || state.reducerConfig.ringDefaultRadio | |
// SVG | |
var svgContainer = d3.select('body') | |
.selectAll('svg') | |
.data(['rangs_svg'], function(d) { | |
return 'rangs_svg' | |
}) | |
var newSvgContainer = svgContainer | |
.enter() | |
.append("svg") | |
.attr("id", 'rangs_svg') | |
svgContainer | |
.style('width', _width) | |
.style('height', _height) | |
d3.select('svg') | |
.selectAll('g.rangs') // items | |
.data(['items']) | |
.style('opacity', _opacity) | |
.enter() | |
.append("g") | |
.classed("rangs", true) // items | |
// rings | |
d3.select('svg') | |
.selectAll('g.rings') // items | |
.data(['items']) | |
.enter() | |
.append("g") | |
.classed("rings", true) // items | |
// http://bl.ocks.org/brattonc/b1abb535227b2f722b51. | |
var dummyText = svgContainer.select(".dummyText") | |
if (dummyText.node() == null) { | |
dummyText = svgContainer | |
.append("text") | |
.attr("id", "dummyText") | |
.attr("class", "dummyText") | |
.text("N") | |
} | |
var textHeight = dummyText.node().getBBox().height | |
// elems trasition | |
var elemsTransition = d3.transition() | |
.duration(_duration) | |
.ease(d3.easeLinear) | |
var rangsTransition = d3.transition() | |
.duration(_duration) | |
.ease(d3.easeLinear) | |
var elemsTransition = d3.transition() | |
.duration(_duration) | |
.ease(d3.easeLinear) | |
var colorScale = d3.scaleCubehelix() | |
.domain([0, 1]) | |
// _________________________________ render rangs | |
var rangGroups = svgContainer.select("g.rangs") // data rang | |
.selectAll("g.rang") | |
.data(gen(_n, _width, _height, _s), | |
function(d) { return d.rid }) | |
var newRangGroups = rangGroups // enter rang | |
.enter() | |
.append("g") | |
.attr("class", "rang") | |
// .attr("id", function (d) { return d.id; }) | |
.attr("rid", function (d) { return d.rid; }) | |
var rectOnNewRang = newRangGroups.append('rect') // append rect | |
.attr("rid", function (d) {return d.rid }) | |
.attr("grid", function (d) {return d.grid }) | |
.attr("class", "rect") | |
.attr("x", function (d) { return d.x; }) | |
.attr("y", function (d) { return d.y; }) | |
.attr("s", function (d) { return d.s; }) | |
.attr("t", function (d) { return d.t; }) | |
.attr("stroke-width", 1) | |
.attr("stroke", "grey") | |
.style("fill", "transparent") | |
if (intransition_updRang == false) { | |
var rectOnExistingRang = rangGroups.select("rect") // update rect | |
.attr("rid", function (d) { return d.rid }) | |
.attr("x", function (d) { return d.x }) | |
.attr("y", function (d) { return d.y }) | |
.attr("s", function (d) { return d.s }) | |
.transition('updRang') | |
.duration(_duration) | |
.ease(d3.easeLinear) | |
.attrTween("height", function(d) { | |
return function (t) { | |
var r = parseInt((1 - t) * d.s) | |
return r | |
} | |
}) | |
.attrTween("width", function(d) { | |
return function (t) { | |
var r = parseInt((1 - t) * d.s) | |
return r | |
} | |
}) | |
.attrTween("s", function(d) { | |
return function (t) { | |
var r = parseInt((1 - t) * d.s) | |
var item = { | |
id: d.id, | |
rid: d.rid, | |
grid: d.grid, | |
x: d.x, | |
y: d.y, | |
t: t, | |
s: parseInt((1 - t) * d.s), | |
} | |
store.dispatch(actions.setRang(item)) | |
return r | |
} | |
}) | |
.on("start", function start() { | |
intransition_updRang = true | |
}) | |
.on("end", function end(d) { | |
store.dispatch(actions.deleteRang(d)) | |
intransition_updRang = false | |
}) | |
rangGroups.exit() // delete rang | |
.remove(function(){ | |
store.dispatch(actions.deleteRang(d)) | |
}) | |
} | |
// _________________________________ render rings | |
var ringElements = svgContainer | |
.select("g.rings") | |
.selectAll("circle") | |
.data(state.reducerWhirls.rings, function (d) { return d.id}) | |
var updateItems = ringElements | |
.attr('r', function(d, i, a) { return d.r }) | |
.attr('cx', function(d, i, a) { return d.cx }) | |
.attr('cy', function(d, i, a) { return d.cy }) | |
.style("fill", function (d) { return colorScale( Math.random() / 2)}) | |
.style("fill-opacity", 0.7) | |
.style("stroke", "none") | |
var newRingElements = ringElements | |
.enter() | |
.append("circle") | |
.attr('class', 'ring') | |
.attr('id', function(d, i, a) { return d.id }) | |
newRingElements | |
.transition('newRing') | |
.duration(_duration) | |
.ease(d3.easeLinear) | |
.attrTween('t', function(d, i, a) { | |
return function (t) { | |
store.dispatch(actions.tickRing(Object.assign({}, d, {t: t}))) | |
return t | |
} | |
}) | |
var exitRingElements = ringElements.exit() | |
.remove(function(){ | |
store.dispatch(actions.deleteRing(d)) | |
}) | |
} // end render | |
exports.renderer = renderer; | |
})); | |
/* */ | |
/* d3rings-store.js */ | |
/* */ | |
/* adapted from REDUX http://redux.js.org/ */ | |
(function (global, factory) { | |
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | |
typeof define === 'function' && define.amd ? define(['exports'], factory) : | |
(factory((global.d3ringsStore = global.d3ringsStore || {}))); | |
}(this, function (exports) { 'use strict'; | |
var createStore = function createStore(reducer, initialState) { | |
var currentReducer = reducer | |
var currentState = initialState | |
var currentListeners = [] | |
var nextListeners = currentListeners | |
var isDispatching = false | |
// ______________________________ ensureCanMutateNextListeners | |
function ensureCanMutateNextListeners() { | |
if (nextListeners === currentListeners) { | |
nextListeners = currentListeners.slice() | |
} | |
} | |
// ______________________________ getState | |
function getState() { | |
return currentState | |
} | |
// ______________________________ redux compose | |
function compose(...funcs) { | |
if (funcs.length === 0) { | |
return arg => arg | |
} else { | |
const last = funcs[funcs.length - 1] | |
const rest = funcs.slice(0, -1) | |
return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args)) | |
} | |
} | |
// ______________________________ subscribe | |
function subscribe(listener) { | |
if (typeof listener !== 'function') { | |
throw new Error('Expected listener to be a function.') | |
} | |
var isSubscribed = true | |
ensureCanMutateNextListeners() | |
nextListeners.push(listener) | |
return function unsubscribe() { | |
if (!isSubscribed) { | |
return | |
} | |
isSubscribed = false | |
ensureCanMutateNextListeners() | |
var index = nextListeners.indexOf(listener) | |
nextListeners.splice(index, 1) | |
} | |
} | |
// ______________________________ dispatch | |
function dispatch(action) { | |
if (typeof action.type === 'undefined') { | |
throw new Error( | |
'Actions may not have an undefined "type" property. ' + | |
'Have you misspelled a constant?' | |
) | |
} | |
if (isDispatching) { | |
throw new Error('Reducers may not dispatch actions.') | |
} | |
try { | |
isDispatching = true | |
currentState = currentReducer(currentState, action) | |
} finally { | |
isDispatching = false | |
} | |
var listeners = currentListeners = nextListeners | |
for (var i = 0; i < listeners.length; i++) { | |
listeners[i]() | |
} | |
return action | |
} | |
// ______________________________ return | |
return { | |
compose: compose, | |
dispatch: dispatch, | |
subscribe: subscribe, | |
getState: getState, | |
} | |
} | |
exports.createStore = createStore; | |
})); | |
/* */ | |
/* index.js */ | |
/* */ | |
if (typeof require === "function") { | |
var d3 = require('./d3.v4.0.0-alpha.44.js') | |
var d3ringsRendererCourt = require('./d3rings-renderer-court.js') | |
var d3ringsRendererLanes = require('./d3rings-renderer-lanes.js') | |
var d3ringsRendererParticles = require('./d3rings-renderer-particles.js') | |
var d3ringsRendererWhirls = require('./d3rings-renderer-whirls.js') | |
var d3ringsReducer = require('./d3rings-reducer.js') | |
var d3ringsStore = require('./d3rings-store.js') | |
var d3ringsActions = require('./d3rings-actions.js') | |
var d3ringsControls = require('./d3rings-controls.js') | |
} | |
/* actions */ | |
var actions = d3ringsActions.ActionCreators | |
/* store */ | |
var store = d3ringsStore.createStore(d3ringsReducer.reducer, d3ringsReducer.reducer()) | |
/* container */ | |
var svgContainer = d3.select(store.getState().reducerConfig.containerElem) | |
.selectAll('svg') | |
.data(['svg']) | |
.enter() | |
.append("svg") | |
.attr("id", store.getState().reducerConfig.containerId) | |
.attr('class', 'chart') | |
.style('width', store.getState().reducerCourt.svgWidth) | |
.style('height', store.getState().reducerCourt.svgHeight) | |
.style('background', 'oldlace') | |
.style('border', '1px solid darkgrey') | |
.attr('viewbox',"0 0 3 2") | |
/* payloads renderers */ | |
var logicAndData_Payload = function () { return { | |
store: store, | |
actions: actions | |
}} | |
var container_Payload = function () { return | |
d3.select('svg') | |
} | |
/* payloads lanes */ | |
var keyDownKeysLanes_Payload = function () { return { | |
keyEvents: store.getState().reducerCourt.keyEvents, | |
currentMode: store.getState().reducerCourt.currentMode, | |
itemSpan: store.getState().reducerConfig.itemSpan, | |
}} | |
var keyUpKeysLanes_Payload = function () { return { | |
keys: store.getState().reducerCourt.keys, | |
currentMode: store.getState().reducerCourt.currentMode, | |
itemSpan: store.getState().reducerConfig.itemSpan, | |
}} | |
var setRecords_Payload = function () { return { | |
itemSpan: store.getState().reducerConfig.itemSpan, | |
currentMode: store.getState().reducerCourt.currentMode | |
}} | |
var setRecordsCollection_Payload = function () { return { | |
recordsCollection: store.getState().reducerConfig.recordsCollection | |
}} | |
/* payloads particles */ | |
var createParticles_Payload = function () { return { | |
particlesPerTick: store.getState().reducerParticles.particlesPerTick, | |
x: store.getState().reducerCourt.mousePos[0], | |
y: store.getState().reducerCourt.mousePos[1], | |
xInit: store.getState().reducerCourt.leftBorder, | |
xEnd: store.getState().reducerCourt.svgWidth, | |
randNormal: store.getState().reducerConfig.randNormal, | |
randNormal2: store.getState().reducerConfig.randNormal2, | |
lanes: store.getState().reducerLanes.lanes, | |
particlesGenerating: store.getState().reducerParticles.particlesGenerating, | |
currentView: store.getState().reducerCourt.currentView, | |
}} | |
var introduceParticles_Payload = function () { return { | |
particlesPerTick: store.getState().reducerParticles.particlesPerTick, | |
x: store.getState().reducerCourt.mousePos[0], | |
y: store.getState().reducerCourt.mousePos[1], | |
xInit: store.getState().reducerCourt.leftBorder, | |
xEnd: store.getState().reducerCourt.svgWidth, | |
randNormal: store.getState().reducerConfig.randNormal, | |
randNormal2: store.getState().reducerConfig.randNormal2, | |
lanes: store.getState().reducerLanes.lanes, | |
particlesGenerating: store.getState().reducerParticles.particlesGenerating, | |
currentView: store.getState().reducerCourt.currentView, | |
}} | |
var tickParticles_Payload = function () { return { | |
width: store.getState().reducerCourt.svgWidth, | |
height: store.getState().reducerCourt.svgHeight, | |
gravity: store.getState().reducerConfig.gravity, | |
lanes: store.getState().reducerLanes.lanes | |
}} | |
/* payloads whirls */ | |
var createRings_Payload = function () { return { | |
ringsPerTick: store.getState().reducerWhirls.ringsPerTick, | |
x: store.getState().reducerCourt.mousePos[0], | |
y: store.getState().reducerCourt.mousePos[1], | |
randNormal: store.getState().reducerConfig.randNormal, | |
randNormal2: store.getState().reducerConfig.randNormal2, | |
rings: store.getState().reducerWhirls.rings, | |
rangs: store.getState().reducerWhirls.rangs, | |
ringsGenerating: store.getState().reducerWhirls.ringsGenerating, | |
}} | |
var updateRangsDuration_Payload = function () { return { | |
rangsAlways: store.getState().reducerWhirls.rangsAlways, | |
rangsHitsIndex: store.getState().reducerWhirls.rangsHitsIndex, | |
}} | |
var updateRangsNumber_Payload = function () { return { | |
rangsAlways: store.getState().reducerWhirls.rangsAlways, | |
rangsHitsIndex: store.getState().reducerWhirls.rangsHitsIndex, | |
}} | |
/* payloads court */ | |
var keyDown_Payload = function (e) { | |
return e | |
} | |
var mouseMove_Payload = function (svg) { | |
return (svg) | |
} | |
var keyDownKeys_Payload = function () { return { | |
keys: store.getState().reducerCourt.keys, | |
views: store.getState().reducerConfig.views, | |
currentView: store.getState().reducerCourt.currentView, | |
}} | |
/* launchers particles*/ | |
var createParticles_particles_Listener = store.compose( | |
store.dispatch, | |
actions.createParticles, | |
createParticles_Payload | |
) | |
var introduceParticles_particles_Listener = store.compose( | |
store.dispatch, | |
actions.introduceParticles, | |
introduceParticles_Payload | |
) | |
var tickParticles_particles_Listener = store.compose( | |
store.dispatch, | |
actions.tickParticles, | |
tickParticles_Payload | |
) | |
var startParticles_particles_Listener = store.compose( | |
store.dispatch, | |
actions.startParticles | |
) | |
var stopParticles_particles_Listener = store.compose( | |
store.dispatch, | |
actions.stopParticles | |
) | |
/* launchers lanes */ | |
var keyDownArrow_lanes_Listener = store.compose( | |
store.dispatch, | |
actions.walkDownRecords, | |
keyDownKeysLanes_Payload | |
) | |
var keyUpArrow_lanes_Listener = store.compose( | |
store.dispatch, | |
actions.walkUpRecords, | |
keyUpKeysLanes_Payload | |
) | |
var setRecordsCollection_lanes_Listener = store.compose( | |
store.dispatch, | |
actions.setRecordsCollection, | |
setRecordsCollection_Payload | |
) | |
var setRecords_lanes_Listener = store.compose( | |
store.dispatch, | |
actions.setRecords, | |
setRecords_Payload | |
) | |
/* launchers rings */ | |
var startRangs_rangs_Listener = store.compose( | |
store.dispatch, | |
actions.startRangs | |
) | |
var stopRangs_rings_Listener = store.compose( | |
store.dispatch, | |
actions.stopRangs | |
) | |
var updateRangsDuration_rings_Listener = store.compose( | |
store.dispatch, | |
actions.updateRangsDuration, | |
updateRangsDuration_Payload | |
) | |
var updateRangsNumber_rings_Listener = store.compose( | |
store.dispatch, | |
actions.updateRangsNumber, | |
updateRangsNumber_Payload | |
) | |
var createRings_rings_Listener = store.compose( | |
store.dispatch, | |
actions.createRings, | |
createRings_Payload | |
) | |
var startRings_rings_Listener = store.compose( | |
store.dispatch, | |
actions.startRings | |
) | |
var stopRings_rings_Listener = store.compose( | |
store.dispatch, | |
actions.stopRings | |
) | |
/* launchers debug */ | |
var setFps_debug_Listener = store.compose( | |
store.dispatch, | |
actions.setFps | |
) | |
/* launchers court */ | |
var processKeybKeys_court_Listener = store.compose( | |
store.dispatch, | |
actions.processKeybKeys, | |
keyDown_Payload | |
) | |
var keyDown_court_Listener = store.compose( | |
store.dispatch, | |
actions.setKeybKey, | |
keyDown_Payload | |
) | |
var releaseKeybKey_court_Listener = store.compose( | |
store.dispatch, | |
actions.releaseKeybKey | |
) | |
var updateMousePos_court_Listener = store.compose( | |
store.dispatch, | |
actions.updateMousePos, | |
mouseMove_Payload | |
) | |
var keyDownAltV_court_Listener = store.compose( | |
store.dispatch, | |
actions.setView, | |
keyDownKeys_Payload | |
) | |
var keyDownAltD_court_Listener = store.compose( | |
store.dispatch, | |
actions.switchDebugMode, | |
keyDownKeys_Payload | |
) | |
var keyLeftArrow_court_Listener = store.compose( | |
store.dispatch, | |
actions.setMode, | |
keyDownKeys_Payload | |
) | |
var keyRightArrow_court_Listener = store.compose( | |
store.dispatch, | |
actions.setMode, | |
keyDownKeys_Payload | |
) | |
var keyUpArrow_court_Listener = store.compose( | |
store.dispatch, | |
actions.setMode, | |
keyDownKeys_Payload | |
) | |
var keyDownArrow_court_Listener = store.compose( | |
store.dispatch, | |
actions.setMode, | |
keyDownKeys_Payload | |
) | |
var keyLeftArrowCtr_court_Listener = store.compose( | |
store.dispatch, | |
actions.resizeWidth, | |
keyDownKeys_Payload | |
) | |
var keyRightArrowCtrl_court_Listener = store.compose( | |
store.dispatch, | |
actions.resizeHeight, | |
keyDownKeys_Payload | |
) | |
var keyUpArrowCtrl_court_Listener = store.compose( | |
store.dispatch, | |
actions.resizeWidth, | |
keyDownKeys_Payload | |
) | |
var keyDownArrowCtrl_court_Listener = store.compose( | |
store.dispatch, | |
actions.resizeHeight, | |
keyDownKeys_Payload | |
) | |
var renderer_court_Listener = store.compose( | |
d3ringsRendererCourt.renderer, | |
logicAndData_Payload | |
) | |
var renderer_lanes_Listener = store.compose( | |
d3ringsRendererLanes.renderer, | |
logicAndData_Payload | |
) | |
var renderer_particles_Listener = store.compose( | |
d3ringsRendererParticles.renderer, | |
logicAndData_Payload | |
) | |
var renderer_whirls_Listener = store.compose( | |
d3ringsRendererWhirls.renderer, | |
logicAndData_Payload | |
) | |
/* launchers */ | |
var mouseDown_Launcher = d3ringsControls.mouseDownControl(logicAndData_Payload()).start(d3.select('svg')) | |
var touchStart_Launcher = d3ringsControls.touchStartControl(logicAndData_Payload()).start(d3.select('svg')) | |
var mouseMove_Launcher = d3ringsControls.mouseMoveControl(logicAndData_Payload()).start(d3.select('svg')) | |
var touchMove_Launcher = d3ringsControls.touchMoveControl(logicAndData_Payload()).start(d3.select('svg')) | |
var mouseUp_Launcher = d3ringsControls.mouseUpControl(logicAndData_Payload()).start(d3.select('svg')) | |
var touchEnd_Launcher = d3ringsControls.touchEndControl(logicAndData_Payload()).start(d3.select('svg')) | |
var mouseLeave_Launcher = d3ringsControls.mouseLeaveControl(logicAndData_Payload()).start(d3.select('svg')) | |
var mouseEnter_Launcher = d3ringsControls.mouseEnterControl(logicAndData_Payload()).start(d3.select('svg')) | |
var ticker_Launcher = d3ringsControls.tickControls(logicAndData_Payload()).start() | |
var d3timer_Launcher = d3ringsControls.timeControls(logicAndData_Payload()).start() | |
var stepper_Launcher = d3ringsControls.stepControls(logicAndData_Payload()).start() | |
var keyDown_Launcher = d3ringsControls.keyDownControl(logicAndData_Payload()).start() | |
var keyRelease_Launcher = d3ringsControls.keyReleaseControl(logicAndData_Payload()).start() | |
var keyRelease_Launcher = d3ringsControls.keyReleaseControl(logicAndData_Payload()).start() | |
/* listeners */ | |
store.subscribe(renderer_court_Listener) | |
keyRelease_Launcher.subscribe(releaseKeybKey_court_Listener) | |
keyDown_Launcher.subscribe(keyDown_court_Listener) | |
keyDown_Launcher.subscribe(keyDownAltV_court_Listener) | |
keyDown_Launcher.subscribe(keyDownAltD_court_Listener) | |
keyDown_Launcher.subscribe(keyLeftArrow_court_Listener) | |
keyDown_Launcher.subscribe(keyRightArrow_court_Listener) | |
keyDown_Launcher.subscribe(keyUpArrow_court_Listener) | |
keyDown_Launcher.subscribe(keyDownArrow_court_Listener) | |
keyDown_Launcher.subscribe(keyLeftArrowCtr_court_Listener) | |
keyDown_Launcher.subscribe(keyRightArrowCtrl_court_Listener) | |
keyDown_Launcher.subscribe(keyUpArrowCtrl_court_Listener) | |
keyDown_Launcher.subscribe(keyDownArrowCtrl_court_Listener) | |
mouseMove_Launcher.subscribe(updateMousePos_court_Listener) | |
mouseDown_Launcher.subscribe(updateMousePos_court_Listener) | |
mouseUp_Launcher.subscribe(updateMousePos_court_Listener) | |
mouseLeave_Launcher.subscribe(updateMousePos_court_Listener) | |
mouseEnter_Launcher.subscribe(updateMousePos_court_Listener) | |
touchStart_Launcher.subscribe(updateMousePos_court_Listener) | |
touchMove_Launcher.subscribe(updateMousePos_court_Listener) | |
touchEnd_Launcher.subscribe(updateMousePos_court_Listener) | |
ticker_Launcher.subscribe(processKeybKeys_court_Listener) | |
d3timer_Launcher.subscribe(setFps_debug_Listener) | |
store.subscribe(renderer_lanes_Listener) | |
stepper_Launcher.subscribe(setRecordsCollection_lanes_Listener) | |
stepper_Launcher.subscribe(setRecords_lanes_Listener) | |
stepper_Launcher.subscribe(keyUpArrow_lanes_Listener) | |
stepper_Launcher.subscribe(keyDownArrow_lanes_Listener) | |
store.subscribe(renderer_particles_Listener) | |
mouseDown_Launcher.subscribe(startParticles_particles_Listener) | |
touchStart_Launcher.subscribe(startParticles_particles_Listener) | |
mouseDown_Launcher.subscribe(createParticles_particles_Listener) | |
touchStart_Launcher.subscribe(createParticles_particles_Listener) | |
mouseMove_Launcher.subscribe(createParticles_particles_Listener) | |
touchMove_Launcher.subscribe(createParticles_particles_Listener) | |
mouseUp_Launcher.subscribe(stopParticles_particles_Listener) | |
touchEnd_Launcher.subscribe(stopParticles_particles_Listener) | |
mouseLeave_Launcher.subscribe(stopParticles_particles_Listener) | |
ticker_Launcher.subscribe(tickParticles_particles_Listener) | |
ticker_Launcher.subscribe(createParticles_particles_Listener) | |
stepper_Launcher.subscribe(introduceParticles_particles_Listener) | |
store.subscribe(renderer_whirls_Listener) | |
mouseDown_Launcher.subscribe(startRangs_rangs_Listener) | |
mouseEnter_Launcher.subscribe(startRangs_rangs_Listener) | |
mouseLeave_Launcher.subscribe(stopRangs_rings_Listener) | |
mouseDown_Launcher.subscribe(startRings_rings_Listener) | |
mouseDown_Launcher.subscribe(createRings_rings_Listener) | |
mouseMove_Launcher.subscribe(createRings_rings_Listener) | |
mouseUp_Launcher.subscribe(stopRings_rings_Listener) | |
mouseLeave_Launcher.subscribe(stopRings_rings_Listener) | |
stepper_Launcher.subscribe(updateRangsDuration_rings_Listener) | |
stepper_Launcher.subscribe(updateRangsNumber_rings_Listener) | |
</script> | |
</body> | |
</html> |
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
<img width="299" alt="preview" src="https://cloud.githubusercontent.com/assets/1050922/15994570/d2448006-3108-11e6-95bc-04cff2e87857.png"> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment