/
45case
/
ptable
Обзор
Документация
Войти
/
45case
/
ptable
Код
Запросы
3
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
dev
src/entities/table/model/legend.ts
207 строк
6 KB
Olya
feat: клик по легенде категорий/фаз и корректная окраска по температуре
17 июл 2026, 11:22
17 июл 2026, 11:22
4fc2553
Код
Авторство
О чём код?
import type { ElementPhaseAtStp, ElementSeries, PeriodicElement, } from "../../element/model/elements"; import { getElementPropertyDefinition } from "../../element/model/properties"; import { celsiusToKelvin, getElementState } from "../../temperature"; type ToneSource = ElementSeries | Pick<PeriodicElement, "group" | "series">; export type LegendGroupKey = "metals" | "metalloids" | "nonmetals"; export type LegendFilter = | { kind: "series"; key: ElementSeries | "halogen" } | { kind: "group"; key: LegendGroupKey } | { kind: "phase"; key: ElementPhaseAtStp }; export type CategoryLegendItem = { key: string; label: string; tone: ToneSource; filter: LegendFilter; }; export type StateLegendItem = { key: ElementPhaseAtStp; label: string; sample: string; filter: LegendFilter; }; export type CategoryLegendGroup = { key: LegendGroupKey; label: string; filter: LegendFilter; items: readonly CategoryLegendItem[]; }; const seriesLabels = getElementPropertyDefinition("series").optionLabels ?? {}; const phaseLabels = getElementPropertyDefinition("phaseAtStp").optionLabels ?? {}; const categoryItems = { alkali: { key: "alkali-metal", label: seriesLabels["alkali-metal"] ?? "Щелочные", tone: "alkali-metal" as const, filter: { kind: "series", key: "alkali-metal" as const } as const, }, alkalineEarth: { key: "alkaline-earth-metal", label: "Щёлочноземельные", tone: "alkaline-earth-metal" as const, filter: { kind: "series", key: "alkaline-earth-metal" as const } as const, }, lanthanide: { key: "lanthanide", label: "Лантаноиды", tone: "lanthanide" as const, filter: { kind: "series", key: "lanthanide" as const } as const, }, actinide: { key: "actinide", label: "Актиноиды", tone: "actinide" as const, filter: { kind: "series", key: "actinide" as const } as const, }, transition: { key: "transition-metal", label: "Переходные", tone: "transition-metal" as const, filter: { kind: "series", key: "transition-metal" as const } as const, }, postTransition: { key: "post-transition-metal", label: "Постпереходные", tone: "post-transition-metal" as const, filter: { kind: "series", key: "post-transition-metal" as const } as const, }, metalloid: { key: "metalloid", label: "Металлоиды", tone: "metalloid" as const, filter: { kind: "series", key: "metalloid" as const } as const, }, nonmetal: { key: "nonmetal", label: "Неметаллы", tone: "nonmetal" as const, filter: { kind: "series", key: "nonmetal" as const } as const, }, halogen: { key: "halogen", label: "Галогены", tone: { series: "nonmetal", group: 17 } as const, filter: { kind: "series", key: "halogen" as const } as const, }, nobleGas: { key: "noble-gas", label: "Благородные газы", tone: "noble-gas" as const, filter: { kind: "series", key: "noble-gas" as const } as const, }, }; export const categoryLegendGroups: readonly CategoryLegendGroup[] = [ { key: "metals", label: "Металлы", filter: { kind: "group", key: "metals" }, items: [ categoryItems.alkali, categoryItems.alkalineEarth, categoryItems.lanthanide, categoryItems.actinide, categoryItems.transition, categoryItems.postTransition, ], }, { key: "metalloids", label: "Металлоиды", filter: { kind: "group", key: "metalloids" }, items: [categoryItems.metalloid], }, { key: "nonmetals", label: "Неметаллы", filter: { kind: "group", key: "nonmetals" }, items: [categoryItems.nonmetal, categoryItems.halogen, categoryItems.nobleGas], }, ]; export const stateLegendItems: readonly StateLegendItem[] = [ { key: "solid", label: "Твёрдое тело", sample: "C", filter: { kind: "phase", key: "solid" }, }, { key: "liquid", label: "Жидкость", sample: "Hg", filter: { kind: "phase", key: "liquid" }, }, { key: "gas", label: "Газ", sample: "H", filter: { kind: "phase", key: "gas" }, }, { key: "unknown", label: phaseLabels.unknown ?? "Неизвестный", sample: "Rf", filter: { kind: "phase", key: "unknown" }, }, ]; export function areLegendFiltersEqual(left: LegendFilter | null, right: LegendFilter | null) { if (left == null || right == null) { return left === right; } return left.kind === right.kind && left.key === right.key; } export function matchesLegendFilter( element: PeriodicElement, filter: LegendFilter, temperatureCelsius = 0, ) { if (filter.kind === "phase") { return getElementState(element, celsiusToKelvin(temperatureCelsius)) === filter.key; } if (filter.kind === "group") { if (filter.key === "metals") { return [ "alkali-metal", "alkaline-earth-metal", "lanthanide", "actinide", "transition-metal", "post-transition-metal", ].includes(element.category); } if (filter.key === "metalloids") { return element.category === "metalloid"; } return element.category === "nonmetal" || element.category === "noble-gas" || element.category === "halogen"; } if (filter.key === "halogen") { return element.category === "halogen"; } if (filter.key === "nonmetal") { return element.category === "nonmetal"; } return element.category === filter.key; } export const unstableIsotopeMassNote = "Для элементов, не имеющих стабильных изотопов, в скобках указывается масса изотопа с наибольшим периодом полураспада.";