Files
templates/c/set-protocol/docs/GUI_PLOT.md

8.4 KiB
Raw Blame History

Общая работа с графиками Android и SETGUI

Численная логика находится в include/set_plot.h и src/set_plot.c. Это модуль C99 без Qt, Android, транспорта, динамической памяти и глобального состояния. Он собирается в существующую библиотеку SETProtocol; отдельная DLL для графиков не требуется. Версия ABI графиков — set_plot_abi_version() == 1; новые операции добавляются без изменения существующих значений и сигнатур.

Общее в templates Адаптер приложения
Нормализованная область просмотра, масштаб 1…128, ограничение панорамирования Размер поля и отступы в пикселях
Независимый масштаб X/Y с сохранением координаты под пальцами События Compose или Qt, колесо, кнопки
Выбор преобладающей оси по изменению расстояния между пальцами Накопление движения до порога; фиксация выбранной оси до конца жеста
Перевод значения в долю экрана и обратно, инверсия Y Canvas/QPainter и оформление шкал
Перемещение маркера от начальной координаты, ограничение видимой областью Захват линии пальцем/мышью, редактор положения
Разность BA, DC и множитель единиц, шаги шкалы 1/2/5 Подписи, цвета, миллисекунды/герцы/единицы сигнала
Проверка абсолютных границ X/Y для фиксации осей Диалог ввода и хранение отдельных границ времени/FFT
Модели маркеров и их размещение в Kotlin/Python-портах Жизненный цикл экрана, очистка и выбор источника

Модель маркеров: A/B — координаты X и вертикальные линии во всю высоту поля; C/D — координаты Y и горизонтальные линии. Они могут пересекаться: отрицательная разность сохраняется. Начальные координаты — 1/3 и 2/3 диапазона. При изменении масштаба уже установленные координаты сохраняются. «Маркеры в видимую область» заново размещает их. Координаты и область просмотра времени/спектра независимы.

set_plot_eval() принимает операцию из enum set_plot_operation, точное число входных double и буфер вывода. Контракт каждой операции указан в заголовке. Возвращает число записанных элементов, 0 — неправильные аргументы. Некорректный коэффициент масштабирования оставляет корректный viewport неизменным. NaN/Inf и вырожденные диапазоны не передаются дальше в отрисовку. FRACTION/VALUE не обрезают координаты: это позволяет правильно отсекать линии по границе поля, а не создавать ложные горизонтальные участки на его краю. DRAG, напротив, ограничивает положение маркера видимым диапазоном.

Порты

  • Android/JVM: ports/android/kotlin/ru/setcorp/setprotocol/trends/NativePlot.kt, PlotViewport.kt, TrendMarkers.kt; тонкий JNI — ports/android/set_plot_jni.c. Android использует System.loadLibrary("setprotocol"). Для JVM-тестов можно передать абсолютный путь DLL/SO системным свойством setplot.library.
  • Python: python/protocan/plot.py: PlotMath(library), Viewport, Bounds, Markers. Приложение передаёт уже загруженную SETProtocol ctypes.CDLL. Зависимости — стандартная библиотека; Qt в этот модуль не импортируется.

Новые изменения не должны добавлять вторую реализацию численных операций в Kotlin/Python или в приложение. Состояние и адаптация событий остаются в портах. Добавление операции требует обновления C ABI, обоих портов и общих эталонов.

Интеграция приложений

Android: TrendGraph использует общие viewport, bounds и маркеры, а Compose рисует линии и панель. При измерениях время отображается в миллисекундах от начала выбранного участка; сохранённые X-координаты включают абсолютное начало.

SETGUI: ui/plot_interaction.py адаптирует общий модуль к Qt. Его используют SignalPlot (ТМС и датчики), TrendPlot (логи) и SpectrumPlot. Колесо по вертикали масштабирует Y, Shift+колесо и горизонтальное колесо — X; сенсорный pinch выбирает ось по движению. Временные графики хранят метку приёма каждого отсчёта. Пропущенные значения не растягивают остальные серии: все сигналы имеют единую шкалу времени. При повторном построении ТМС из журнала используются исходные метки приёма. Дискретные дорожки имеют общую X-шкалу, а маркеры уровня Y относятся к аналоговому полю.

Расчёт FFT не является частью этого модуля. Android и SETGUI вычисляют спектр через set_spectrum.c; там же находится общий поиск доминирующего узкополосного пика, а трёхсекундный таймер его отображения остаётся состоянием GUI. Вкладка спектра SETGUI получает готовые уровни в дБмВ от прибора. Общая интерактивная часть не меняет эти данные или единицы.

Проверка и сборка

  • CMake/CTest: shared_plot проверяет ABI, размеры буферов и координаты.
  • tests/fixtures/plot-v1.json содержит общие численные эталоны. Их читают PlotContractTest (фактический JNI) и python/tests/test_plot.py (ctypes).
  • Host DLL/SO для Python: python tools/build_host.py --output <путь>.
  • Для JVM: та же команда с --java-home <JDK> добавляет JNI-порт графиков. Нужен C-компилятор (MSVC на Windows, cc/clang/gcc на Unix) и JDK с jni.h.
  • Android-проект автоматически собирает host-библиотеку перед JVM-тестами; интерпретатор Python можно задать свойством Gradle setflash.python.
  • SETGUI проверяет события мыши, колеса и двух пальцев через QtTest без физического прибора; численные тесты не требуют GUI.

Исходники должны приходить из одного коммита подмодуля templates в обоих проектах. Локальная замена файлов без обновления gitlink не закрепляет версию.