diff --git a/src/hybridSimulation.js b/src/hybridSimulation.js index 12ab577..bf4881a 100644 --- a/src/hybridSimulation.js +++ b/src/hybridSimulation.js @@ -1,8 +1,8 @@ -import {dispatch} from "d3-dispatch"; -import constant from "./constant"; -import interpBruteForce from "./interpolation/interpBruteForce"; -import interpolationPivots from "./interpolation/interpolationPivots"; -import {takeSampleFrom} from "./interpolation/helpers"; +import {dispatch} from 'd3-dispatch'; +import constant from './constant'; +import interpBruteForce from './interpolation/interpBruteForce'; +import interpolationPivots from './interpolation/interpolationPivots'; +import {takeSampleFrom} from './interpolation/helpers'; /** * An implementation of Chalmers, Morrison, and Ross' 2002 hybrid layout @@ -27,37 +27,37 @@ import {takeSampleFrom} from "./interpolation/helpers"; export default function (sim, forceS, forceF) { var SAMPLE_ITERATIONS = 300, - FULL_ITERATIONS = 20, + FULL_ITERATIONS = 20, interpDistanceFn, - NUM_PIVOTS = 0, - INTERP_FINE_ITS = 20, + NUM_PIVOTS = 0, + INTERP_FINE_ITS = 20, sample = [], remainder = [], simulation = sim, forceSample = forceS, forceFull = forceF, - event = d3.dispatch("sampleTick", "fullTick", "startInterp", "end"), + event = d3.dispatch('sampleTick', 'fullTick', 'startInterp', 'end'), initAlready = false, nodes, alreadyRanIterations, hybrid; - if(simulation != undefined) initSimulation(); - if(forceS != undefined || forceF != undefined) initForces(); + if (simulation != undefined) initSimulation(); + if (forceS != undefined || forceF != undefined) initForces(); // Performed on first run - function initialize() { + function initialize () { initAlready = true; alreadyRanIterations = 0; simulation - .on("tick", sampleTick) - .on("end", sampleEnded) + .on('tick', sampleTick) + .on('end', sampleEnded) .nodes(sample) - .force("Sample force", forceSample); - console.log("Initialized Simulation for Hybrid"); + .force('Sample force', forceSample); + console.log('Initialized Simulation for Hybrid'); } - function initForces(){ + function initForces () { if (forceSample.onStableVelo) { forceSample.onStableVelo(sampleEnded); } @@ -75,12 +75,12 @@ export default function (sim, forceS, forceF) { } } - function initSimulation(){ + function initSimulation () { nodes = simulation.nodes(); simulation .stop() .alphaDecay(0) - .alpha(1) + .alpha(1); let sets = takeSampleFrom(nodes, Math.sqrt(nodes.length)); sample = sets.sample; @@ -88,64 +88,64 @@ export default function (sim, forceS, forceF) { } // Sample simulation ticked 1 frame, keep track of number of iterations here. - function sampleTick() { - event.call("sampleTick"); - if(alreadyRanIterations++ >= SAMPLE_ITERATIONS){ + function sampleTick () { + event.call('sampleTick'); + if (alreadyRanIterations++ >= SAMPLE_ITERATIONS) { sampleEnded(); } } // Full simulation ticked 1 frame, keep track of number of iterations here. - function fullTick() { - event.call("fullTick"); - if(alreadyRanIterations++ >= FULL_ITERATIONS){ + function fullTick () { + event.call('fullTick'); + if (alreadyRanIterations++ >= FULL_ITERATIONS) { fullEnded(); } } - function fullEnded() { + function fullEnded () { simulation.stop(); initAlready = false; - simulation.force("Full force", null); - event.call("end"); + simulation.force('Full force', null); + event.call('end'); } - function sampleEnded() { + function sampleEnded () { simulation.stop(); - simulation.force("Sample force", null); + simulation.force('Sample force', null); // Reset velocity of all nodes - for (let i=sample.length-1; i>=0; i--){ - sample[i].vx=0; - sample[i].vy=0; + for (let i = sample.length - 1; i >= 0; i--) { + sample[i].vx = 0; + sample[i].vy = 0; } - event.call("startInterp"); - if (NUM_PIVOTS>=1) { + event.call('startInterp'); + if (NUM_PIVOTS >= 1) { interpolationPivots(sample, remainder, NUM_PIVOTS, interpDistanceFn, INTERP_FINE_ITS); } else { interpBruteForce(sample, remainder, interpDistanceFn, INTERP_FINE_ITS); } - event.call("fullTick"); + event.call('fullTick'); alreadyRanIterations = 0; simulation - .on("tick", null) - .on("end", null) // The ending condition should be iterations count + .on('tick', null) + .on('end', null) // The ending condition should be iterations count .nodes(nodes); - if (FULL_ITERATIONS<1 || forceF === undefined || forceF === null) { - event.call("end"); + if (FULL_ITERATIONS < 1 || forceF === undefined || forceF === null) { + event.call('end'); return; } simulation - .on("tick", fullTick) - .force("Full force", forceFull) + .on('tick', fullTick) + .force('Full force', forceFull) .restart(); } return hybrid = { restart: function () { - if(!initAlready) initialize(); + if (!initAlready) initialize(); simulation.restart(); return hybrid; }, @@ -184,7 +184,7 @@ export default function (sim, forceS, forceF) { }, interpDistanceFn: function (_) { - return arguments.length ? (interpDistanceFn = typeof _ === "function" ? _ : constant(+_), hybrid) : interpDistanceFn; + return arguments.length ? (interpDistanceFn = typeof _ === 'function' ? _ : constant(+_), hybrid) : interpDistanceFn; }, simulation: function (_) { @@ -197,7 +197,7 @@ export default function (sim, forceS, forceF) { forceFull: function (_) { return arguments.length ? (forceFull = _, initForces(), hybrid) : forceFull; - }, + } }; } diff --git a/src/interpolation/interpBruteForce.js b/src/interpolation/interpBruteForce.js index c4acd92..1591cd8 100644 --- a/src/interpolation/interpBruteForce.js +++ b/src/interpolation/interpBruteForce.js @@ -1,5 +1,5 @@ -import {takeSampleFrom} from "./helpers"; -import {placeNearToNearestNeighbour} from "./interpCommon"; +import {takeSampleFrom} from './helpers'; +import {placeNearToNearestNeighbour} from './interpCommon'; /** * Perform interpolation where the "parent" node is found by brute-force. @@ -18,19 +18,19 @@ import {placeNearToNearestNeighbour} from "./interpCommon"; * @param {number} endingIts - for phase 3, how many iterations to refine the * placement of each interpolated point */ -export default function(sampleSet, remainderSet, distanceFn, endingIts) { +export default function (sampleSet, remainderSet, distanceFn, endingIts) { let sampleSubset = takeSampleFrom(sampleSet, Math.sqrt(sampleSet.length)).sample, sampleSubsetDistanceCache = []; // For each datapoint "node" to be interpolated - for (let i = remainderSet.length-1; i>=0; i--) { + for (let i = remainderSet.length - 1; i >= 0; i--) { let node = remainderSet[i], nearestSample, minDist, sample, dist, index; // For each datapoint "sample" in the sample set - for (let j = sampleSet.length-1; j>=0; j--) { + for (let j = sampleSet.length - 1; j >= 0; j--) { sample = sampleSet[j]; dist = distanceFn(node, sample); if (nearestSample === undefined || dist < minDist) { diff --git a/src/interpolation/interpCommon.js b/src/interpolation/interpCommon.js index 860c311..29e2305 100644 --- a/src/interpolation/interpCommon.js +++ b/src/interpolation/interpCommon.js @@ -1,5 +1,5 @@ -import {pointOnCircle, sumDistError} from "./helpers"; -import jiggle from "../jiggle"; +import {pointOnCircle, sumDistError} from './helpers'; +import jiggle from '../jiggle'; /** * Phase 2 and 3 of each node to be interpolated. @@ -24,9 +24,9 @@ import jiggle from "../jiggle"; index must correspond to sampleSubset * @param {Integer} endingIts - Number of iterations for phase 3 */ -export function placeNearToNearestNeighbour(node, nearNeighbour, radius, sampleSubset, realDistances, endingIts) { +export function placeNearToNearestNeighbour (node, nearNeighbour, radius, sampleSubset, realDistances, endingIts) { let - sumDistErrorByAngle = function(angle){ + sumDistErrorByAngle = function (angle) { return sumDistError(pointOnCircle(nearNeighbour.x, nearNeighbour.y, angle, radius), sampleSubset, realDistances); }, dist0 = sumDistErrorByAngle(0), @@ -71,21 +71,21 @@ export function placeNearToNearestNeighbour(node, nearNeighbour, radius, sampleS // Phase 3 let - multiplier = 1/sampleSubset.length, + multiplier = 1 / sampleSubset.length, sumForces; for (let i = 0; i < endingIts; i++) { sumForces = sumForcesToSample(node, sampleSubset, realDistances); - node.x += sumForces.x*multiplier; - node.y += sumForces.y*multiplier; + node.x += sumForces.x * multiplier; + node.y += sumForces.y * multiplier; } } -function sumForcesToSample(node, samples, sampleCache) { +function sumForcesToSample (node, samples, sampleCache) { let nodeVx = 0, nodeVy = 0, x, y, l, i, sample; - for (i = samples.length-1; i >=0 ; i--) { + for (i = samples.length - 1; i >= 0; i--) { sample = samples[i]; // jiggle so l won't be zero and divide by zero error after this @@ -108,19 +108,19 @@ function sumForcesToSample(node, samples, sampleCache) { * @param {function(x)} fn - function that takes in a number x and returns a number * @return {integer} - an integer x where f(x) is minimum */ -function binarySearchMin(lb, hb, fn) { +function binarySearchMin (lb, hb, fn) { while (lb <= hb) { - if(lb === hb) return lb; + if (lb === hb) return lb; - if(hb-lb == 1) { + if (hb - lb == 1) { if (fn(lb) >= fn(hb)) return hb; else return lb; } let - range = hb-lb, - valLowerHalf = fn(lb + range/4), - valHigherHalf = fn(lb + range*3/4); + range = hb - lb, + valLowerHalf = fn(lb + range / 4), + valHigherHalf = fn(lb + range * 3 / 4); if (valLowerHalf > valHigherHalf) lb = Math.floor((lb + hb) / 2); diff --git a/src/interpolation/interpolationPivots.js b/src/interpolation/interpolationPivots.js index 8b0231d..5a7a07a 100644 --- a/src/interpolation/interpolationPivots.js +++ b/src/interpolation/interpolationPivots.js @@ -1,5 +1,5 @@ -import {takeSampleFrom} from "./helpers"; -import {placeNearToNearestNeighbour} from "./interpCommon"; +import {takeSampleFrom} from './helpers'; +import {placeNearToNearestNeighbour} from './interpCommon'; /** * Perform interpolation where the "parent" node is is estimated by pivot-based searching. @@ -23,7 +23,7 @@ import {placeNearToNearestNeighbour} from "./interpCommon"; * @param {number} endingIts - for phase 3, how many iterations to refine the * placement of each interpolated point */ -export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIts) { +export default function (sampleSet, remainderSet, numPivots, distanceFn, endingIts) { // Pivot based parent finding let numBuckets = Math.floor(Math.sqrt(sampleSet.length)); let numNonPivots = sampleSet.length - numPivots; @@ -69,7 +69,7 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt let bucketNumber = Math.floor(distCache[i][j] / bucketWidth); if (bucketNumber >= numBuckets) { bucketNumber = numBuckets - 1; - } else if (bucketNumber < 0) { // Should never be negative anyway + } else if (bucketNumber < 0) { // Should never be negative anyway bucketNumber = 0; } pivotsBuckets[j][bucketNumber].push(sample); @@ -77,10 +77,9 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt } // --------------------------------------------------------------------- - let sampleSubset = takeSampleFrom(sampleSet, Math.sqrt(sampleSet.length)).sample; - //Plot each of the remainder nodes - for (let i = remainderSet.length-1; i>=0; i--) { + // Plot each of the remainder nodes + for (let i = remainderSet.length - 1; i >= 0; i--) { let node = remainderSet[i]; let sampleSubsetDistanceCache = [], minDist, nearSample; @@ -95,7 +94,7 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt if (index !== -1) { sampleSubsetDistanceCache[index] = dist; } - if (minDist === undefined || dist < minDist){ + if (minDist === undefined || dist < minDist) { minDist = dist; nearSample = pivot; } @@ -103,11 +102,11 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt let bucketNumber = Math.floor(dist / bucketWidth); if (bucketNumber >= numBuckets) { bucketNumber = numBuckets - 1; - } else if (bucketNumber < 0) { // Should never be negative anyway + } else if (bucketNumber < 0) { // Should never be negative anyway bucketNumber = 0; } - for (let j = pivotsBuckets[p][bucketNumber].length-1; j>=0; j--) { + for (let j = pivotsBuckets[p][bucketNumber].length - 1; j >= 0; j--) { let candidateNode = pivotsBuckets[p][bucketNumber][j]; let index = sampleSubset.indexOf(candidateNode); if (index !== -1 && sampleSubsetDistanceCache[index] !== undefined) @@ -118,7 +117,7 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt sampleSubsetDistanceCache[index] = dist; } - if (dist < minDist){ + if (dist < minDist) { minDist = dist; nearSample = candidateNode; }