Overview#
The chart toolbar is a hybrid legacy/React-era UI layer that controls both the primary chart and the secondary Analysis Board chart.
This article documents the visible controls, the event model behind them, and the current source files that own the behavior.
Primary source files#
templates/board.php- chart header markup, toolbar markup, inline and compact dropdown controlsresources/js/main.js- chart rendering, mouse/touch navigation, toolbar state sync, expand/screenshot actionsresources/css/react-ui.css- React-shell overrides, compact toolbar rules, dropdown stacking and clipping fixesresources/css/chart.cssandresources/css/style.css- legacy chart layout, overlays, graph-cover behavior, and default canvas wrappers
Visible UI structure#
Header layer#
Each chart header exposes the action cluster:
Take screenshotExpand chartRestore chart
The second chart also exposes the center-aligned collapse toggle for Analysis Board.
Toolbar layer#
The toolbar directly below the header contains:
Model IDwith a copy buttonMin/max priceinputs- the rectangle selection button for quick vertical range capture
Fix scaleLevels/Levels & AssociatesRange
On narrower chart widths, the inline Levels and Range clusters collapse into compact dropdown menus controlled by the React-shell CSS container query.
Main and secondary chart model#
The code maintains two mostly parallel chart runtimes:
- primary chart -
drawGraph(),Graph_settings,Data_settings,#graph-cover - secondary chart -
drawGraph2(),Graph_settings2,Data_settings_2,#graph-cover-2
The toolbar semantics are intentionally mirrored between both charts, but some behaviors remain separately implemented in main.js.
Toolbar control ownership#
Model ID and copy actions#
The visible model id containers and copy buttons are declared in board.php and updated from runtime logic in main.js.
Important buttons include:
#copy-model-id-btn#copy-model-id-btn-2#copy-selected-model-id-btn-2
Min/max range management#
The text inputs are direct price-range controls, while the rectangle icon activates quick visual selection mode.
The delegated range-selection logic starts from:
getRangeSelectDom()updateRangeSelectUi()updateRangeSelectRect()ensureRangeSelectDelegation()
On mouse up, the selected vertical area is converted back into prices and written into the corresponding minprice / maxprice inputs before forcing a redraw.
Fix scale#
Fix scale is still part of the legacy toolbar contract. It is declared in board.php and consumed by the chart draw flow when the visible scale should stay locked.
Levels control#
Levels exists in two synchronized representations:
- inline checkbox cluster for wide chart widths
- compact dropdown for smaller widths
The visible options are the associated structural branches P6, P6", auxP6, and auxP6'.
Range control#
Range follows the same UI pattern as Levels: inline controls for wide layouts and a dropdown for compact layouts.
The current runtime implementation is centered around:
mpNormalizeChartRangePercent()mpGetChartRangeCollections()mpSyncChartRangeFromElement()mpDrawModelRangeMarkers()
The control stores one shared percent value per chart and one toggle per model branch.
The dashed vertical marker is drawn relative to node 6 and projects forward to the right of the model structure.
Expand, restore, and screenshot flow#
Primary chart actions#
The primary chart expand/restore flow is centered around toggleChartExpand().
The chart header buttons are wired so the runtime can switch between the compact card layout and the fullscreen-style expanded layout without rebuilding the entire page.
Secondary chart actions#
The secondary chart has its own dedicated action flow:
toggleChart2Expand()takeChart2Screenshot()syncChart2HeaderActionButtons()ensureSecondChartCanvas()
When expanded, the second chart can be moved into document.body temporarily so it is no longer constrained by the normal analysis layout.
React-shell CSS layer#
The current toolbar and dropdown behavior is heavily shaped by resources/css/react-ui.css.
This file overrides the older chart styles to solve real runtime issues such as:
- header action positioning after moving screenshot/expand buttons into a cleaner header cluster
- compact toolbar switching based on chart container width rather than viewport width
- dropdown stacking above chart overlays like
#graph-cover - chart-shell clipping that could previously cut off compact dropdown menus such as
Range
Known implementation patterns#
- The toolbar is not owned by one pure component model; markup, runtime logic, and layout fixes live across PHP, JS, and CSS.
- The second chart mirrors the first one functionally, but many handlers are duplicated rather than shared through a fully unified abstraction.
- The interaction layer is intentionally DOM-based on top of canvas, which is why clipping and z-index issues can affect dropdown controls even though chart drawing itself happens on canvas.
Safe change rules#
- When editing toolbar markup, update both the main chart and the Analysis Board variant in
board.php. - When editing compact toolbar behavior, verify both inline and dropdown UI states stay synchronized.
- When editing overlay or dropdown styles, check both clipping and z-index behavior against the graph-cover layer.
- After JS or CSS changes, rebuild frontend assets with
npm run buildso the runtime uses updatedpublic/app.min.jsandpublic/app.css.