/
45case
/
ptable
Обзор
Документация
Войти
/
45case
/
ptable
Код
Запросы
3
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
dev
src/entities/element/lib/formatHomeProperties.ts
338 строк
9 KB
Olya
Страница Электроны + сайдбар с характеритстиками (Степень окисления, Конфигурация, Развёрнутая, Уровни энергии, ВЗМО)
24 июл 2026, 11:54
24 июл 2026, 11:54
3cf1d48
Код
Авторство
О чём код?
/** Format number with Russian decimal comma. */ export function formatPropertyNumber( value: number | null | undefined, options?: { digits?: number; maxDigits?: number; scientificBelow?: number; suffix?: string; }, ): string { if (value == null || Number.isNaN(value)) { return "—"; } const digits = options?.digits; const maxDigits = options?.maxDigits ?? 4; const scientificBelow = options?.scientificBelow; const suffix = options?.suffix ? ` ${options.suffix}` : ""; if (scientificBelow != null && value !== 0 && Math.abs(value) < scientificBelow) { const scientific = value .toExponential(1) .replace(".", ",") .replace("e+", "E") .replace("e-", "E-"); return `${scientific}${suffix}`; } let text: string; if (digits != null) { text = value.toFixed(digits); } else if (Number.isInteger(value)) { text = String(value); } else { text = value.toFixed(maxDigits).replace(/\.?0+$/, ""); } text = text.replace(".", ","); return `${text}${suffix}`; } export function formatKelvinAsCelsius(valueK: number | null | undefined): string { return formatKelvinTemperature(valueK, "C"); } /** Ptable: eV = kJ/mol × 0.0103642688 */ export const KJ_MOL_TO_EV = 0.0103642688; /** Format molar energy (affinity / ionization) stored as kJ/mol. */ export function formatMolarEnergy( valueKJmol: number | null | undefined, unit: "kJ" | "eV" = "kJ", options?: { includeUnit?: boolean }, ): string { if (valueKJmol == null || Number.isNaN(valueKJmol)) { return "—"; } const includeUnit = options?.includeUnit !== false; if (unit === "eV") { return formatPropertyNumber(valueKJmol * KJ_MOL_TO_EV, { maxDigits: 3, suffix: includeUnit ? "eV" : undefined, }); } return formatPropertyNumber(valueKJmol, { maxDigits: 2, suffix: includeUnit ? "kJ/mol" : undefined, }); } /** Format electron affinity stored as kJ/mol. */ export function formatElectronAffinity( valueKJmol: number | null | undefined, unit: "kJ" | "eV" = "kJ", options?: { includeUnit?: boolean }, ): string { return formatMolarEnergy(valueKJmol, unit, options); } /** Ionization order options 1–30 (ptable). */ export const IONIZATION_ORDERS = Array.from({ length: 30 }, (_, index) => index + 1); /** Ptable radius kinds with Russian labels. */ export const ATOMIC_RADIUS_KIND_OPTIONS = [ { value: "calculated", label: "расчётный" }, { value: "empirical", label: "эмпирический" }, { value: "covalent", label: "ковалентный" }, { value: "vanderwaals", label: "ван-дер-Ваальсов" }, ] as const; /** Ptable hardness scales with Russian labels. */ export const HARDNESS_KIND_OPTIONS = [ { value: "brinell", label: "Бринелль" }, { value: "mohs", label: "Моос" }, { value: "vickers", label: "Виккерс" }, ] as const; /** Ptable modulus kinds with Russian labels. */ export const MODULUS_KIND_OPTIONS = [ { value: "bulk", label: "объёмный" }, { value: "shear", label: "сдвига" }, { value: "young", label: "Юнга" }, ] as const; /** Ptable density kinds with Russian labels. */ export const DENSITY_KIND_OPTIONS = [ { value: "stp", label: "н.у." }, { value: "liquid", label: "Жидкость" }, ] as const; /** Ptable conductivity kinds with Russian labels. */ export const CONDUCTIVITY_KIND_OPTIONS = [ { value: "thermal", label: "тепловая" }, { value: "electric", label: "электрическая" }, ] as const; /** Ptable heat kinds with Russian labels. */ export const HEAT_KIND_OPTIONS = [ { value: "specific", label: "удельная" }, { value: "vaporization", label: "парообразования" }, { value: "fusion", label: "плавления" }, ] as const; /** Ptable abundance environments with Russian labels. */ export const ABUNDANCE_KIND_OPTIONS = [ { value: "universe", label: "Вселенная" }, { value: "solar", label: "Солнце" }, { value: "meteor", label: "метеориты" }, { value: "crust", label: "кора" }, { value: "ocean", label: "океан" }, { value: "human", label: "человек" }, ] as const; /** Format abundance mass percent. */ export function formatAbundance( value: number | null | undefined, options?: { includeUnit?: boolean }, ): string { return formatPropertyNumber(value, { maxDigits: 4, scientificBelow: 0.001, suffix: options?.includeUnit === false ? undefined : "%", }); } export function getConductivityUnitLabel(kind: "thermal" | "electric"): string { return kind === "electric" ? "MS/m" : "W/m·K"; } export function getHeatUnitLabel( kind: "specific" | "vaporization" | "fusion", energyUnit: "kJ" | "eV" = "kJ", ): string { if (kind === "specific") { return "J/kg·K"; } return energyUnit === "eV" ? "eV" : "kJ/mol"; } /** Format heat: specific in J/(kg·K); vaporization/fusion in kJ/mol or eV. */ export function formatHeat( value: number | null | undefined, kind: "specific" | "vaporization" | "fusion", energyUnit: "kJ" | "eV" = "kJ", options?: { includeUnit?: boolean }, ): string { if (value == null || Number.isNaN(value)) { return "—"; } const includeUnit = options?.includeUnit !== false; if (kind === "specific") { return formatPropertyNumber(value, { maxDigits: 1, suffix: includeUnit ? "J/kg·K" : undefined, }); } return formatMolarEnergy(value, energyUnit, options); } /** Format conductivity (thermal W/(m·K) or electric MS/m). */ export function formatConductivity( value: number | null | undefined, kind: "thermal" | "electric", options?: { includeUnit?: boolean }, ): string { if (value == null || Number.isNaN(value)) { return "—"; } const includeUnit = options?.includeUnit !== false; return formatPropertyNumber(value, { maxDigits: 4, scientificBelow: 0.01, suffix: includeUnit ? getConductivityUnitLabel(kind) : undefined, }); } /** Ptable: g/cm³ = kg/m³ / 1000. */ export const KG_M3_TO_G_CM3 = 0.001; /** Format density stored as kg/m³. */ export function formatDensity( valueKgM3: number | null | undefined, unit: "kg" | "g" = "kg", options?: { includeUnit?: boolean }, ): string { if (valueKgM3 == null || Number.isNaN(valueKgM3)) { return "—"; } const includeUnit = options?.includeUnit !== false; if (unit === "g") { return formatPropertyNumber(valueKgM3 * KG_M3_TO_G_CM3, { maxDigits: 4, scientificBelow: 0.001, suffix: includeUnit ? "g/cm³" : undefined, }); } return formatPropertyNumber(valueKgM3, { maxDigits: 4, suffix: includeUnit ? "kg/m³" : undefined, }); } /** Format a kelvin temperature in °C, °F, or K (ptable melt/boil unit select). */ export function formatKelvinTemperature( valueK: number | null | undefined, unit: "C" | "F" | "K" = "C", options?: { includeUnit?: boolean }, ): string { if (valueK == null || Number.isNaN(valueK)) { return "—"; } const includeUnit = options?.includeUnit !== false; if (unit === "K") { return formatPropertyNumber(valueK, { maxDigits: 2, suffix: includeUnit ? "K" : undefined, }); } if (unit === "F") { const fahrenheit = ((valueK - 273.15) * 9) / 5 + 32; return formatPropertyNumber(fahrenheit, { maxDigits: 2, suffix: includeUnit ? "°F" : undefined, }); } const celsius = valueK - 273.15; return formatPropertyNumber(celsius, { maxDigits: 2, suffix: includeUnit ? "°C" : undefined, }); } export function formatElectronsPerShellDisplay(shells: number[] | null | undefined): string { if (!shells?.length) { return "—"; } return shells.join(" "); } /** * Card footer for Energy levels (ptable): keep at most the last 3 shells, * prefix with "-" when truncated (e.g. `2 8 18 32 18 8 2` → `- 18 8 2`). */ export function formatElectronsPerShellCardDisplay( shells: number[] | null | undefined, ): string { if (!shells?.length) { return "—"; } const maxShown = 3; if (shells.length <= maxShown) { return shells.join(" "); } return `- ${shells.slice(-maxShown).join(" ")}`; } export function formatDiscoveredYear(year: number | null | undefined): string { if (year == null || Number.isNaN(year)) { return "—"; } const whole = Math.trunc(year); if (whole < 0) { return `${Math.abs(whole)} г. до н.э.`; } return `${whole} г. н.э.`; } /** Bigenc pages that need a disambiguated title (not the bare element name). */ const bigencArticleSlugsByName: Readonly<Record<string, string>> = { Бор: "Бор_(химический_элемент)", Уран: "Уран_(химический_элемент)", Тантал: "Тантал_(химический_элемент)", Палладий: "Палладий_(химический_элемент)", Титан: "Титан_(химический_элемент)", }; /** Full article URLs that replace the default Bigenc wiki link. */ const articleUrlOverridesByName: Readonly<Record<string, string>> = { Плутоний: "http://www.himsnab-spb.ru/article/ps/pu/", }; export function getBigencWikiUrl(slug: string): string { return `https://bigenc.ru/wiki/${encodeURIComponent(slug)}`; } export function getBigencArticleUrl(elementName: string): string { const override = articleUrlOverridesByName[elementName]; if (override) { return override; } const slug = bigencArticleSlugsByName[elementName] ?? elementName; return getBigencWikiUrl(slug); } export type LegendArticleRef = { title: string; url: string; };