Skip to main content

Architecture

Chart and navigation panel architecture

Chart and navigation panel architecture guide

Section Architecture
Updated 07.06.2026

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 controls
  • resources/js/main.js - chart rendering, mouse/touch navigation, toolbar state sync, expand/screenshot actions
  • resources/css/react-ui.css - React-shell overrides, compact toolbar rules, dropdown stacking and clipping fixes
  • resources/css/chart.css and resources/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 screenshot
  • Expand chart
  • Restore chart

The second chart also exposes the center-aligned collapse toggle for Analysis Board.

Toolbar layer#

The toolbar directly below the header contains:

  • Model ID with a copy button
  • Min/max price inputs
  • the rectangle selection button for quick vertical range capture
  • Fix scale
  • Levels / Levels & Associates
  • Range

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.

Pointer and touch navigation#

Hover and candle readout#

The transparent interaction layer #graph-cover / #graph-cover-2 handles pointer movement above the canvas.

Hover updates the current candle information and drives crosshair-style helpers such as price and bar readouts.

Wheel zoom#

The primary chart uses wheel() and the secondary chart uses wheel2().

Both functions adjust the horizontal scale only when the pointer is inside the active plotting area boundaries.

Horizontal panning#

Drag behavior is implemented on the graph-cover layer.

Once the pointer is pressed and moved, the runtime calculates dx, updates the current bar pointer, and redraws the chart.

Active bar selection#

A click on the graph-cover without drag movement changes the active bar.

If multiple models belong to the same bar, repeated clicks can cycle through the available models for that bar slot.

Touch support#

The primary chart touch path is handled on #graph-cover:

  • one finger - horizontal move
  • two fingers - zoom

The second chart currently has wheel support and pointer drag handling as part of its dedicated runtime path.

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 build so the runtime uses updated public/app.min.js and public/app.css.

Continue Reading

Related Articles