currentObject = {
function calculateMean(data) {
var arr = [];
const l = data.length;
for (var i = 0; i < l; ++i) {
const temp = Object.values(data[i]);
arr[i] = d3.mean(temp);
}
return arr;
}
function calculateStandardDeviation(data) {
var arr = [];
const l = data.length;
for (var i = 0; i < l; ++i) {
const dP = Object.values(data[i]),
mean = d3.mean(dP);
arr[i] = Math.sqrt(d3.sum(dP.map((d) => (d - mean) ** 2)) / dP.length);
}
return arr;
}
function calculateSkewness(data) {
var arr = [];
const l = data.length;
const means = calculateMean(data);
const sDs = calculateStandardDeviation(data);
for (var i = 0; i < l; ++i) {
const dP = Object.values(data[i]);
arr[i] =
d3.sum(dP.map((d) => (d - means[i]) ** 3 / dP.length)) / sDs[i] ** 3;
}
return arr;
}
function calculateKurtosis(data) {
var arr = [];
const l = data.length;
const means = calculateMean(data);
const sDs = calculateStandardDeviation(data);
for (var i = 0; i < l; ++i) {
const dP = Object.values(data[i]);
arr[i] =
d3.sum(dP.map((d) => (d - means[i]) ** 4 / dP.length)) / sDs[i] ** 4;
}
return arr;
}
// Geometric parameters:
function calculateLength(d) {
d = Object.values(d);
var size = d.length;
var l = {};
for (var i = 0; i < size; ++i) {
l[i] = Math.sqrt(
(d[i] - d[(i + 1) % size]) ** 2 +
(d[(i + 1) % size] - d[(i + 2) % size]) ** 2
);
}
return l;
}
function calculateDistance(v1, v2) {
return Math.sqrt((v2.x - v1.x) ** 2 + (v2.y - v1.y) ** 2);
}
function calculateBoundingSphere(d) {
d = Object.values(d);
var s = d.length;
const geometry = new THREE.Geometry();
for (var j = 0; j < s; ++j) {
var temp = new THREE.Vector3(d[j], d[(j + 1) % s], 0);
geometry.vertices.push(temp);
}
geometry.computeBoundingSphere();
return geometry.boundingSphere;
}
function calculateArea(d) {
var sum = 0;
const l = d.length;
for (var i = 0; i < l; ++i) {
sum += d[i].x * d[(i + 1) % l].y;
sum -= d[i].y * d[(i + 1) % l].x;
}
return 0.5 * Math.abs(sum);
}
function calculateCircumference(d) {
var sum = 0;
const l = d.length;
for (var i = 0; i < l; ++i) {
sum += Math.sqrt(
(d[(i + 1) % l].x - d[i].x) ** 2 + (d[(i + 1) % l].y - d[i].y) ** 2
);
}
return sum;
}
function calculateEdgeLengths(d) {
const arr = [];
const l = d.length;
for (var i = 0; i < l; ++i) {
arr.push(
Math.sqrt(
(d[(i + 1) % l].x - d[i].x) ** 2 + (d[(i + 1) % l].y - d[i].y) ** 2
)
);
}
return arr;
}
function calculateAngles(d) {
var angles = [];
for (var i = 0; i < d.length; ++i) {
const v1x = d[(i - 1 + d.length) % d.length].x - d[i].x;
const v1y = d[(i - 1 + d.length) % d.length].y - d[i].y;
const v2x = d[(i + 1) % d.length].x - d[i].x;
const v2y = d[(i + 1) % d.length].y - d[i].y;
const angle =
((Math.atan2(v2y, v2x) - Math.atan2(v1y, v1x)) / Math.PI) * 180;
angle > 180
? angles.push(angle - 360)
: angle < -180
? angles.push(angle + 360)
: angles.push(parseFloat(angle));
}
return angles;
}
function calculateAbsoluteAngles(d) {
var angles = [];
for (var i = 0; i < d.length; ++i) {
const v1x = d[(i - 1 + d.length) % d.length].x - d[i].x;
const v1y = d[(i - 1 + d.length) % d.length].y - d[i].y;
const v2x = d[(i + 1) % d.length].x - d[i].x;
const v2y = d[(i + 1) % d.length].y - d[i].y;
const angle =
((Math.atan2(v2y, v2x) - Math.atan2(v1y, v1x)) / Math.PI) * 180;
angle > 0 ? angles.push(angle) : angles.push(angle + 360);
}
return angles;
}
// Dataset properties:
var object = {};
const selectedDataset = customDataset ? customObject : datasets[choice];
var raw = selectedDataset.data;
// Extract Name Column and clean dataset:
const colorMapping = raw.map((d) => d[selectedDataset.nameColumn]);
const colorCategories = [...new Set(colorMapping)];
const colorScale = d3.scaleOrdinal(colorCategories, colorValues);
const dataCategories = raw.columns.filter(
(d) => d != selectedDataset.nameColumn
);
const dataset = raw.map((d) => {
var b = {};
var incomplete = false;
for (var i = 0; i < dataCategories.length; ++i) {
b[dataCategories[i]] = d[dataCategories[i]];
if (d[dataCategories[i]] == null) {
b[dataCategories[i]] = 0;
}
}
return b;
});
dataset.columns = dataCategories;
const sideLengths = dataset.map((d) => calculateLength(d));
const minMaxAvg = dataset.map((d) => {
var min = Number.MAX_VALUE;
var max = -Number.MAX_VALUE;
var sum = 0;
for (var de in d) {
d[de] > max ? (max = d[de]) : "foo";
d[de] < min ? (min = d[de]) : "foo";
sum += d[de];
}
return { min: min, max: max, avg: sum / Object.keys(d).length };
});
const dimScales = new Map(
Array.from(dataCategories, (key) => [
key,
d3.scaleLinear(
d3.extent(dataset, (d) => d[key]),
[0, 1]
)
])
);
const ABCDpairs = dataset.map((d) => {
d = Object.values(d);
var s = d.length;
var pairArray = [];
for (var i = 0; i < s; i = i + 2) {
pairArray.push({ x: d[i], y: d[(i + 1) % s] });
}
return pairArray;
});
const ABCDavg = ABCDpairs.map((d) => ({
x: d3.sum(d.map((b) => b.x)) / d.length,
y: d3.sum(d.map((b) => b.y)) / d.length
}));
const zero = 0;
const fullExt = d3.extent(dataset.flatMap((d) => Object.values(d)));
var fullScale = d3.scaleLinear(fullExt, [zero, 1]);
const ABCDxExtent = d3.extent(
dataset.flatMap((d) => Object.values(d).filter((b, i) => i % 2 == 0))
);
const ABCDyExtent = d3.extent(
dataset.flatMap((d) =>
Object.values(d).filter((b, i) =>
Object.values(d).length % 2 == 1 ? i == 0 || i % 2 == 1 : i % 2 == 1
)
)
);
var ABCDscaleX = d3.scaleLinear(ABCDxExtent, [zero, 1]);
var ABCDscaleY = d3.scaleLinear(ABCDyExtent, [zero, 1]);
if (scaleLog && fullExt[1] > 0) {
fullScale = d3
.scaleLog([fullExt[0] < logT ? logT : fullExt[0], fullExt[1]], [zero, 1])
.clamp(logT);
ABCDscaleX = d3
.scaleLog(
[ABCDxExtent[0] < logT ? logT : ABCDxExtent[0], ABCDxExtent[1]],
[zero, 1]
)
.clamp(logT);
ABCDscaleY = d3
.scaleLog(
[ABCDyExtent[0] < logT ? logT : ABCDyExtent[0], ABCDyExtent[1]],
[zero, 1]
)
.clamp(logT);
}
const ABCDpairsDimensionNormalized = dataset.map((d) => {
d = Object.values(d);
var s = d.length;
var pairArray = [];
for (var i = 0; i < s; i = i + 2) {
pairArray.push({
x: dimScales.get(dataCategories[i])(d[i]),
y: dimScales.get(dataCategories[(i + 1) % s])(d[(i + 1) % s])
});
}
return pairArray;
});
const ABCDpairsDatasetNormalized = dataset.map((d) => {
d = Object.values(d);
var s = d.length;
var pairArray = [];
for (var i = 0; i < s; i = i + 2) {
pairArray.push({ x: ABCDscaleX(d[i]), y: ABCDscaleY(d[(i + 1) % s]) });
}
return pairArray;
});
const ABBCpairsDimensionNormalized = dataset.map((d) => {
d = Object.values(d);
var s = d.length;
var pairArray = [];
for (var i = 0; i < s; ++i) {
pairArray.push({
x: dimScales.get(dataCategories[i])(d[i]),
y: dimScales.get(dataCategories[(i + 1) % s])(d[(i + 1) % s])
});
}
return pairArray;
});
const ABBCpairsDatasetNormalized = dataset.map((d) => {
d = Object.values(d);
var s = d.length;
var pairArray = [];
for (var i = 0; i < s; ++i) {
pairArray.push({ x: fullScale(d[i]), y: fullScale(d[(i + 1) % s]) });
}
return pairArray;
});
const boundingSphere = dataset.map((d) => calculateBoundingSphere(d));
const lrAnglesABBCDim = ABBCpairsDimensionNormalized.map((d) =>
calculateAngles(d)
);
const LRABBCDim = lrAnglesABBCDim.map((d) => {
var LR = { left: 0, right: 0 };
for (var i = 0; i < d.length; ++i) {
d[i] < 0 ? (LR.left += Math.abs(d[i])) : (LR.right += Math.abs(d[i]));
}
return LR;
});
const lrAnglesABBCData = ABBCpairsDatasetNormalized.map((d) =>
calculateAngles(d)
);
const LRABBCData = lrAnglesABBCData.map((d) => {
var LR = { left: 0, right: 0 };
for (var i = 0; i < d.length; ++i) {
d[i] < 0 ? (LR.left += Math.abs(d[i])) : (LR.right += Math.abs(d[i]));
}
return LR;
});
const lrAnglesABCDDim = ABCDpairsDimensionNormalized.map((d) =>
calculateAngles(d)
);
const LRABCDDim = lrAnglesABCDDim.map((d) => {
var LR = { left: 0, right: 0 };
for (var i = 0; i < d.length; ++i) {
d[i] < 0 ? (LR.left += Math.abs(d[i])) : (LR.right += Math.abs(d[i]));
}
return LR;
});
const lrAnglesABCDData = ABCDpairsDatasetNormalized.map((d) =>
calculateAngles(d)
);
const LRABCDData = lrAnglesABCDData.map((d) => {
var LR = { left: 0, right: 0 };
for (var i = 0; i < d.length; ++i) {
d[i] < 0 ? (LR.left += Math.abs(d[i])) : (LR.right += Math.abs(d[i]));
}
return LR;
});
selectedDataset.customValues = customValues.map((d) => d.map((b) => b.value));
selectedDataset.clusterDistributionValues = clusterDistributionValues;
selectedDataset.distributionParameters = distrparameters.map((d) =>
d.map((b) => b.value).filter((_, i) => i != 0)
);
selectedDataset.creationType = customCreationType;
selectedDataset.selectedSamples = 0;
selectedDataset.customLength = datasetLength;
selectedDataset.customDim = datasetDim;
selectedDataset.customClustercount = clusterCount;
selectedDataset.lineThickness = lineThickness;
selectedDataset.dotRadius = dotRadius;
selectedDataset.glyphThickness = glyphThickness;
selectedDataset.pointSize = pointSize;
selectedDataset.axisWidth = axisWidth;
selectedDataset.innerTickSize = innerTickSize;
selectedDataset.xDistance = xDistance;
selectedDataset.yDistance = yDistance;
selectedDataset.marginleft = margin.left;
selectedDataset.marginright = margin.right;
selectedDataset.margintop = margin.top;
selectedDataset.marginbottom = margin.bottom;
object.export = selectedDataset;
// Polygon Data:
object.ABBCdimensionPairs = ABBCpairsDimensionNormalized;
object.ABBCdatasetPairs = ABBCpairsDatasetNormalized;
object.ABCDdimensionPairs = ABCDpairsDimensionNormalized;
object.ABCDdatasetPairs = ABCDpairsDatasetNormalized;
// Placement Data:
object.angles = ABBCpairsDimensionNormalized.map((d) =>
calculateAbsoluteAngles(d)
);
object.leftanglesABBCDim = LRABBCDim.map((d) => d.left);
object.rightanglesABBCDim = LRABBCDim.map((d) => d.right);
object.leftanglesABBCData = LRABBCData.map((d) => d.left);
object.rightanglesABBCData = LRABBCData.map((d) => d.right);
object.leftanglesABCDDim = LRABCDDim.map((d) => d.left);
object.rightanglesABCDDim = LRABCDDim.map((d) => d.right);
object.leftanglesABCDData = LRABCDData.map((d) => d.left);
object.rightanglesABCDData = LRABCDData.map((d) => d.right);
object.areaABBCDim = ABBCpairsDimensionNormalized.map((d) =>
calculateArea(d)
);
object.areaABBCData = ABBCpairsDatasetNormalized.map((d) => calculateArea(d));
object.areaABCDDim = ABCDpairsDimensionNormalized.map((d) =>
calculateArea(d)
);
//object.areaABCDData = ABCDpairsDatasetNormalized.map((d) => calculateArea(d));
object.areaABCDData = ABCDpairsDatasetNormalized.map(
(d) => Math.round(calculateArea(d) * 10000) / 10000
);
object.circumferenceABBCDim = ABBCpairsDimensionNormalized.map((d) =>
calculateCircumference(d)
);
object.circumferenceABBCData = ABBCpairsDatasetNormalized.map((d) =>
calculateCircumference(d)
);
object.circumferenceABCDDim = ABCDpairsDimensionNormalized.map((d) =>
calculateCircumference(d)
);
object.circumferenceABCDData = ABCDpairsDatasetNormalized.map((d) =>
calculateCircumference(d)
);
object.sidelengthsABBCDim = ABBCpairsDimensionNormalized.map((d) =>
calculateEdgeLengths(d)
);
object.sidelengthsABBCData = ABBCpairsDatasetNormalized.map((d) =>
calculateEdgeLengths(d)
);
object.sidelengthsABCDDim = ABCDpairsDimensionNormalized.map((d) =>
calculateEdgeLengths(d)
);
object.sidelengthsABCDData = ABCDpairsDatasetNormalized.map((d) =>
calculateEdgeLengths(d)
);
object.circumference = sideLengths.map((d) => {
d = Object.values(d);
return d3.sum(d);
});
object.sideLengths = sideLengths;
object.pcpScales = Array.from(dataCategories, (key) => [
key,
d3.scaleLinear(
d3.extent(dataset, (d) => d[key]),
[dim - margin.top, margin.bottom]
)
]);
if (scaleLog) {
object.pcpScales = Array.from(dataCategories, (key) => [
key,
d3
.scaleLog(
[
d3.extent(dataset, (d) => d[key])[0] < logT
? logT
: d3.extent(dataset, (d) => d[key])[0],
d3.extent(dataset, (d) => d[key])[1]
],
[dim - margin.top, margin.bottom]
)
.clamp(true)
]);
}
object.min = minMaxAvg.map((d) => d.min);
object.max = minMaxAvg.map((d) => d.max);
object.avg = minMaxAvg.map((d) => d.avg);
object.ABCDavgXDim = ABCDpairsDimensionNormalized.map((d) =>
d3.mean(d.map((b) => b.x))
);
object.ABCDavgYDim = ABCDpairsDimensionNormalized.map((d) =>
d3.mean(d.map((b) => b.y))
);
object.ABCDavgXData = ABCDpairsDatasetNormalized.map((d) =>
d3.mean(d.map((b) => b.x))
);
object.ABCDavgYData = ABCDpairsDatasetNormalized.map((d) =>
d3.mean(d.map((b) => b.y))
);
object.kurtosis = calculateKurtosis(dataset);
object.skewness = calculateSkewness(dataset);
object.standarddeviation = calculateStandardDeviation(dataset);
// General Data:
object.dataset = dataset;
object.colorMapping = colorMapping;
object.colorScale = colorScale;
return object;
}