Compare commits
7 Commits
pivotHitRa
...
withConsol
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6182a5fc26 | ||
|
|
adf8126d86 | ||
|
|
0d148b555f | ||
|
|
5ee568b1cb | ||
|
|
054ff7312e | ||
|
|
6813be06df | ||
|
|
b88d3c9bfa |
@@ -143,7 +143,7 @@ If *threshold* is specified, sets a threshold and returns this force. When the a
|
|||||||
|
|
||||||
If *handler* is specified, sets a handler function which will be called at the end of each iteration if the average velocity changes of the system goes below the [threshold](#neighbourSampling_stableVelocity), and returns this force. To remove the handler, change it to null. If *threshold* is not specified, returns the current value, which defaults to null.
|
If *handler* is specified, sets a handler function which will be called at the end of each iteration if the average velocity changes of the system goes below the [threshold](#neighbourSampling_stableVelocity), and returns this force. To remove the handler, change it to null. If *threshold* is not specified, returns the current value, which defaults to null.
|
||||||
|
|
||||||
### Hybrid Layout Simulation - TO WRITE
|
### Hybrid Layout Simulation
|
||||||
|
|
||||||
The hybrid layout algorithm reduces the computation power usage even further by performing neighbour and sampling algorithm on only $\sqrt{n}$ sample subset of the data, and interpolating the rest in. Neighbour and sampling algorithm may also be ran again over the full dataset after the interpolation to refine the layout. This algorithm is only recommended for visualizing larger dataset.
|
The hybrid layout algorithm reduces the computation power usage even further by performing neighbour and sampling algorithm on only $\sqrt{n}$ sample subset of the data, and interpolating the rest in. Neighbour and sampling algorithm may also be ran again over the full dataset after the interpolation to refine the layout. This algorithm is only recommended for visualizing larger dataset.
|
||||||
|
|
||||||
@@ -151,9 +151,9 @@ The hybrid layout algorithm reduces the computation power usage even further by
|
|||||||
|
|
||||||
Creates a new hybrid layout simulation default parameters. The simulation will takeover control of [d3.forceSimulation](https://github.com/d3/d3-force#forceSimulation) provided (*simulation* parameter). *forceSample* and *forceFull* are pre-configured [d3.forceNeighbourSampling](#forceNeighbourSampling) forces to be run over the $\sqrt{n}$ samples and full dataset respectively. While unsupported, other D3 forces such as [d3.forceLinkFullyConnected](forceLinkFullyConnected) may also work.
|
Creates a new hybrid layout simulation default parameters. The simulation will takeover control of [d3.forceSimulation](https://github.com/d3/d3-force#forceSimulation) provided (*simulation* parameter). *forceSample* and *forceFull* are pre-configured [d3.forceNeighbourSampling](#forceNeighbourSampling) forces to be run over the $\sqrt{n}$ samples and full dataset respectively. While unsupported, other D3 forces such as [d3.forceLinkFullyConnected](forceLinkFullyConnected) may also work.
|
||||||
|
|
||||||
*forceSample* may have [stableVelocity](neighbourSampling_stableVelocity) configured to end the simulation and begin the interpolation phase early, but any [handler](neighbourSampling_onStableVelo) functions will be replaced be hybridSimulation's own internal function.
|
*forceSample* and *forceFull* may have [stableVelocity](neighbourSampling_stableVelocity) configured to end the simulation and begin the interpolation phase early, but any [handler](neighbourSampling_onStableVelo) functions will be replaced be hybridSimulation's own internal function.
|
||||||
|
|
||||||
*forceSample* may be absent, null, or undefined to skip the final refinement.
|
*forceFull* may also be absent, null, or undefined to skip the final refinement.
|
||||||
|
|
||||||
*simulation* should have already been loaded with nodes. If there are any changes in the list of nodes, the simulation have to be re-set using the [.simulation](#hybrid_simulation) method.
|
*simulation* should have already been loaded with nodes. If there are any changes in the list of nodes, the simulation have to be re-set using the [.simulation](#hybrid_simulation) method.
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ If *force* is specified, sets the neighbour and sampling force to run on the $\s
|
|||||||
|
|
||||||
<a name="hybrid_forceFull" href="#hybrid_forceFull">#</a> *hybrid*.**forceFull**([*force*])
|
<a name="hybrid_forceFull" href="#hybrid_forceFull">#</a> *hybrid*.**forceFull**([*force*])
|
||||||
|
|
||||||
If *force* is specified, sets the neighbour and sampling force to run on the whole dataset after interpolation and returns this layout simulation. If set to null, the process will be skipped. If *force* is not specified, returns the current force object.
|
If *force* is specified, sets the neighbour and sampling force to run on the whole dataset after interpolation and returns this layout simulation. The same limitation applies: [stableVelocity](neighbourSampling_stableVelocity) may be configured to end the simulation and begin the interpolation phase early, but any [handler](neighbourSampling_onStableVelo) functions will be replaced be hybridSimulation's own internal function. If set to null, the process will be skipped. If *force* is not specified, returns the current force object.
|
||||||
|
|
||||||
<a name="hybrid_sampleIterations" href="#hybrid_sampleIterations">#</a> *hybrid*.**sampleIterations**([*iterations*])
|
<a name="hybrid_sampleIterations" href="#hybrid_sampleIterations">#</a> *hybrid*.**sampleIterations**([*iterations*])
|
||||||
|
|
||||||
|
|||||||
@@ -200,7 +200,11 @@ function ticked() {
|
|||||||
.attr("cy", function (d) {
|
.attr("cy", function (d) {
|
||||||
return d.y*MULTIPLIER;
|
return d.y*MULTIPLIER;
|
||||||
});
|
});
|
||||||
}
|
}/*
|
||||||
|
if(alreadyRanIterations%10 != 1) stresses.push("");
|
||||||
|
else stresses.push(d3.calculateStress(nodes, function (n, m) {
|
||||||
|
return distanceFunction(n, m, props, norm);
|
||||||
|
}));*/
|
||||||
// Emit the distribution data to allow the drawing of the bar graph
|
// Emit the distribution data to allow the drawing of the bar graph
|
||||||
if (springForce) {
|
if (springForce) {
|
||||||
intercom.emit("passedData", simulation.force(forceName).distributionData());
|
intercom.emit("passedData", simulation.force(forceName).distributionData());
|
||||||
@@ -214,7 +218,7 @@ function ended() {
|
|||||||
simulation.stop();
|
simulation.stop();
|
||||||
simulation.force(forceName, null);
|
simulation.force(forceName, null);
|
||||||
console.log("ended");
|
console.log("ended");
|
||||||
if (rendering !== true) { // Never drawn anything before? Now it's time.
|
//if (rendering !== true) { // Never drawn anything before? Now it's time.
|
||||||
node
|
node
|
||||||
.attr("cx", function (d) {
|
.attr("cx", function (d) {
|
||||||
return d.x*MULTIPLIER;
|
return d.x*MULTIPLIER;
|
||||||
@@ -222,7 +226,7 @@ function ended() {
|
|||||||
.attr("cy", function (d) {
|
.attr("cy", function (d) {
|
||||||
return d.y*MULTIPLIER;
|
return d.y*MULTIPLIER;
|
||||||
});
|
});
|
||||||
}
|
//}
|
||||||
|
|
||||||
if (p1 !== 0) {
|
if (p1 !== 0) {
|
||||||
// Performance time measurement
|
// Performance time measurement
|
||||||
@@ -236,6 +240,9 @@ function ended() {
|
|||||||
p1 = 0;
|
p1 = 0;
|
||||||
p2 = 0;
|
p2 = 0;
|
||||||
}
|
}
|
||||||
|
console.log("Post stress", d3.calculateStress(nodes, function (n, m) {
|
||||||
|
return distanceFunction(n, m, props, norm);
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
function brushEnded() {
|
function brushEnded() {
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ function startHybridSimulation() {
|
|||||||
let forceSample = d3.forceNeighbourSampling()
|
let forceSample = d3.forceNeighbourSampling()
|
||||||
.neighbourSize(NEIGHBOUR_SIZE)
|
.neighbourSize(NEIGHBOUR_SIZE)
|
||||||
.sampleSize(SAMPLE_SIZE)
|
.sampleSize(SAMPLE_SIZE)
|
||||||
.stableVelocity(0)
|
.stableVelocity(0.43)
|
||||||
.distance(distance)
|
.distance(distance)
|
||||||
|
|
||||||
let forceFull = d3.forceNeighbourSampling()
|
let forceFull = d3.forceNeighbourSampling()
|
||||||
.neighbourSize(FULL_NEIGHBOUR_SIZE)
|
.neighbourSize(FULL_NEIGHBOUR_SIZE)
|
||||||
.sampleSize(FULL_SAMPLE_SIZE)
|
.sampleSize(FULL_SAMPLE_SIZE)
|
||||||
|
.stableVelocity(0.6)
|
||||||
.distance(distance)
|
.distance(distance)
|
||||||
|
|
||||||
let hybridSimulation = d3.hybridSimulation(simulation, forceSample, forceFull)
|
let hybridSimulation = d3.hybridSimulation(simulation, forceSample, forceFull)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function startLinkSimulation() {
|
|||||||
.distance(function (n, m) {
|
.distance(function (n, m) {
|
||||||
return distanceFunction(n, m, props, norm);
|
return distanceFunction(n, m, props, norm);
|
||||||
})
|
})
|
||||||
.stableVelocity(0.000001) //TODO
|
.stableVelocity(0) //TODO
|
||||||
.onStableVelo(ended);
|
.onStableVelo(ended);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ export default function (sim, forceS, forceF) {
|
|||||||
initAlready = false,
|
initAlready = false,
|
||||||
nodes,
|
nodes,
|
||||||
alreadyRanIterations,
|
alreadyRanIterations,
|
||||||
hybrid;
|
hybrid,
|
||||||
|
p0 = performance.now(), p1, p2, p3;
|
||||||
|
|
||||||
if(simulation != undefined) initSimulation();
|
if(simulation != undefined) initSimulation();
|
||||||
if(forceS != undefined || forceF != undefined) initForces();
|
if(forceS != undefined || forceF != undefined) initForces();
|
||||||
@@ -63,6 +64,10 @@ export default function (sim, forceS, forceF) {
|
|||||||
forceSample.onStableVelo(sampleEnded);
|
forceSample.onStableVelo(sampleEnded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (forceFull.onStableVelo) {
|
||||||
|
forceFull.onStableVelo(fullEnded);
|
||||||
|
}
|
||||||
|
|
||||||
// Set default value for interpDistanceFn if not been specified yet
|
// Set default value for interpDistanceFn if not been specified yet
|
||||||
if(interpDistanceFn === undefined) {
|
if(interpDistanceFn === undefined) {
|
||||||
if(forceFull.distance == 'function')
|
if(forceFull.distance == 'function')
|
||||||
@@ -96,14 +101,25 @@ export default function (sim, forceS, forceF) {
|
|||||||
function fullTick() {
|
function fullTick() {
|
||||||
event.call("fullTick");
|
event.call("fullTick");
|
||||||
if(++alreadyRanIterations >= FULL_ITERATIONS){
|
if(++alreadyRanIterations >= FULL_ITERATIONS){
|
||||||
simulation.stop();
|
fullEnded();
|
||||||
initAlready = false;
|
|
||||||
simulation.force("Full force", null);
|
|
||||||
event.call("end");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fullEnded() {
|
||||||
|
p3 = performance.now();
|
||||||
|
simulation.stop();
|
||||||
|
initAlready = false;
|
||||||
|
simulation.force("Full force", null);
|
||||||
|
console.log("Phase 1 takes", p1-p0);
|
||||||
|
console.log("Phase 2 takes", p2-p1);
|
||||||
|
console.log("Phase 3 takes", p3-p2);
|
||||||
|
console.log("Total", p3-p0);
|
||||||
|
console.log("Phase 3 iterations", alreadyRanIterations);
|
||||||
|
event.call("end");
|
||||||
|
}
|
||||||
|
|
||||||
function sampleEnded() {
|
function sampleEnded() {
|
||||||
|
p1 = performance.now();
|
||||||
simulation.stop();
|
simulation.stop();
|
||||||
simulation.force("Sample force", null);
|
simulation.force("Sample force", null);
|
||||||
// Reset velocity of all nodes
|
// Reset velocity of all nodes
|
||||||
@@ -118,6 +134,7 @@ export default function (sim, forceS, forceF) {
|
|||||||
} else {
|
} else {
|
||||||
interpBruteForce(sample, remainder, interpDistanceFn, INTERP_FINE_ITS);
|
interpBruteForce(sample, remainder, interpDistanceFn, INTERP_FINE_ITS);
|
||||||
}
|
}
|
||||||
|
p2 = performance.now();
|
||||||
|
|
||||||
event.call("fullTick");
|
event.call("fullTick");
|
||||||
alreadyRanIterations = 0;
|
alreadyRanIterations = 0;
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt
|
|||||||
let sets = takeSampleFrom(sampleSet, numPivots);
|
let sets = takeSampleFrom(sampleSet, numPivots);
|
||||||
let pivots = sets.sample;
|
let pivots = sets.sample;
|
||||||
let nonPivotSamples = sets.remainder;
|
let nonPivotSamples = sets.remainder;
|
||||||
let correct = 0, wrong = 0, percentsOff = [];
|
|
||||||
|
|
||||||
let pivotsBuckets = []; // [ For each Pivot:[For each bucket:[each point in bucket]] ]
|
let pivotsBuckets = []; // [ For each Pivot:[For each bucket:[each point in bucket]] ]
|
||||||
for (let i = 0; i < numPivots; i++) {
|
for (let i = 0; i < numPivots; i++) {
|
||||||
@@ -131,45 +130,6 @@ export default function(sampleSet, remainderSet, numPivots, distanceFn, endingIt
|
|||||||
if (sampleSubsetDistanceCache[k] === undefined)
|
if (sampleSubsetDistanceCache[k] === undefined)
|
||||||
sampleSubsetDistanceCache[k] = distanceFn(node, sampleSubset[k]);
|
sampleSubsetDistanceCache[k] = distanceFn(node, sampleSubset[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let nearestSample, nearestMinDist, sample, dist;
|
|
||||||
for (let j = sampleSet.length-1; j>=0; j--) {
|
|
||||||
sample = sampleSet[j];
|
|
||||||
dist = distanceFn(node, sample);
|
|
||||||
if (nearestSample === undefined || dist < nearestMinDist) {
|
|
||||||
nearestMinDist = dist;
|
|
||||||
nearestSample = sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(minDist-nearestMinDist == 0) correct++;
|
|
||||||
else {
|
|
||||||
wrong++;
|
|
||||||
if(nearestMinDist!=0)percentsOff.push(minDist/nearestMinDist)
|
|
||||||
}
|
|
||||||
|
|
||||||
placeNearToNearestNeighbour(node, nearSample, minDist, sampleSubset, sampleSubsetDistanceCache, endingIts);
|
placeNearToNearestNeighbour(node, nearSample, minDist, sampleSubset, sampleSubsetDistanceCache, endingIts);
|
||||||
}
|
}
|
||||||
console.log("Correct", correct);
|
|
||||||
console.log("Wrong", wrong);
|
|
||||||
console.log("Correct percent", 100*correct/(correct+wrong));
|
|
||||||
StandardDeviation(percentsOff)
|
|
||||||
}
|
|
||||||
|
|
||||||
function StandardDeviation(numbersArr) {
|
|
||||||
//--CALCULATE AVAREGE--
|
|
||||||
var total = 0;
|
|
||||||
for(var key in numbersArr)
|
|
||||||
total += numbersArr[key];
|
|
||||||
var meanVal = total / numbersArr.length;
|
|
||||||
console.log("Average percent off", meanVal);
|
|
||||||
//--CALCULATE AVAREGE--
|
|
||||||
|
|
||||||
//--CALCULATE STANDARD DEVIATION--
|
|
||||||
var SDprep = 0;
|
|
||||||
for(var key in numbersArr)
|
|
||||||
SDprep += Math.pow((parseFloat(numbersArr[key]) - meanVal),2);
|
|
||||||
var SDresult = Math.sqrt(SDprep/numbersArr.length);
|
|
||||||
//--CALCULATE STANDARD DEVIATION--
|
|
||||||
console.log("SD percent off", SDresult);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export default function() {
|
|||||||
node = nodes[i];
|
node = nodes[i];
|
||||||
velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy));
|
velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy));
|
||||||
}
|
}
|
||||||
velocityDiff /= n*(n-1);
|
velocityDiff /= n;
|
||||||
latestVelocityDiff = velocityDiff;
|
latestVelocityDiff = velocityDiff;
|
||||||
|
|
||||||
if(velocityDiff<stableVelocity){
|
if(velocityDiff<stableVelocity){
|
||||||
|
|||||||
@@ -60,12 +60,13 @@ export default function () {
|
|||||||
node = nodes[i];
|
node = nodes[i];
|
||||||
velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy));
|
velocityDiff += Math.abs(Math.hypot(node.vx-node.oldvx, node.vy-node.oldvy));
|
||||||
}
|
}
|
||||||
velocityDiff /= n*(neighbourSize+sampleSize);
|
velocityDiff /= n;
|
||||||
latestVelocityDiff = velocityDiff;
|
latestVelocityDiff = velocityDiff;
|
||||||
|
|
||||||
if(velocityDiff<stableVelocity){
|
if(velocityDiff<stableVelocity){
|
||||||
stableVeloHandler();
|
stableVeloHandler();
|
||||||
}
|
}
|
||||||
|
else console.log(velocityDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user