const selectors = { get sortControl() { return document.forms.sortControl.elements; }, get clusterControl() { return document.forms.clusterControl.elements; }, get colorSpace() { return selectors.colorSpace.value; }, }; const onMetricChange = (elements) => { elements.sortOrderLabel.value = elements.sortOrder.checked ? "Maximizing" : "Minimizing"; const kind = elements.metricKind.value; elements.whole.disabled = kind !== "whole"; elements.mean.disabled = kind !== "mean"; elements.statistic.disabled = kind !== "statistic"; elements.sortMetric.value = elements[kind].value; updateSort(); showResults(selectors.sortControl.resultsToDisplay.value); }; const onColorChange = (inputValue) => { console.log(inputValue); const colorInput = "#" + (inputValue?.replace("#", "") ?? "FFFFFF"); if (colorInput.length !== 7) { return; } const rgb = d3.color(colorInput); if (!rgb) { return; } const refomatted = rgb.formatHex(); selectors.sortControl.colorText.value = refomatted; selectors.sortControl.colorPicker.value = refomatted; // TODO last color saver // TODO bg + text color change updateScores(rgb); updateSort(); showResults(selectors.sortControl.resultsToDisplay.value); }; const calcScores = (data, target) => { const sigma = Math.sqrt( data.inertia - 2 * vectorDot(data.mu.vector, target.vector) + target.sqMag ); const theta = rad2deg * Math.acos(vectorDot(data.mu.unit, target.unit)); const rawPhi = Math.abs(data.mu.hue - target.hue); return { sigma, bigTheta: 1 - vectorDot(data.nu, target.unit), alpha: sigma * Math.pow(bigTheta, target.chroma + target.lightness), theta, phi: Math.min(rawPhi, 360 - rawPhi), delta: vectorMag(data.mu.vector.map((x, i) => x - target.vector[i])), manhattan: data.mu.vector .map((x, i) => Math.abs(x - target.vector[i])) .reduce((x, y) => x + y), ch: Math.max(...data.mu.vector.map((x, i) => Math.abs(x - target.vector[i]))), lightnessDiff: Math.abs(data.mu.lightness - target.lightness), inertia: data.inertia, variance: data.inertia - data.mu.sqMag, muNuAngle: data.muNuAngle, size: data.size, lightness: data.mu.lightness, chroma: data.mu.chroma, importance: data.importance, }; }; const currentScores = {}; const currentBestClusterIndices = {}; let sortedData = pokemonData; const updateScores = (rgb) => { const { J, a, b } = d3.jab(rgb); const targetJab = buildVectorData([J, a, b], jab2hue, jab2lit, jab2chroma, jab2hex); const targetRgb = buildVectorData( [rgb.r, rgb.g, rgb.b], rgb2hue, rgb2lit, rgb2chroma, rgb2hex ); pokemonData.forEach(({ name, jab, rgb }) => { currentScores[name] = { jab: { total: calcScores(jab.total, targetJab), clusters: jab.clusters.map((c) => calcScores(c, targetJab)), }, rgb: { total: calcScores(rgb.total, targetRgb), clusters: rgb.clusters.map((c) => calcScores(c, targetRgb)), }, }; currentBestClusterIndices[name] = { // TODO jab: 0, rgb: 0, }; }); }; const updateSort = () => { // TODO }; const showResults = (resultsToDisplay) => { // TODO }; window.onload = () => { const metricTemplate = document.getElementById("metric-form-template").content; selectors.sortControl.metric.appendChild(metricTemplate.cloneNode(true)); selectors.sortControl.metricKind.value = "whole"; selectors.sortControl.whole.value = "alpha"; onMetricChange(selectors.sortControl); selectors.clusterControl.metric.appendChild(metricTemplate.cloneNode(true)); selectors.clusterControl.sortOrder.checked = true; selectors.clusterControl.metricKind.value = "statistic"; selectors.clusterControl.statistic.value = "importance"; onMetricChange(selectors.clusterControl); };