// https://d3js.org/d3-chord/ Version 0.0.2. Copyright 2016 Mike Bostock. (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-path')) : typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-path'], factory) : (factory((global.d3 = global.d3 || {}),global.d3,global.d3)); }(this, function (exports,d3Array,d3Path) { 'use strict'; var cos = Math.cos; var sin = Math.sin; var pi = Math.PI; var halfPi = pi / 2; var tau = pi * 2; var max = Math.max; function compareValue(compare) { return function(a, b) { return compare( a.source.value + a.target.value, b.source.value + b.target.value ); }; } function chord() { var padAngle = 0, sortGroups = null, sortSubgroups = null, sortChords = null; function chord(matrix, e_series, subjectByName, subjectByIndex) { if (e_series === undefined) { console.log("^^^^^^^^^^^^^^^^^^^^^^^^^ matrix mode") var n = matrix.length, groupSums = [], groupIndex = d3Array.range(n), subgroupIndex = [], chords = [], groups = chords.groups = new Array(n), subgroups = new Array(n * n), k, x, x0, dx, i, j; // Compute the sum. k = 0, i = -1; while (++i < n) { x = 0, j = -1; while (++j < n) { x += matrix[i][j]; } groupSums.push(x); subgroupIndex.push(d3Array.range(n)); k += x; } // Sort groups… if (sortGroups) groupIndex.sort(function(a, b) { return sortGroups(groupSums[a], groupSums[b]); }); // Sort subgroups… if (sortSubgroups) subgroupIndex.forEach(function(d, i) { d.sort(function(a, b) { return sortSubgroups(matrix[i][a], matrix[i][b]); }); }); // Convert the sum to scaling factor for [0, 2pi]. // TODO Allow start and end angle to be specified? // TODO Allow padding to be specified as percentage? k = max(0, tau - padAngle * n) / k; dx = k ? padAngle : tau / n; // Compute the start and end angle for each group and subgroup. // Note: Opera has a bug reordering object literal properties! x = 0, i = -1; while (++i < n) { x0 = x, j = -1; while (++j < n) { var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; subgroups[dj * n + di] = { index: di, subindex: dj, startAngle: a0, endAngle: a1, value: v }; } groups[di] = { index: di, startAngle: x0, endAngle: x, value: groupSums[di] }; x += dx; } // Generate chords for each (non-empty) subgroup-subgroup link. i = -1; while (++i < n) { j = i - 1; while (++j < n) { var source = subgroups[j * n + i], target = subgroups[i * n + j]; if (source.value || target.value) { chords.push(source.value < target.value ? {source: target, target: source} : {source: source, target: target}); } } } return sortChords ? chords.sort(sortChords) : chords } else // ========================================================================================== { var e_m = e_series.length, e_n = subjectByName.keys().length, // number of groups e_groupSums = {}, e_groupIndex = [], e_subgroupIndex = [], e_chords = [], e_groups = [], e_subgroups = [], e_k, e_x, e_x0, e_dx, e_g, e_s e_k = 0, e_s = -1; while (++e_s < e_m) { // actions e_k += e_series[e_s].weigh // source slots e_k += 1 // target slots } e_k = max(0, tau - padAngle * e_n) / e_k; // radians per slot e_dx = e_k ? padAngle : tau / e_n; // radians per pad var e_subgroups = [] e_x0 = e_x = 0, e_g = -1; while (++e_g < e_n) { // for each group e_g var subject = subjectByIndex[e_g] e_subgroups[e_g] = [] e_x0 = e_x, e_s = -1; while (++e_s < e_m) { // for each action e_s var action = e_series[e_s] // set action if (subject.name === action.source.name // 1 0 && subject.name !== action.target.name ) { // if group is subject of action var v = action.weigh // slots of action per source var a0 = e_x // start action where we finished e_x = e_x + v * e_k // end action per slots var a1 = e_x // end action per slots var sg = Object.assign({}, action, { // base subgroup on action index: action.source.index, // set source group index subindex: action.target.index, // set target group index startAngleSource: a0, endAngleSource: a1, value: v, // set action value - weigh }) e_subgroups[e_g].push(sg) // add subgroup to group array } else if (subject.name === action.source.name // 1 1 && subject.name === action.target.name ) { // if group is subject of action var a0, a1, b0, b1 var v = action.weigh // slots of action per source var v1 = 1 a0 = e_x // start action where we finished a1 = e_x += v * e_k // end action per slots b0 = a1 // start action where we finished b1 = e_x += v1 * e_k // end action per slots var sg = Object.assign({}, action, { // base subgroup on action index: action.source.index, // set source group index subindex: action.target.index, // set target group index startAngleSource: a0, endAngleSource: a1, startAngleTarget: b0, endAngleTarget: b1, value: v, // set action value - weigh }) e_subgroups[e_g].push(sg) // add subgroup to group array } else if (subject.name !== action.source.name // 0 1 && subject.name === action.target.name ) { // if group is subject of action var a0, a1, b0, b1 var v = 0 // slots of action per source var v1 = 1 // slots of action per target a0 = e_x // start action where we finished a1 = e_x += v * e_k // end action per slots b0 = a1 // start action where we finished b1 = e_x += v1 * e_k // end action per slots var sg = Object.assign({}, action, { // base subgroup on action index: action.source.index, // set source group index subindex: action.target.index, // set target group index startAngleTarget: b0, endAngleTarget: b1, // value: v, // set action value - weigh }) e_subgroups[e_g].push(sg) // add subgroup to group array } } e_groups[e_g] = { index: e_g, startAngle: e_x0, endAngle: e_x, value: e_groupSums[e_g], subgroups: e_subgroups[e_g], } e_x += e_dx // increment angle with pad } e_s = -1; while (++e_s < e_m) { // for each actions e_s var actionThis = e_series[e_s] // action var actionSourceGroup = e_groups[e_series[e_s].source.index] // source group var actionTargetGroup = e_groups[e_series[e_s].target.index] // target group var actionSubgroupsSource = e_groups[e_series[e_s].source.index].subgroups // source subgroups var indexSource = actionSubgroupsSource.filter(function(d) { // source subgroup return d.prx == actionThis.prx })[0] var actionSubgroupsTarget = e_groups[e_series[e_s].target.index].subgroups // target subgroups var indexTarget = actionSubgroupsTarget.filter(function(d) { // target subgroup return d.prx == actionThis.prx })[0] e_chords.push( { prx: actionThis.prx, predicate: actionThis.predicate, weigh: actionThis.weigh, source: { index: actionThis.source.index, subindex: indexSource.source.index, startAngle: indexSource.startAngleSource, endAngle: indexSource.endAngleSource, value: actionThis, }, target: { index: actionThis.target.index, subindex: indexSource.target.index, startAngle: indexTarget.startAngleTarget, endAngle: indexTarget.endAngleTarget, value: actionThis, } } ) } e_chords.groups = e_groups return sortChords ? e_chords.sort(sortChords) : e_chords; } } chord.padAngle = function(_) { return arguments.length ? (padAngle = max(0, _), chord) : padAngle; }; chord.sortGroups = function(_) { return arguments.length ? (sortGroups = _, chord) : sortGroups; }; chord.sortSubgroups = function(_) { return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups; }; chord.sortChords = function(_) { return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._; }; return chord; } var slice = Array.prototype.slice; function constant(x) { return function() { return x; }; } function defaultSource(d) { return d.source; } function defaultTarget(d) { return d.target; } function defaultRadius(d) { return d.radius; } function defaultStartAngle(d) { return d.startAngle; } function defaultEndAngle(d) { return d.endAngle; } function ribbon() { var source = defaultSource, target = defaultTarget, radius = defaultRadius, startAngle = defaultStartAngle, endAngle = defaultEndAngle, context = null; function ribbon() { var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv), sr = +radius.apply(this, (argv[0] = s, argv)), sa0 = startAngle.apply(this, argv) - halfPi, sa1 = endAngle.apply(this, argv) - halfPi, sx0 = sr * cos(sa0), sy0 = sr * sin(sa0), tr = +radius.apply(this, (argv[0] = t, argv)), ta0 = startAngle.apply(this, argv) - halfPi, ta1 = endAngle.apply(this, argv) - halfPi; if (!context) context = buffer = d3Path.path(); context.moveTo(sx0, sy0); context.arc(0, 0, sr, sa0, sa1); if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr? context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0)); context.arc(0, 0, tr, ta0, ta1); } context.quadraticCurveTo(0, 0, sx0, sy0); context.closePath(); if (buffer) return context = null, buffer + "" || null; } ribbon.radius = function(_) { return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), ribbon) : radius; }; ribbon.startAngle = function(_) { return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), ribbon) : startAngle; }; ribbon.endAngle = function(_) { return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), ribbon) : endAngle; }; ribbon.source = function(_) { return arguments.length ? (source = _, ribbon) : source; }; ribbon.target = function(_) { return arguments.length ? (target = _, ribbon) : target; }; ribbon.context = function(_) { return arguments.length ? ((context = _ == null ? null : _), ribbon) : context; }; return ribbon; } exports.chord = chord; exports.ribbon = ribbon; Object.defineProperty(exports, '__esModule', { value: true }); })); /* */ /* d3rings-controls.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 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-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-reducer-court.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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(); } // _____________ COURT var initialStateCourt = { leftBorder: 0, // svgHeight: 400, // svgWidth: 600, // keys: [], keysEvents: {}, notice: 'auto lanes', currentMode: 'autoMode', currentView: 'chordsView', 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-renderer-court.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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' + ')' } if (currentView == 'chordsView') { noticeToShow = noticeToShow + currentView + " " + labelMode+ " - the key is in the arrow key" } 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-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-reducer-debug.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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'; // _____________ 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-actions-lanes.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-reducer-lanes.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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'; // _____________ 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-renderer-lanes.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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-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-reducer-particles.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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'; // _____________ 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-renderer-particles.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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-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-reducer-whirls.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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(); } function inSquare (cx, cy, xl, yl, xh, yh) { if (cx > xl && cx < xh && cy > yl && cy < yh) return true else return false } // _____________ 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 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-renderer-whirls.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 // 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.interpolateCubehelixLong(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-actions-chords.js */ /* */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3ringsActionsChords = global.d3ringsActionsChords || {}))); }(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 actionConstants = { FETCH_CHORDS_COLLECTION: '', SET_CHORDS_COLLECTION: '', SET_CHORDS: '', WALK_DOWN_CHORDS: '', WALK_UP_CHORDS: '', } var ActionTypes = keyMirror(actionConstants, '') // ____________________ actions var ActionCreators = { fetchChordsCollection(payload) { // FETCH_CHORDS_COLLECTION return { type: ActionTypes.FETCH_CHORDS_COLLECTION, payload: payload, } }, setChordsCollection(payload) { // SET_CHORDS_COLLECTION return { type: ActionTypes.SET_CHORDS_COLLECTION, payload: payload, } }, setChords(payload) { // SET_CHORDS return { type: ActionTypes.SET_CHORDS, payload: payload, } }, walkDownChords(payload) { // WALK_DOWN_CHORDS return { type: ActionTypes.WALK_DOWN_CHORDS, payload: payload, } }, walkUpChords(payload) { // WALK_UP_CHORDS return { type: ActionTypes.WALK_UP_CHORDS, payload: payload, } }, } exports.ActionTypes = ActionTypes exports.ActionCreators = ActionCreators })); /* */ /* d3rings-reducer-chords.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.js') var d3ringsActions = require('./d3rings-actions-chords.js') } (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3ringsReducerChords = global.d3ringsReducerChords || {}))); }(this, function (exports) { 'use strict'; var actionsSeriesCreate = function actionsSeriesCreate (dataParam) { var cbn = [] var ci = -1 var d3map = d3.map() dataParam.forEach(function(d) { var cr = {} if (d3map.has(d.source)) { cr.source = d3map.get(d.source) } else { ++ci cr.source = {name: d.source, index: ci} d3map.set(d.source, cr.source) } if (d3map.has(d.target)) { cr.target = d3map.get(d.target) } else { ++ci cr.target = {name: d.target, index: ci} d3map.set(d.target, cr.target) } cr.prx = d.prx cr.predicate = d.predicate cr.weigh = d.weigh cr.valueOf = d.valueOf cbn.push(cr) }) return cbn } var subjectByNameCreate = function subjectByNameCreate (dataParam) { var ci = -1 var d3map = d3.map() var cidx = dataParam cidx.forEach(function(d) { if (!d3map.has(d.source)) d3map.set(d.source, {name: d.source, index: ++ci}) if (!d3map.has(d.target)) d3map.set(d.target, {name: d.target, index: ++ci}) }) return d3map } var subjectByIndexCreate = function subjectByIndexCreate (dataParam) { // source, weigh, ??? var ci = -1 var subjectIndex = {} var d3map = d3.map() dataParam.forEach(function(d) { if (!d3map.has(d.source)) { ++ci; d3map.set(d.source, { index: ci }) subjectIndex[ci] = { name: d.source, index: ci, weigh: d.weigh, } } if (d3map.has(d.source)) { var e = d3map.get(d.source); subjectIndex[e.index] = { name: d.source, index: ci, weigh: d.weigh } } if (!d3map.has(d.target)) { ++ci; d3map.set(d.target, { index: ci }) subjectIndex[ci] = { name: d.target } } }) return subjectIndex } var actionsListCreate = function actionsListCreate (dataParam) { // source, target, predicate, weigh, value var cbn = [] var ci = -1 var d3map = d3.map() dataParam.forEach(function(d) { var cr = {} if (d3map.has(d.source)) cr.source = d3map.get(d.source); else { ++ci cr.source = {name: d.source, index: ci} d3map.set(d.source, cr.source) } if (d3map.has(d.target)) cr.target = d3map.get(d.target) else { ++ci cr.target = {name: d.target, index: ci} d3map.set(d.target, cr.target) } cr.predicate = d.predicate; cr.weigh = d.weigh; cr.valueOf = d.valueOf; cbn.push(cr) }) return cbn } // _____________ CHORDS var initialStateThis = { outerRate: 3/8, outerDelta: 20, chords: [], chordsCollection: [], chordsIndex: 0, areChordsFetched: false, src: 'chords.csv', itemsCursorLow: 0, itemsCursorHigh: 0, keyEventsOnChords: {}, itemSpan: 50, itemProps: ['source', 'target', 'predicate', 'weigh'], subjectByNameAll: {}, subjectByIndexAll: {}, actionsListAll: [], chordsCollection: [ {source: "architect", target: "faraon", predicate: "did village in tebas, workers!", weigh: 5}, {source: "faraon", target: "architect", predicate: "uhmm!!!", weigh: 10}, {source: "friend", target: "architect", predicate: "what a waste!!!", weigh: 9}, {source: "architect", target: "faraon", predicate: "built fortress in kadesh, hittites!", weigh: 5}, {source: "faraon", target: "architect", predicate: "uhmm!!!", weigh: 10}, {source: "girl friend", target: "architect", predicate: "coward!!!", weigh: 9}, {source: "faraon", target: "architect", predicate: "now sleeping room, eternal", weigh: 15}, {source: "architect", target: "faraon", predicate: "uhmm", weigh: 2}, {source: "friend", target: "architect", predicate: "lazy!!!", weigh: 9}, {source: "girl friend", target: "architect", predicate: "do it!!!", weigh: 9}, {source: "faraon", target: "architect", predicate: "resources, all!!!", weigh: 15}, {source: "architect", target: "faraon", predicate: "uhmm", weigh: 3}, {source: "architect", target: "faraon", predicate: " ..... ", weigh: 1}, {source: "architect", target: "faraon", predicate: " ..... ", weigh: 1}, {source: "architect", target: "faraon", predicate: " __/^\\__ !!!", weigh: 10}, {source: "faraon", target: "architect", predicate: "uhmm", weigh: 5}, {source: "friend", target: "architect", predicate: "uhmm!!!", weigh: 9}, {source: "girl friend", target: "architect", predicate: "uhmm!!!", weigh: 9}, {source: "faraon", target: "architect", predicate: "sitting room, inside!!!", weigh: 15}, {source: "faraon", target: "architect", predicate: "resources, all!!!", weigh: 15}, {source: "architect", target: "faraon", predicate: "uhmm", weigh: 3}, {source: "architect", target: "faraon", predicate: "uhmm", weigh: 2}, {source: "architect", target: "faraon", predicate: "uhmm", weigh: 1}, ], } function reducerThis(state = initialStateThis, action) { if (action == null) return state var ActionTypes = d3ringsActions.ActionTypes switch (action.type) { case ActionTypes.SET_CHORDS_COLLECTION: // setChordsCollection // console.log("SET_CHORDS_COLLECTION", action) var r = Object.assign({}, state) if (state.areChordsFetched == false) { var chordsCollection = action.payload.chordsCollection var itemSpan = state.itemSpan if (chordsCollection.length) { var cc = chordsCollection.map(function(d, i) { return({ prx: i, source: d.source, target: d.target, predicate: d.predicate, weigh: +d.weigh, valueOf: function value() { return this.weigh }, }) }) if (itemSpan > cc.length) itemSpan = cc.length r = Object.assign({}, state, { chordsCollection: cc, areChordsFetched: true, itemSpan: itemSpan, }) } } return r case ActionTypes.FETCH_CHORDS_COLLECTION: // fetchChordsCollection var data = action.payload.chords var areChordsFetched = state.areChordsFetched var itemSpan = state.itemSpan var r = Object.assign({}, state) if (areChordsFetched === false && typeof data !== 'undefined' && data.length) { var actionListAll = actionsListCreate(data) // source, target var subjectByNameAll = subjectByNameCreate(data) // source, target var subjectByIndexAll = subjectByIndexCreate(data) var actionsListAll = actionsListCreate(data) if (itemSpan > data.length) itemSpan = data.length r = Object.assign({}, state, { chordsCollection: data, areChordsFetched: true, actionListAll: actionListAll, subjectByNameAll: subjectByNameAll, subjectByIndexAll: subjectByIndexAll, actionsListAll: actionsListAll, itemSpan: itemSpan, }) } return r case ActionTypes.SET_CHORDS: // setChords // console.log("SET_CHORDS") var vLow = state.itemsCursorLow var vHigh = state.itemsCursorHigh var itemSpan = state.itemSpan var mode = action.payload.currentMode var r = state if (mode == 'autoMode') { var chordsCollection = state.chordsCollection var numChords = chordsCollection.length if (vHigh >= vLow) vHigh = vHigh + 1 // add one to upper border if (vHigh > numChords) vHigh = 0 // 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 > numChords) vLow = -1 // reset at end of cycle var chords = state.chordsCollection.slice(vLow, vHigh) var actionsSeries = actionsSeriesCreate(chords) // source, target var subjectByName = subjectByNameCreate(chords) // source, target var subjectByIndex = subjectByIndexCreate(chords) r = Object.assign({}, state, { chords: chords, itemsCursorLow: vLow, itemsCursorHigh: vHigh, actionsSeries: actionsSeries, subjectByName: subjectByName, subjectByIndex: subjectByIndex, }) } return r case ActionTypes.WALK_UP_CHORDS: // walkUpChords // console.log("WALK_UP_CHORDS", action) var keyEventsOnChords = state.keyEventsOnChords 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.itemsCursorLow var vHigh = state.itemsCursorHigh var itemSpan = action.payload.itemSpan var currentMode = action.payload.mode var r = state if (currentMode == 'walkMode') { if (keyEventsOnChords.upArrow !== null && keyEventsOnChords.upArrow !== action.payload.keyEvents.upArrow) { // upArrow keyEventsOnChords.upArrow = action.payload.keyEvents.upArrow vLow = Math.max(0, --vLow) var chords = state.chordsCollection.slice(vLow, vHigh) var actionsSeries = actionsSeriesCreate(chords) // source, target var subjectByName = subjectByNameCreate(chords) // source, target var subjectByIndex = subjectByIndexCreate(chords) r = Object.assign({}, state, { chords: chords, itemsCursorLow: vLow, itemsCursorHigh: vHigh, actionsSeries: actionsSeries, subjectByName: subjectByName, subjectByIndex: subjectByIndex, }) } } return r case ActionTypes.WALK_DOWN_CHORDS: // walkDownChords // console.log("WALK_DOWN_CHORDS") var keyEventsOnChords = state.keyEventsOnChords 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.itemsCursorLow var vHigh = state.itemsCursorHigh var itemSpan = state.itemSpan var currentMode = action.payload.currentMode var r = Object.assign({}, state) if (currentMode == 'walkMode') { if (keyEventsOnChords.downArrow !== null && keyEventsOnChords.downArrow !== action.payload.keyEvents.downArrow) { // downArrow keyEventsOnChords.downArrow = action.payload.keyEvents.downArrow r = Object.assign({}, state, keyEventsOnChords) if ((vHigh - vLow) >= itemSpan) ++vLow ++vHigh if (vHigh > numChords) vHigh = 0 // upper border var chords = state.chordsCollection.slice(vLow, vHigh) var actionsSeries = actionsSeriesCreate(chords) // source, target var subjectByName = subjectByNameCreate(chords) // source, target var subjectByIndex = subjectByIndexCreate(chords) r = Object.assign({}, state, { chords: chords, itemsCursorLow: vLow, itemsCursorHigh: vHigh, actionsSeries: actionsSeries, subjectByName: subjectByName, subjectByIndex: subjectByIndex, }) } } return r default: return state } } exports.reducer = reducerThis; })); /* */ /* d3rings-renderer-chords.js */ /* ref. https://bl.ocks.org/mbostock/1308257 */ // http://circos.ca/guide/tables/ // http://bl.ocks.org/mbostock/4062006 /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.js') } (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3ringsRendererChords = global.d3ringsRendererChords || {}))); }(this, function (exports) { 'use strict'; // _____________ context var stateChords = { reducerChords: {} } 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(stateChords.reducerChords.chords) === JSON.stringify(newState.reducerChords.chords)) { return } var state = stateChords = newState var data = state.reducerChords.chords if (!data.length) return var lastDataItem = data.slice(-1)[0] // hide on wrong views var _opacity = 1 var _currentView = state.reducerCourt.currentView if (_currentView !== 'chordsView') _opacity = 0 var _width = state.reducerCourt.svgWidth var _height = state.reducerCourt.svgHeight var _svgid = state.reducerConfig.container var _currentView = state.reducerCourt.currentView var _fadeTime = state.reducerConfig.fadeFactor * state.reducerConfig.beatTime var subjectByName = state.reducerChords.subjectByName var subjectByIndex = state.reducerChords.subjectByIndex var actionsSeries = state.reducerChords.actionsSeries var outerRate = state.reducerChords.outerRate var outerDelta = state.reducerChords.outerDelta // var _groupNameColorFrom = 'white' var _groupNameColorTo = 'white' var _groupNameColorOther = 'SaddleBrown' var _groupArcColorFrom = 'black' var _groupArcColorTo = 'darkgrey' var _groupToolTipColorOther = 'gray' var _groupBorderColor = "gray" var _chordColorLast = "gold" var _chordColorOther = 'yellow' var _predicateColorLast = "sienna" var _predicateColorOther = 'gold' var _predicateTextSize = 12 // SVG var svgContainer = d3.select('body') .selectAll('svg') .data(['svg'], function(d) { return 'svg' }) var newSvgContainer = svgContainer .enter() .append("svg") .attr("id", 'svg') svgContainer .style('width', _width) .style('height', _height) // --------------------------------------- // http://bl.ocks.org/brattonc/b1abb535227b2f722b51. function textWidth(N, s) { var dummyText = svgContainer.select(".dummyText") if (dummyText.node() == null) { dummyText = svgContainer .append("text") .attr("id", "dummyText") .attr("class", "dummyText") .text(N) .style("font-size", function(d, i) { return s }) } var textHeight = dummyText.node().getBBox().height var textWidth = dummyText.node().getBBox().width svgContainer.select(".dummyText").remove() return textWidth } // --------------------------------------- // trasition var d3Transition = d3.transition() .duration(_fadeTime) .ease(d3.easeLinear) // --------------------------------------- var outerRadius = outerRate * Math.min(_width, _height), innerRadius = outerRadius - outerDelta; var format = d3.format(",.3r"); // var formatValue = d3.formatPrefix(",.0", 1e3); // The arc generator, for the groups. var arc = d3.arc() .innerRadius(innerRadius) .outerRadius(outerRadius); var ribbon = d3.ribbon() .radius(innerRadius); var fill = d3.scaleLinear() .domain([0, 9]) .range(["#F8EDD3", "#DB704D"]) var color = d3.scaleOrdinal() .domain(d3.range(4)) .range(["#000000", "#FFDD89", "#957244", "#F26223"]); // --------------------------------------- MATRIX var matrix = [] for (var i = 0; i < subjectByName.size(); i++) { matrix[i] = []; for (var j = 0; j < subjectByName.size(); j++) { matrix[i][j] = 0; } } actionsSeries.forEach(function(d) { matrix[d.source.index][d.target.index] = d; }) var chord = d3.chord() .padAngle(0.05) // .radius(innerRadius // .sortSubgroups(d3.descending) var chordsMatrix = chord(matrix, actionsSeries, subjectByName, subjectByIndex) // var chordsMatrix = chord(matrix) // .sortChords(d3.descending) // .padding(.07); var ribbon = d3.ribbon() .radius(innerRadius); // --------------------------------------- // CHORDS GROUP var chordsGroup = svgContainer .selectAll('g.chords') // items .data(['chords group']) var chordsGroupNew = chordsGroup.enter() .append("g") .classed("chords", true) // items .attr("transform", "translate(" + _width / 2 + "," + _height / 2 + ")") .datum(chordsMatrix); // --------------------------------------- // GROUPS GROUP var groupsGroup = svgContainer .select('g.chords') .selectAll('g.groups') .data(['groups group']) var groupsGroupNew = groupsGroup.enter() .append("g") .classed("groups", true) // --------------------------------------- // GROUPS ELEMS var groupElems = svgContainer .select("g.groups") .selectAll("g.group") .data(chordsMatrix.groups, function(d) { return d.index }) // GROUPS ELEMS EXIT groupElems.exit() .remove() // GROUPS ELEMS ENTER var groupElemsEnter = groupElems.enter() .append("g") .classed("group", true) // --------------------------------------- // var gpath = svgContainer // .select("g.chords") // .selectAll('path') // .data(chordsMatrix.groups, function(d) { // return d.index }) // gpath.attr('id', function(d){return 'path22' + d.index}) // gpath.attr('d', d3.arc() // .innerRadius(innerRadius/ 2) // .outerRadius(outerRadius/ 2) // ) // gpath.enter().append('path') // .attr('d', d3.arc() // .innerRadius(innerRadius/ 2) // .outerRadius(outerRadius / 2) // ) // gpath.exit().remove() // GROUPS ARCS ENTER groupElemsEnter .append("path") .style("fill", function(d) { // arcs - new by index in chart var r = fill(d.index) if (subjectByIndex[d.index].name == lastDataItem.source) r = _groupArcColorFrom if (subjectByIndex[d.index].name == lastDataItem.target) r = _groupArcColorTo return r }) .style("stroke", _groupToolTipColorOther) .style("stroke-width", 1) .attr("id", function(d, i) { return "group" + d.index; }) .attr("d", arc) .append("title") // group toolTip .text(function(d) { return subjectByIndex[d.index].name + " predicates " + format(d.value) + "with weigh " + subjectByIndex[d.index].weigh; }) // GROUPS ARCS UPDATE groupElems .select('path') .attr("d", arc) .style("fill", function(d) { // group arcs update var r = fill(d.index) if (subjectByIndex[d.index].name == lastDataItem.source) r = _groupArcColorFrom if (subjectByIndex[d.index].name == lastDataItem.target) r = _groupArcColorTo return r }) .style("stroke", _groupBorderColor) .style("stroke-width", 1) // --------------------------------------- // GROUPS NAMES ENTER groupElemsEnter .append("text") .attr("x", 6) .attr("dy", 15) .append("textPath") .attr("xlink:href", function(d) { return "#group" + d.index; }) .text(function(d) { var text = subjectByIndex[d.index].name // group name enter return text }) .style("stroke", function(d, i , a) { var r = _groupNameColorOther if (subjectByIndex[d.index].name == lastDataItem.source) r = _groupNameColorFrom if (subjectByIndex[d.index].name == lastDataItem.target) r = _groupNameColorTo return r }) .style("fill", function(d, i , a) { var r = _groupNameColorOther if (subjectByIndex[d.index].name == lastDataItem.source) r = _groupNameColorFrom if (subjectByIndex[d.index].name == lastDataItem.target) r = _groupNameColorTo return r }) .style("stroke-width", function(d, i , a) { var r = 1 return r }) // GROUPS NAMES UPDATE groupElems .select('textPath') .text(function(d) { return subjectByIndex[d.index].name }) // group name update .style("stroke", function(d, i , a) { var r = _groupNameColorOther if (subjectByIndex[d.index].name == lastDataItem.source) r = _groupNameColorFrom if (subjectByIndex[d.index].name == lastDataItem.target) r = _groupNameColorTo return r }) .style("fill", function(d, i , a) { var r = _groupNameColorOther if (subjectByIndex[d.index].name == lastDataItem.source) r = _groupNameColorFrom if (subjectByIndex[d.index].name == lastDataItem.target) r = _groupNameColorTo return r }) // GROUPS ToolTips UPDATE groupElems .select('title') .text(function(d) { return subjectByIndex[d.index].name + " " + " predicates " + format(d.value) + "with weigh " + subjectByIndex[d.index].weigh; }); // --------------------------------------- // RIBBONS GROUP var ribbonsGroup = svgContainer .select('g.ribbons') .selectAll('g.ribbons') .data(['ribbons group']) var ribbonsGroupNew = ribbonsGroup.enter() .append("g") .classed("ribbons", true) // --------------------------------------- // RIBBONS ELEMS var ribbonsElems = svgContainer .select("g.chords") .selectAll("g.ribbon") .data(chordsMatrix, function(d, i) { return d.prx }) // RIBBONS ELEMS EXIT ribbonsElems.exit() .remove() // RIBBONS ELEMS ENTER var ribbonsElemsEnter = ribbonsElems.enter() .append("g") .classed("ribbon", true) ribbonsElemsEnter .append("path") .attr("id", function(d, i) { return "ribbon" + d.source.value.prx }) .attr("d", ribbon) // .style("fill", function(d) { return fill(d.source.index) }) .style("fill", function(d) { // ribbon path enter var r = fill(d.source.value.source.index) if (d.source.value.source.name == lastDataItem.source) r = _chordColorLast return r }) .style("stroke", function(d) { return d3.rgb(fill(d.source.index)).darker(); }) .append("title") .text(function(d) { return d.source.value.source.name + " to " + d.source.value.target.name + ":" + format(d.source.value)}) // RIBBONS ELEMS UPDATE ribbonsElems .select("path") .attr("d", ribbon) // .attr("d", function(d) { // return d // }) .style("fill", function(d) { // ribbon path update var r = fill(d.source.value.source.index) return r }) // CHORDS TITLE ribbonsElems .select("title") .text(function(d) { // source (index, subindex, startAngle, endAngle, value), target var r = d.source.value.source.name + " to " + d.source.value.target.name + ":" + format(d.source.value) return r}) // --------------------------------------- // PREDICATES GROUP var predicatesGroup = svgContainer .select('g.chords') .selectAll("g.predicates") .data(['predicates group']) var predicatesGroupNew = predicatesGroup.enter() .append("g") .classed("predicates", true) // items // --------------------------------------- // PREDICATES ELEMS var predicatesElems = svgContainer .select("g.predicates") .selectAll("g.predicate") .data(chordsMatrix, function(d) { return d.source.value.prx}) // PREDICATES EXIT predicatesElems.exit() .remove() // PREDICATES ENTER var predicatesElemsEnter = predicatesElems.enter() // ^^^^^^^^^^^^^^ CONVERSATION .append("g") .attr("class","predicate") .append("text") .attr("x", 0) .attr("y", 0) .attr("class","predicate") .text(function(d) { var r = d.source.value.predicate return r }) .style("font-size", function(d, i) { return _predicateTextSize }) .attr("transform", function(d) { var rotate = '' var translate = '' var mirror = '' var transform = '' var d3Angle = (d.source.startAngle + d.source.endAngle) / 2 var mathAngle = (2 * Math.PI) - (d3Angle - (Math.PI / 2)) // var rotate = "rotate(" + (d3Angle * 180 / Math.PI - 90) + ") " // var translate = "translate(" + (innerRadius + 26) + ") " // var mirror = (d3Angle > Math.PI ? "rotate(180)" : "") var deltaX, deltaY, tx, ty tx = ty = deltaX = deltaY = 0 if (d3Angle > 0/2 * Math.PI && d3Angle < 1/2 * Math.PI ) { // NE deltaX = 0 deltaY = 0 } else if (d3Angle > 1/2 * Math.PI && d3Angle < 2/2 * Math.PI ) { // SE deltaX = 0 deltaY = textWidth("N", _predicateTextSize) } else if (d3Angle > 2/2 * Math.PI && d3Angle < 3/2 * Math.PI ) { // SW deltaX = - textWidth(d.source.value.predicate, _predicateTextSize) - textWidth("N", _predicateTextSize) deltaY = textWidth("N", _predicateTextSize) } else if (d3Angle > 3/2 * Math.PI && d3Angle < 4/2 * Math.PI) { // NW deltaX = - textWidth(d.source.value.predicate, _predicateTextSize) - textWidth("N", _predicateTextSize) deltaY = 0 } tx = outerRadius * Math.cos(mathAngle) ty = - outerRadius * Math.sin(mathAngle) // inverse screen metrix translate = "translate(" + (tx + deltaX) + "," + (ty + deltaY) + ") " transform = rotate + translate + mirror // ^^^^^^^^^^^^^^^ return transform }) .style("fill", function(d) { var r = (d.source.value.prx == lastDataItem.prx) ? _predicateColorLast : _predicateColorOther return r }) // PREDICATES UPDATE predicatesElems .select("text.predicate") .style("fill", function(d, i , a) { var r = _predicateColorOther return r }) .style("font-size", function(d, i) { return 0 }) .attr("transform", function(d) { var rotate = '' var translate = '' var mirror = '' var transform = '' var d3Angle = (d.target.startAngle + d.target.endAngle) / 2 var mathAngle = (2 * Math.PI) - (d3Angle - (Math.PI / 2)) var tx = outerRadius * Math.cos(mathAngle) var ty = - outerRadius * Math.sin(mathAngle) // inverse screen metrix translate = "translate(" + (tx) + "," + (ty) + ") " transform = rotate + translate + mirror // ^^^^^^^^^^^^^^^ return transform }) .style("opacity", function(d) { return 0 }) } exports.renderer = renderer; })) /* */ /* 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') var d3ringsActionsChords = require('./d3rings-actions-chords.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, d3ringsActionsChords.ActionTypes ) var ActionCreators = merge_objects( d3ringsActionsCourt.ActionCreators, d3ringsActionsDebug.ActionCreators, d3ringsActionsLanes.ActionCreators, d3ringsActionsParticles.ActionCreators, d3ringsActionsWhirls.ActionCreators, d3ringsActionsChords.ActionCreators ) exports.ActionTypes = ActionTypes; exports.ActionCreators = ActionCreators; })); /* */ /* d3rings-reducer-config.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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'; // _____________ CONFIG var initialStateConfig = { modes: {autoMode: 'autoMode', walkMode: 'walkMode'}, modeLabels: {autoMode: 'auto', walkMode: 'walk'}, views: ['chordsView', '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 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 d3ringsReducerChords = require('./d3rings-reducer-chords.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, reducerChords: d3ringsReducerChords.reducer, }) var r = reducer() exports.reducer = reducer; })); /* */ /* d3rings-store.js */ /* */ if (typeof require === "function") { var d3ringsReducer = require('./d3rings-reducer.js') var d3ringsStore = require('./d3rings-store.js') var d3ringsActions = require('./d3rings-actions.js') var d3ringsControls = require('./d3rings-controls.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, } } /* store */ var store = createStore(d3ringsReducer.reducer, d3ringsReducer.reducer()) exports.createStore = createStore exports.store = store })); /* */ /* d3rings-listeners-court.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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') } (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.d3ringsListenersCourt = global.d3ringsListenersCourt || {}))); }(this, function (exports) { 'use strict'; /* actions */ var actions = d3ringsActions.ActionCreators /* store */ // var store = d3ringsStore.createStore(d3ringsReducer.reducer, d3ringsReducer.reducer()) var store = d3ringsStore.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* 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 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 ) // renderers var renderer_court_Listener = store.compose( d3ringsRendererCourt.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) })); /* */ /* d3rings-listeners-debug.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* launchers debug */ var setFps_debug_Listener = store.compose( store.dispatch, actions.setFps ) /* 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() /* 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 */ d3timer_Launcher.subscribe(setFps_debug_Listener) /* */ /* d3rings-listeners-lanes.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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()) var store = d3ringsStore.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* 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 }} /* 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 ) // renderers var renderer_lanes_Listener = store.compose( d3ringsRendererLanes.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_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) /* */ /* d3rings-listeners-particles.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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()) var store = d3ringsStore.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* 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 }} /* 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 ) // renderers var renderer_particles_Listener = store.compose( d3ringsRendererParticles.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_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) /* */ /* d3rings-whirls-debug.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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()) var store = d3ringsStore.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* 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, }} /* 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 ) // renderers 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_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) /* */ /* d3rings-listeners-chords.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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()) var store = d3ringsStore.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* payloads chords */ var keyDownKeysChords_Payload = function () { return { keyEvents: store.getState().reducerCourt.keyEvents, currentMode: store.getState().reducerCourt.currentMode, itemSpan: store.getState().reducerConfig.itemSpan, }} var keyUpKeysChords_Payload = function () { return { keys: store.getState().reducerCourt.keys, currentMode: store.getState().reducerCourt.currentMode, itemSpan: store.getState().reducerConfig.itemSpan, }} var setChords_Payload = function () { return { currentMode: store.getState().reducerCourt.currentMode }} var fetchChordsCollection_Payload = function () { return { src: store.getState().reducerChords.src, areChordsFetched: store.getState().reducerChords.areChordsFetched, }} var setChordsCollection_Payload = function () { return { chordsCollection: store.getState().reducerChords.chordsCollection }} /* launchers chords */ var keyDownArrow_chords_Listener = store.compose( store.dispatch, actions.walkDownChords, keyDownKeysChords_Payload ) var keyUpArrow_chords_Listener = store.compose( store.dispatch, actions.walkUpChords, keyUpKeysChords_Payload ) var fetchChordsCollection_chords_Listener = store.compose( function(payload) { if (payload.areChordsFetched == false) { return d3.queue() .defer(d3.csv, store.getState().reducerChords.src, // processRecord function (d, i) { d.prx = i d.source = d.source d.target = d.target d.predicate = d.predicate d.weigh = +d.weigh d.valueOf = function value() { return this.weigh } return d; } ) .await( // processData function (error, dataCsv) { store.dispatch(actions.fetchChordsCollection({chords: dataCsv})) } ) } }, fetchChordsCollection_Payload ) var setChordsCollection_chords_Listener = store.compose( store.dispatch, actions.setChordsCollection, setChordsCollection_Payload ) var setChords_chords_Listener = store.compose( store.dispatch, actions.setChords, setChords_Payload ) // renderers var renderer_chords_Listener = store.compose( d3ringsRendererChords.renderer, logicAndData_Payload ) /* listeners */ store.subscribe(renderer_chords_Listener) stepper_Launcher.subscribe(setChords_chords_Listener) stepper_Launcher.subscribe(setChordsCollection_chords_Listener) stepper_Launcher.subscribe(fetchChordsCollection_chords_Listener) stepper_Launcher.subscribe(keyUpArrow_chords_Listener) stepper_Launcher.subscribe(keyDownArrow_chords_Listener) /* */ /* index.js */ /* */ if (typeof require === "function") { var d3 = require('./d3.v4.0.0-rc.2.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 d3ringsRendererChords = require('./d3rings-renderer-chords.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()) var store = d3ringsStore.store /* payloads renderers */ var logicAndData_Payload = function () { return { store: store, actions: actions }} /* 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") /* 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()