|
@@ -114,6 +114,9 @@ const state = {
|
|
|
};
|
|
|
|
|
|
// Metrics
|
|
|
+const getBestKMean = (stats, q) => argMin(stats.kMeans.map((z, i) => vectorSqDist(z.vector, q.vector) / stats.kWeights[i]));
|
|
|
+const getWorstKMean = (stats, q) => argMax(stats.kMeans.map((z, i) => vectorSqDist(z.vector, q.vector) / stats.kWeights[i]));
|
|
|
+
|
|
|
const summarySelectors = [
|
|
|
// true mean
|
|
|
stats => [stats.trueMean, 1],
|
|
@@ -123,12 +126,12 @@ const summarySelectors = [
|
|
|
stats => [stats.kMeans[stats.smallestCluster], stats.kWeights[stats.smallestCluster]],
|
|
|
// best fit cluster
|
|
|
(stats, q) => {
|
|
|
- const best = argMin(stats.kMeans.map((z, i) => vectorSqDist(z.vector, q.vector) / stats.kWeights[i]));
|
|
|
+ const best = getBestKMean(stats, q);
|
|
|
return [stats.kMeans[best], stats.kWeights[best]];
|
|
|
},
|
|
|
// worst fit cluster
|
|
|
(stats, q) => {
|
|
|
- const worst = argMax(stats.kMeans.map((z, i) => vectorSqDist(z.vector, q.vector) / stats.kWeights[i]));
|
|
|
+ const worst = getWorstKMean(stats, q);
|
|
|
return [stats.kMeans[worst], stats.kWeights[worst]];
|
|
|
},
|
|
|
];
|
|
@@ -393,7 +396,7 @@ const onColorChanged = skipScore => {
|
|
|
if (readColor) {
|
|
|
state.targetColor = readColor;
|
|
|
|
|
|
- renderQVec(state.targetColor.jabData.vector.map(c => c.toFixed(2)), getQJABDisplay(), "Jab");
|
|
|
+ renderQVec(state.targetColor.jabData.vector.map(c => c.toFixed(3)), getQJABDisplay(), "Jab");
|
|
|
renderQVec(state.targetColor.rgbData.vector.map(c => c.toFixed()), getQRGBDisplay(), "RGB");
|
|
|
|
|
|
const textColor = getContrastingTextColor(state.targetColor.rgbData.vector);
|