Keep a deleted kind's colour, not just its name
A kind that is deleted keeps its tombstone so meals logged as it stay readable, and the chart recovered its name from there — but not its colour, falling back to grey. Grey is what "No kind" uses, so a deleted kind's food and unlabelled food drew as the same colour: two distinct series, indistinguishable in the stack and in the legend beneath it. The tombstone has the colorIndex all along, so reading the whole record rather than just the name fixes it. The check now pins the colour as well as the name, since the name alone was what let this through. Deleting a kind still leaves the meals alone — confirmed as the wanted behaviour. This only makes that behaviour legible.
This commit is contained in:
@@ -147,6 +147,7 @@ suite("what the sentence is allowed to say");
|
|||||||
"foodTrendMoves", "foodSeriesSentences", "foodSeriesFor"],
|
"foodTrendMoves", "foodSeriesSentences", "foodSeriesFor"],
|
||||||
stubs: {
|
stubs: {
|
||||||
liveFoodKinds: () => kinds,
|
liveFoodKinds: () => kinds,
|
||||||
|
loadFoodKinds: () => kinds,
|
||||||
foodKindNames: () => new Map(kinds.map(k => [k.id, k.name])),
|
foodKindNames: () => new Map(kinds.map(k => [k.id, k.name])),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -203,12 +204,16 @@ suite("what the sentence is allowed to say");
|
|||||||
names: ["NO_KIND", "FOOD_COLORS", "foodTrend", "foodSeriesFor"],
|
names: ["NO_KIND", "FOOD_COLORS", "foodTrend", "foodSeriesFor"],
|
||||||
stubs: {
|
stubs: {
|
||||||
liveFoodKinds: () => [],
|
liveFoodKinds: () => [],
|
||||||
foodKindNames: () => new Map([["gone", "Old recipe"]]),
|
// The tombstone: gone from the picker, still carrying name and colour.
|
||||||
|
loadFoodKinds: () => [{ id: "gone", name: "Old recipe", colorIndex: 2, deleted: true }],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const days = byKind([{ gone: 100 }, { gone: 110 }, { gone: 120 }, { gone: 130 }, { gone: 0 }]);
|
const days = byKind([{ gone: 100 }, { gone: 110 }, { gone: 120 }, { gone: 130 }, { gone: 0 }]);
|
||||||
eq(namesOnly.foodSeriesFor(days).map(s => s.name), ["Old recipe"],
|
const series = namesOnly.foodSeriesFor(days);
|
||||||
|
eq(series.map(s => s.name), ["Old recipe"],
|
||||||
"it keeps its name rather than vanishing or reading as 'No kind'");
|
"it keeps its name rather than vanishing or reading as 'No kind'");
|
||||||
|
eq(series[0].colorIndex, 2,
|
||||||
|
"…and its colour, which grey would confuse with the 'No kind' series");
|
||||||
}
|
}
|
||||||
|
|
||||||
suite("the caption stays bounded as kinds are added");
|
suite("the caption stays bounded as kinds are added");
|
||||||
|
|||||||
+11
-3
@@ -2068,7 +2068,9 @@
|
|||||||
// With no kinds defined this returns a single unnamed series, which is what
|
// With no kinds defined this returns a single unnamed series, which is what
|
||||||
// makes the whole feature invisible to anyone not using it.
|
// makes the whole feature invisible to anyone not using it.
|
||||||
function foodSeriesFor(days) {
|
function foodSeriesFor(days) {
|
||||||
const names = foodKindNames();
|
// Every kind ever, tombstones included — a deleted one keeps both its name
|
||||||
|
// and its colour, which is what lets its food stay identifiable below.
|
||||||
|
const all = new Map(loadFoodKinds().map(k => [k.id, k]));
|
||||||
const used = (id) => days.some(d => (d.gramsByKind?.[id] || 0) > 0);
|
const used = (id) => days.some(d => (d.gramsByKind?.[id] || 0) > 0);
|
||||||
const out = [];
|
const out = [];
|
||||||
for (const k of liveFoodKinds()) {
|
for (const k of liveFoodKinds()) {
|
||||||
@@ -2079,13 +2081,19 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Kinds deleted since, but still on meals in this window: their food is
|
// Kinds deleted since, but still on meals in this window: their food is
|
||||||
// real and has to appear somewhere, under the name the tombstone kept.
|
// real and has to appear somewhere, under the name and colour the tombstone
|
||||||
|
// kept. Falling back to grey here would be wrong twice over — it is also
|
||||||
|
// "No kind"'s colour, so the two series would be indistinguishable in both
|
||||||
|
// the stack and the legend.
|
||||||
for (const d of days) {
|
for (const d of days) {
|
||||||
for (const id of Object.keys(d.gramsByKind || {})) {
|
for (const id of Object.keys(d.gramsByKind || {})) {
|
||||||
if (id === NO_KIND || out.some(s => s.id === id)) continue;
|
if (id === NO_KIND || out.some(s => s.id === id)) continue;
|
||||||
if (!used(id)) continue;
|
if (!used(id)) continue;
|
||||||
|
const gone = all.get(id);
|
||||||
out.push({
|
out.push({
|
||||||
id, name: names.get(id) || "Deleted kind", colorIndex: null,
|
id,
|
||||||
|
name: gone?.name || "Deleted kind",
|
||||||
|
colorIndex: gone ? (gone.colorIndex ?? 0) : null,
|
||||||
of: (dd) => dd.gramsByKind?.[id] || 0,
|
of: (dd) => dd.gramsByKind?.[id] || 0,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user