/
45case
/
ptable
Обзор
Документация
Войти
/
45case
/
ptable
Код
Запросы
3
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
dev
src/entities/table/model/categoryLegend.ts
123 строки
4 KB
Olya
feat: клик по легенде категорий/фаз и корректная окраска по температуре
17 июл 2026, 11:22
17 июл 2026, 11:22
4fc2553
Код
Авторство
О чём код?
import type { ElementCategory } from "../../element/model/category"; export type CategoryLegendGroupKey = "metals" | "metalloids" | "nonmetals"; export type CategoryLegendItem = { category: ElementCategory; label: string; highlightCategories?: readonly ElementCategory[]; }; export type CategoryLegendGroup = { key: CategoryLegendGroupKey; label: string; items: readonly CategoryLegendItem[]; }; export const categoryLegendGroups: readonly CategoryLegendGroup[] = [ { key: "metals", label: "Металлы", items: [ { category: "alkali-metal", label: "Щелочные металлы" }, { category: "alkaline-earth-metal", label: "Щелочноземельные металлы" }, { category: "lanthanide", label: "Лантаноиды" }, { category: "actinide", label: "Актиноиды" }, { category: "transition-metal", label: "Переходные металлы" }, { category: "post-transition-metal", label: "Постпереходные металлы" }, ], }, { key: "metalloids", label: "Полуметаллы", items: [{ category: "metalloid", label: "Полуметаллы" }], }, { key: "nonmetals", label: "Неметаллы", items: [ { category: "nonmetal", label: "Неметаллы", highlightCategories: ["nonmetal", "halogen"], }, { category: "noble-gas", label: "Благородные газы" }, ], }, ]; export const categoryLegendItems: readonly CategoryLegendItem[] = categoryLegendGroups.flatMap( (group) => group.items, ); export type CategoryLegendHover = | { kind: "category"; category: ElementCategory } | { kind: "group"; group: CategoryLegendGroupKey }; const legendItemCategoriesByCategory = new Map<ElementCategory, readonly ElementCategory[]>( categoryLegendItems.map((item) => [ item.category, item.highlightCategories ?? [item.category], ]), ); const categoriesByGroup = new Map<CategoryLegendGroupKey, readonly ElementCategory[]>( categoryLegendGroups.map((group) => [ group.key, group.items.flatMap((item) => item.highlightCategories ?? [item.category]), ]), ); export function getLegendItemCategories(category: ElementCategory): readonly ElementCategory[] { return legendItemCategoriesByCategory.get(category) ?? [category]; } export function getGroupCategories(group: CategoryLegendGroupKey): readonly ElementCategory[] { return categoriesByGroup.get(group) ?? []; } export function isElementCategoryHighlighted( elementCategory: ElementCategory, hover: CategoryLegendHover | null, ): boolean { if (hover == null) { return false; } if (hover.kind === "category") { return getLegendItemCategories(hover.category).includes(elementCategory); } return getGroupCategories(hover.group).includes(elementCategory); } export function isCategoryLegendHoverActive(hover: CategoryLegendHover | null): boolean { return hover != null; } export function isElementCategorySelected( elementCategory: ElementCategory, selectedCategories: ReadonlySet<ElementCategory>, selectedGroups: ReadonlySet<CategoryLegendGroupKey>, ): boolean { for (const category of selectedCategories) { if (getLegendItemCategories(category).includes(elementCategory)) { return true; } } for (const group of selectedGroups) { if (getGroupCategories(group).includes(elementCategory)) { return true; } } return false; } export function hasCategoryLegendSelection( selectedCategories: ReadonlySet<ElementCategory>, selectedGroups: ReadonlySet<CategoryLegendGroupKey>, ): boolean { return selectedCategories.size > 0 || selectedGroups.size > 0; }