UX Improvements

This commit is contained in:
Brennan Wilkes (Text Groove) 2026-02-02 21:50:08 -08:00
parent c3702b0ba2
commit f8896eb031
3 changed files with 80 additions and 14 deletions

View file

@ -3,6 +3,7 @@ import { parsePriceToNumber, keySkuForRow, displaySku } from "./sku.js";
import { loadIndex } from "./state.js";
import { inferGithubOwnerRepo, githubListCommits, githubFetchFileAtSha, fetchJson } from "./api.js";
import { loadSkuRules } from "./mapping.js";
import { storeColor, isWhite } from "./storeColors.js";
/* ---------------- Chart lifecycle ---------------- */
@ -665,12 +666,23 @@ export async function renderItem($app, skuInput) {
const span = (ySug.suggestedMax ?? 0) - (ySug.suggestedMin ?? 0);
const step = niceStepAtLeast(MIN_STEP, span, MAX_TICKS);
const datasets = series.map((s) => ({
label: s.label,
data: labels.map((d) => (s.points.has(d) ? s.points.get(d) : null)),
spanGaps: false,
tension: 0.15,
}));
const datasets = series.map((s) => {
const c = storeColor(s.label); // store label
return {
label: s.label,
data: labels.map((d) => (s.points.has(d) ? s.points.get(d) : null)),
spanGaps: false,
tension: 0.15,
borderColor: c,
backgroundColor: c,
pointBackgroundColor: c,
pointBorderColor: c,
borderWidth: isWhite(c) ? 2 : 1.5,
};
});
const ctx = $canvas.getContext("2d");
CHART = new Chart(ctx, {

View file

@ -5,6 +5,7 @@ import {
githubFetchFileAtSha,
githubListCommits,
} from "./api.js";
import { storeColor, isWhite } from "./storeColors.js";
let _chart = null;
@ -692,14 +693,23 @@ export async function renderStats($app) {
const canvas = document.getElementById("statsChart");
if (!canvas) return;
const datasets = stores.map((s) => ({
label: displayStoreName(s),
data: Array.isArray(seriesByStore[s])
? seriesByStore[s]
: labels.map(() => null),
spanGaps: false,
tension: 0.15,
}));
const datasets = stores.map((s) => {
const c = storeColor(s); // store key
return {
label: displayStoreName(s),
data: Array.isArray(seriesByStore[s]) ? seriesByStore[s] : labels.map(() => null),
spanGaps: false,
tension: 0.15,
borderColor: c,
backgroundColor: c,
pointBackgroundColor: c,
pointBorderColor: c,
borderWidth: isWhite(c) ? 2 : 1.5,
};
});
if (_chart) {
_chart.data.labels = labels;

44
viz/app/storeColors.js Normal file
View file

@ -0,0 +1,44 @@
function normalizeStoreId(s) {
return String(s || "")
.toLowerCase()
.replace(/[^a-z0-9]+/g, "");
}
const STORE_COLOR_OVERRIDES = {
strath: "#76B7FF",
bsw: "#E9DF7A",
kensingtonwinemarket: "#F2C200",
vessel: "#FFFFFF",
gullliquor: "#6B0F1A",
kegncork: "#111111",
legacyliquor: "#7B4A12",
vintagespirits: "#E34A2C",
// aliases
gull: "#6B0F1A",
legacy: "#7B4A12",
vintage: "#E34A2C",
};
function hashToHue(str) {
let h = 2166136261;
for (let i = 0; i < str.length; i++) {
h ^= str.charCodeAt(i);
h = Math.imul(h, 16777619);
}
return (h >>> 0) % 360;
}
export function storeColor(storeKeyOrLabel) {
const id = normalizeStoreId(storeKeyOrLabel);
const forced = STORE_COLOR_OVERRIDES[id];
if (forced) return forced;
const hue = hashToHue(id || "unknown");
return `hsl(${hue} 65% 55%)`;
}
export function isWhite(color) {
return String(color).toUpperCase() === "#FFFFFF";
}