Table of Contents

Cycle-Line Charts

The cycle-line charts visualise a per-step, per-cycle detail view of force / moment signals around the currently-selected step. They are re-fetched whenever the step selection changes, so the operator can zoom into one spindle revolution (or the configured cycle window) while scrubbing through the mission timeline on the strip charts.

They sit in the Step Info column of the Execution Page, below Step Properties and CWE. The anatomy covers four, all sharing BaseCycleLineChart.vue, in the order the column stacks them:

Chart Source Data Cycle parameter Notes
Sim Cutting Force Cycle MachiningStep.ForceToWorkpieceOnProgramCoordinate or ForceToToolOnToolRunningCoordinate spindle angle (deg) Header dropdown picks between the two flag values; swaps the fetcher prop so BaseCycleLineChart refetches.
Sim Spindle Moment Cycle MachiningStep.MomentsToToolAboutObservationPointOnSpindleRotationCoordinate_Nm spindle angle (deg) Simulated moment from the physics model. Carries the locus (dartboard) mode.
Sensor Cutting Force Cycle IForceShot via TimeMapping.GetShots(stepIndex) time (s) Dynamometer-measured force. Returns an empty shape when there is no dynamometer data.
Sensor Spindle Moment Cycle IMomentShot via MachiningProject.TimeMapping.GetShots(stepIndex) time (s) Sensor-measured moment. Rendered as a sibling card to the sim chart rather than a twin overlay, which keeps the two uplot instances independent. Carries the locus (dartboard) mode.

The parameter split is the reason the two pairs never share a cursor: a simulated cycle is indexed by phase, a measured one by clock.

Key Model: MachiningProject.TimeMapping + the selected MachiningStep.

Layout

Each cycle-line chart is a collapsible panel:

  • Header Row
    • Title label.
    • Flag picker (Sim Cutting Force chart only) — a <q-btn-dropdown> between ForceToWorkpieceOnProgramCoordinate (default) and ForceToToolOnToolRunningCoordinate.
    • Mode picker (enableLocus charts only — the two spindle-moment charts) — Line / Dartboard.
    • Value-boundary dropdown — Auto, or Fixed with a ± bound that pins the y range symmetrically so two steps can be compared without the axis moving. Its label reads the bound when one is set.
    • Reload.
  • Body — UplotChart.vue rendering three series (X / Y / Z channels) over the cycle parameter ts, or XyLocusChart.vue in dartboard mode, which plots the same samples as a locus in the plane. The line-mode legend width is shared by every line-mode cycle chart, as the strip charts share theirs; the locus view has no legend divider and is unaffected.
  • Empty-state overlay — No step selected with nothing picked, Not ready before the payload arrives, No data for step when the step carries none. The underlying series still carry a shape-preserving ts=[0,360], xs/ys/zs=[NaN,NaN] payload so the canvas does not jump. The two sensor charts read No data for step for every step of a project with no TimeMapping shot data, which is the normal state of a project that has not been measured.

Behavior

  • Step-driven refetch. BaseCycleLineChart accepts a fetcher: () => Promise<CycleLineResponse> prop. The step-selection push arrives on /clStripHub as StepSelected; the fetcher is re-invoked and the chart re-renders.
  • Server-resolved step. The cycle-line endpoints resolve “currently-selected step” from LocalProjectService.ClStrip.GetSelectedPos() rather than accepting stepIndex as a query parameter. This keeps the contract simple and matches the event-driven model used by the rest of the execution plumbing.
  • Toolbar slot. The optional #toolbar slot lets callers embed per-chart controls (such as the force chart's flag picker) without subclassing.
  • Shared cursor mark, in two groups. Clicking a point publishes that sample's cycle parameter — not its index — to a module-scoped mark shared by the group: sim for the two simulated charts (spindle angle), sensor for the two measured ones (seconds). Each chart draws the mark as a vertical line in line mode and a highlighted point in dartboard mode, and the mark survives both a mode switch and a change of selected step. The split is deliberate: a click on a simulated chart must not move a sensor-side cursor, because the two axes are not the same quantity.
  • The sim mark reaches outside the chart family. The CWE panel of the Execution Page's Step Info column watches it and pushes the angle to its own displayee, so the flute overlay in the engagement view rotates to the phase clicked on a force or moment chart. The angle persists on that displayee across steps — the server re-applies it with each step's spin direction — so it is pushed only on (re)connect and on a new click.

Source Code Path

See HiNC App Anatomy for git repository links.

HiNC-2025-webservice (Quasar CLI SPA):

  • wwwroot-src/src/components/execution/charts/BaseCycleLineChart.vue — shared cycle-line skeleton.
  • wwwroot-src/src/components/execution/charts/UplotChart.vue — uplot wrapper (shared with the strip charts).
  • wwwroot-src/src/components/execution/charts/XyLocusChart.vue — the dartboard (locus) renderer used in place of the uplot chart in that mode.
  • wwwroot-src/src/composables/useCycleSyncMark.ts — the two module-scoped cursor marks and their group keys.
  • wwwroot-src/src/components/execution/StepVolumePanel.vue — the CWE panel that follows the sim mark to rotate its flute overlay.
  • wwwroot-src/src/components/execution/charts/ForceCycleLineChart.vue — force cycle-line chart with the flag picker.
  • wwwroot-src/src/components/execution/charts/SimSpindleMomentCycleLineChart.vue — simulated spindle moment.
  • wwwroot-src/src/components/execution/charts/SensorSpindleMomentCycleLineChart.vue — sensor-measured spindle moment.
  • wwwroot-src/src/components/execution/charts/DynamometerForceCycleLineChart.vue — dynamometer force.
  • Execution/ExecutionChartsController.cs — cycle-line endpoints:
    • GET /api/execution/cycle-line/force?flag=ForceToWorkpieceOnProgramCoordinate|ForceToToolOnToolRunningCoordinate
    • GET /api/execution/cycle-line/sim-spindle-moment
    • GET /api/execution/cycle-line/sensor-spindle-moment
    • GET /api/execution/cycle-line/dynamometer-force

All four endpoints return { hasData, ts, xs, ys, zs } flattened for direct uplot consumption. Empty payloads use a shape-preserving ts=[0,360], xs/ys/zs=[NaN,NaN] fill.

See Also

  • Execution Page — the page whose Step Info column hosts these charts
  • Strip Charts — windowed mission-timeline charts that share the same uplot engine and drive step selection
  • Inspecting a Step — the task these charts serve, with the two scales and the shared mark read as a procedure