feat(sim-builder): улучшение P3 — графики: несколько кривых, заливка под кривой, маркеры, легенда

This commit is contained in:
Maxim Dolgolyov
2026-06-13 14:26:36 +03:00
parent 222005c0ba
commit 69e219ae8c
4 changed files with 260 additions and 24 deletions
+25 -3
View File
@@ -1,6 +1,30 @@
# Feature Context: Конструктор симуляций (SimForge)
## Current State
- **РАУНД УЛУЧШЕНИЙ (IMPROVEMENTS.md) — P3 «Графики/диаграммы» РЕАЛИЗОВАН** (рабочее дерево, не
закоммичено; ветка `feature/sim-builder`). Файл: только `frontend/js/labs/_sim_engine.js`. Расширен
`_drawPlot` + ветка `type==='plot'` в `_prepareObjects`. Оси/сетка/подписи уже из P1 — не дублировались.
- **Несколько кривых**: нормализуются в `prep.curves[]`, приоритет источника `curves:[{...}]`
`exprs:['sin(x)','x^2']` → одиночный `expr` (легаси, обратная совместимость сохранена). Каждой кривой
свой цвет (явный `color` или `DEFAULT_PALETTE[i%8]`). `prep.exprFn` = первой кривой (для trace-режима).
- **Поля кривой** (`curves[i]`): `expr`, `color`, `label`(→легенда), `width`, `lineStyle`, `opacity`,
`fill`(true→полупрозр. цвет / строка), `marker`(none|dot|ring). Не заданные наследуют plot-уровень.
**Plot-уровневые `fill`/`marker`** — дефолт для всех кривых.
- **Заливка под кривой** `_fillUnderCurve` (между кривой и y=0, посегментно — разрывы у не-finite не
сливаются; baseY клиппится к canvas). **Маркеры** `_drawCurveMarkers` (переиспользует `_drawPoint`,
прорежены ~28px). **Легенда** `_drawLegend` на canvas (тёмная плашка + свотч + светлый текст, верх-право,
авто при `label`, `legend:false` отключает). Новые модульные хелперы `_markerStyle`/`_fillAlpha`.
- **Безопасность**: цвета только в canvas-стоки (strokeStyle/fillStyle/fillText фикс-цвет легенды);
DOM-style с пользовательским цветом не используется; eval нет. Каждая кривая в своём save/restore,
легенда на внешнем уровне.
- Верификация: `node --check` OK; headless vm-смоук (canvas-стаб со счётчиком save/restore + РЕАЛЬНЫЕ
`_sim_expr`+`_sim_engine`) 10/10: легаси/exprs[]/curves+fill+marker+legend/наследование/не-finite
(1/x,tan)/legend:false/trace±range/fillUnder+markers с null/регресс point-vector-circle-rect — все PASS;
ctx сбалансирован (depth→0, нет underflow). Эмодзи нет (только пре-существующие → в комментариях); eval=0.
Temp-смоук удалён. git status: тронут только `_sim_engine.js`.
- **Следующее (P4):** UI билдера + контролы стиля (`sim-builder.html`/`sim-builder.js`) — дать новым полям
plot контролы: список кривых (add/del, expr+color+label+width+lineStyle+opacity+fill+marker), plot-fill/
marker, тумблер легенды; плюс per-объект color/opacity/width/dash, z-order, дублирование, мобайл.
- **РАУНД УЛУЧШЕНИЙ (IMPROVEMENTS.md) — P2 «Качество графики объектов» РЕАЛИЗОВАН** (рабочее дерево, не
закоммичено; ветка `feature/sim-builder`). Файл: только `frontend/js/labs/_sim_engine.js`. Один движок →
эффект и в билдере, и в /lab, и на доске.
@@ -25,9 +49,7 @@
масштаб; все поля прочитаны; палитра применена + явный color сохранён; трасса накоплена; destroy чист.
Эмодзи нет (скан кодпойнтов: только пре-существующие →/─/═/∞ в комментариях); eval=0; new Function — только
в комментарии стр.15. git status: тронут только `_sim_engine.js`.
- **Следующее (P3):** графики/диаграммы (`_drawPlot`): оси-деления plot, несколько кривых, заливка под
кривой, маркеры точек (переиспользовать `_drawPoint`), легенда. Хелперы `_applyStroke`/`_fillStyleFor`/
`_drawPoint` готовы к переиспользованию.
- **Следующее (P3):** РЕАЛИЗОВАНО (см. блок P3 выше) — несколько кривых, заливка, маркеры, легенда.
- **РАУНД УЛУЧШЕНИЙ (IMPROVEMENTS.md) — P1 «Рабочее поле» РЕАЛИЗОВАН** (рабочее дерево, не закоммичено;
ветка `feature/sim-builder`, общая с параллельной сессией materials/quota). Файл: только
`frontend/js/labs/_sim_engine.js` (sim-builder.html НЕ потребовался). Один движок → эффект и в билдере, и в /lab, и на доске.
+26 -4
View File
@@ -68,9 +68,31 @@
кривых). Для P3 расширять `_drawPlot` — оси-делений plot, несколько кривых, заливка под кривой, маркеры
точек (можно переиспользовать `_drawPoint`), легенда. Хелперы `_applyStroke`/`_fillStyleFor`/`_drawPoint`
готовы к переиспользованию.
- [ ] **P3 — Графики/диаграммы (визуал charts).** Для plot: оси с делениями/подписями, несколько кривых,
заливка под кривой, маркеры точек, легенда; аккуратный стиль диаграмм. Файл: `_sim_engine.js` (+ билдер
поля plot).
- [x] **P3 — Графики/диаграммы (визуал charts).** Для plot: несколько кривых, заливка под кривой,
маркеры точек, легенда; аккуратный стиль диаграмм (оси/сетка/подписи — уже из P1). Файл: `_sim_engine.js`.
**Handoff (P3 → P4): новые поля plot-объекта** (контракт для контролов билдера в P4). Все читаются в
`_prepareObjects` (ветка `type==='plot'`), рендерятся ТОЛЬКО на canvas (без DOM-style/eval). Старый
одиночный `expr`/`var`/`range`/`samples`/`trace` работает как раньше (обратная совместимость):
- **Несколько кривых.** Источник (приоритет): `curves:[{...}]` → `exprs:['sin(x)','x^2']` → `expr`
(легаси). Нормализуются в `prep.curves[]`. Каждой кривой свой цвет: явный `color` или
`DEFAULT_PALETTE[i%8]`. `prep.exprFn` = первая кривая (для trace-режима).
- **Поля кривой** (`curves[i]`): `expr` (строка), `color`, `label` (строка → легенда), `width`,
`lineStyle` (`solid|dashed|dotted`), `opacity` (0..1), `fill` (`true` → полупрозр. цвет кривой / строка
цвета), `marker` (`none|dot|ring`). Не заданные наследуются от plot-уровня (`width/lineStyle/opacity`)
или дефолтов.
- **Plot-уровневые** `fill` и `marker` — дефолт для всех кривых (если у кривой не задано).
- **Заливка под кривой** — между кривой и осью `y=0`, посегментно (разрывы у не-finite точек не сливаются),
`_fillUnderCurve`. Прозрачность через `_fillAlpha(color, 0.18)` для `fill:true`.
- **Маркеры узлов** — `_drawCurveMarkers` (переиспользует `_drawPoint`), прорежены ~28px по экрану
(не рисуем сотни точек). `dot` → filled, `ring` → hollow.
- **Легенда** — `_drawLegend` (на canvas: тёмная плашка + цветной свотч + светлый текст), верх-право,
не наезжает на бар кнопок вида. Включается авто при наличии `label`; `legend:false` отключает.
- **Качество кривой** — пропуск не-finite (разрывы), переиспользован существующий equidistant sampling
(`samples`, деф. 200, макс 2000), `_applyStroke` (dash/opacity/glow/lineJoin/cap).
- **На P4 (билдер):** дать этим полям контролы — список кривых (добавить/удалить, expr + color-picker +
label + width + lineStyle + opacity + fill toggle/color + marker select), plot-уровневые fill/marker,
тумблер легенды. Хелпер `_markerStyle`/`_fillAlpha` — модульного уровня, рядом с `_dashFor`/`_opacity`.
- [ ] **P4 — UI билдера + контролы стиля.** Дизайн-полировка панелей/тулбара (ls.css), нативные color-
пикеры + opacity/width/dash/линестиль на объект, z-order/дублирование/видимость объектов, пустые
состояния, мобайл. Файлы: `frontend/sim-builder.html`, `frontend/js/sim-builder.js`.
@@ -82,6 +104,6 @@
|-------|--------|--------|-----------|
| P1 Working field | Done | ✅ PASS | ✅ |
| P2 Object graphics | Done | ✅ PASS | ✅ |
| P3 Charts | ⬜ | ⬜ | |
| P3 Charts | Done | ✅ PASS | |
| P4 Builder UI | ⬜ | ⬜ | ⬜ |
| P5 Direct manip + history | ⬜ | ⬜ | ⬜ |