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