MAIDR JavaScript API
    Preparing search index...

    Class SmoothTrace

    Trace implementation for smooth plots with continuous audio feedback.

    The description is LineTrace's, save for the vocabulary below: the chart type resolves from TraceType.SMOOTH through getChartTypeLabel(), and everything else a fitted curve has to say -- the samples, the band around them -- the line already reports.

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    Accessors

    Methods

    Constructors

    Properties

    observers: Observer<TraceState>[]
    isWarning: boolean
    isComputingStateAt: boolean

    True while AbstractTrace.getStateAt computes state at a temporarily moved cursor. Enforces (structurally, not just by documentation) that state getters never notify observers.

    id: string
    type: TraceType
    title: string
    name: string | undefined

    What this layer is, when the producer named it. See MaidrLayer.name.

    layer: MaidrLayer
    supportsExtrema: true

    Abstract property that subclasses must implement to indicate extrema support

    rotorSupport: true
    movable: MovableGraph
    points: LinePoint[][]
    lineValues: number[][]
    highlightValues: (SVGElement | SVGElement[])[][] | null

    One entry per point, or -- where a series is drawn as several elements with no way to tell which is which -- the whole set behind every point of it, outlined together. ContourTrace is the case: a level with islands has one <path> per island and no dependable order among them (xability/maidr#1142).

    lineElements: SVGElement[] = []

    The rendered <path>, <polyline> or <polygon> of each series, when the highlight markers were synthesised from one.

    mapViaPathParsing builds a circle per data point and throws the element it read them out of away, so the trace's own highlight list holds the vertices of the line and nothing of the line itself. Anything drawing the trace from those markers therefore draws a scatter of dots where the chart drew a continuous line -- which on a tactile display is not a cosmetic difference: the segments between vertices are most of the geometry, and without them a zoomed-in view whose window falls between two points has nothing in it at all.

    Empty when the markers are the chart's own dot elements (mapViaDomElements), where the connecting line is a separate element this trace never resolved and so cannot offer.

    highlightCenters:
        | {
            x: number;
            y: number;
            row: number;
            col: number;
            element: SVGElement;
        }[]
        | null
    min: number[]

    Each series' own lowest and highest measured value, which [ and ] jump to within the series the cursor is on.

    max: number[]

    Accessors

    • get isInitialEntry(): boolean

      Returns boolean

    • set isInitialEntry(value: boolean): void

      Parameters

      • value: boolean

      Returns void

    • get row(): number

      Returns number

    • set row(value: number): void

      Parameters

      • value: number

      Returns void

    • get col(): number

      Returns number

    • set col(value: number): void

      Parameters

      • value: number

      Returns void

    • get xAxis(): string

      The x axis's name, falling back to a generic one the layer authored none.

      A getter rather than a field set in the constructor: the fallback is a translated word, and a trace outlives a language change — a name resolved once at construction would keep the language the chart was built in.

      Returns string

    • get yAxis(): string

      The y axis's name, or a generic one. See xAxis.

      Returns string

    • get z(): string

      The z axis's name, or a generic one. See xAxis.

      Returns string

    • get isEmptyAtCursor(): boolean

      Whether the cursor has no point to report.

      Read from dimension rather than from any one trace's data, because that is the one shape every trace already answers in. It is also evaluated at the cursor — LineTrace returns the current series' length as cols — so this covers a ragged layer, where one series has points and another has none, and not only a layer that is empty throughout.

      Returns boolean

      True when there is nothing at (row, col) to describe

    • get hasMultiPoints(): boolean

      Returns boolean

    • get layerLabel(): string

      How this layer names itself in the description dialog's layer tabs.

      The producer's name when there is one, and the chart-type label otherwise — the same fallback order TextService.layerIdentity uses for the spoken layer-switch announcement, so a tab and the announcement single out the same layer by the same name. The two differ only in register: the announcement says "point plot" where the dialog says "Scatter Plot", because that written form is what the dialog's own Chart Type line has always shown and a tab sitting above it should agree with it.

      Returns string

    • get guide(): ChartGuide | undefined

      A plain-language introduction to this layer's chart type, for the description dialog. See chartGuide.

      A layer that names its own chart type never gets the trace type's: that guide explains the type the chart is read as, which is not what the chart is, and a gantt's tasks, dates and project plans said of a packet's bit fields are false. It gets the guide to the diagram it names (MaidrLayer.diagramType), or the one it gives to its own chart (MaidrLayer.typeGuide), or none.

      Returns ChartGuide | undefined

    • get orientationLabel(): string | undefined

      Which way this chart is drawn, or undefined for a type that has no orientation to speak of.

      Entering the chart already announces it -- "This is a maidr plot of type: horizontal bar" -- but the description dialog said only "Chart Type: Bar Chart", and for the box, violin and boxen families the orientation also silently reverses the order of the rows in the table underneath, because their constructors reverse the groups when the chart is horizontal. A reader comparing the table with what they walked had no way to know why the two disagreed.

      Exposed here, and read once by the description service, rather than pushed as a stat by each of the thirty-odd traces that has one. Named apart from the bar and distribution families' own orientation fields, which hold the declared* value and default it to vertical for every type -- including the ones that have no orientation at all.

      Returns string | undefined

      horizontal or vertical, or undefined when the type has no orientation to report.

    • get traceType(): TraceType

      The trace's chart type. Lightweight alternative to reading state.traceType, which eagerly computes the full audio/braille/text/ highlight state just to expose this one string.

      Returns TraceType

    • get level(): "trace"

      Returns "trace"

      Trace.level

    • get values(): number[][]

      Returns number[][]

    • get valueRange(): { min: number; max: number }

      The range every series is pitched and brailled against: the lowest and the highest measured value of the whole layer.

      One range for the layer, as a bar layer has one, because the series of a line chart are drawn against one value axis. Pitched each against its own range, every line's own lowest point played the bottom note and its own highest the top one, so a smaller value on one line could sound higher than a larger value on another, and unequal values on two lines played the same note.

      The tone at the cursor, the chord at a point several series share and the braille all read it, so a subclass heard on another register overrides this one getter and all three follow. A bump chart, whose register runs the other way round, keeps its braille the right way up with an override of its own.

      Returns { min: number; max: number }

      The lowest and highest value of the register

    • get valuesArePositions(): boolean

      Whether a value is where the series is drawn on the value axis, rather than a magnitude measured out from a baseline.

      True of a line: a 0 between negative and positive values is a place on the axis, and is pitched there. A filled mark -- an area's band, a polar area's wedge -- is a magnitude, as a bar is, and its 0 is no band and no wedge, which the null tone marks; those traces answer false.

      Returns boolean

      True when the layer's values are positions

    • get outOfBoundsState(): TraceEmptyState

      The boundary tone sounds where the point the reader stopped at sounds.

      The base pans it by column index, which is this family's own sweep, and so was right only where panningFor is not overridden. A radar's point pans by its spoke's angle and its boundary chimed by the spoke's index: the 3 o'clock spoke, heard on the right, chimed left of centre, and the 9 o'clock spoke hard right. A ROC or precision-recall curve's point pans by its rate and a parallel coordinates' by its axis, and their boundaries chimed by index as well.

      Returns TraceEmptyState

      The empty trace state, panned to the cursor's point

    • get seriesCanMeet(): boolean

      Whether two series meet where their values are equal.

      True of lines, which are drawn at their own values: two lines with one value at an x share that point of the drawing, and two whose values pass each other cross. A subclass whose series are drawn somewhere other than at their values -- a stacked area's band sits on the bands below it -- answers false, and then no point is announced or sounded as an intersection, and neither the extrema list nor the rotor offers one.

      Returns boolean

      True when series meet where their values do

    • get state(): TraceState

      Get the state for this smooth trace. Overrides the parent state to set plotType to 'smooth' for proper identification in instruction text and layer announcements.

      Returns TraceState

      The trace state with plotType set to 'smooth'

    • get groupFallbackLabel(): string

      What one series is called wherever an announcement names it.

      A curve, announced beside its own name on every move; inheriting the line's "Group" puts two words for one referent in one sentence.

      Returns string

      The fallback label

    • get seriesLabels(): {
          count: string;
          perSeries: string;
          names: string;
          column: string;
      }

      The vocabulary the description dialog is rendered with.

      These are samples along a fitted curve, not observations -- the data the curve was fitted to is not in the layer at all. A reader told "Points per line: 80" takes them for eighty measurements, and then reads a table of eighty evenly spaced x values that are the fit's resolution rather than anything that was measured.

      Returns { count: string; perSeries: string; names: string; column: string }

      The four labels the description uses

    • get audio(): AudioState

      Sonifies the curve as a glissando rather than as one tone per sample.

      Returns AudioState

      The audio state, carrying the neighbouring samples too

    Methods

    • Runs action with this element's observers muted.

      A cursor move normally is the announcement -- moveToIndex notifies, and everything downstream of it speaks, brailles and highlights. That is wrong for a move the reader did not make and is not waiting to hear: the description dialog's layer tabs relocate the reader in the chart while the modal is open, and the trace's announcement would land in the same live region the dialog is using, so one of the two is dropped. The caller announces afterwards, once, when the reader is back on the chart.

      Nesting is safe and the flag is restored on every path, including a throw, because a flag left raised would silence the chart for good.

      Parameters

      • action: () => void

        The moves to make in silence

      Returns void

    • Gets safe row and column indices to prevent accessing undefined values

      Returns { row: number; col: number }

      Object with safe row and column indices

    • Parameters

      • a: number

        Utility function to compare point values for rotor functionality

      • b: number
      • type: "lower" | "higher"

      Returns boolean

      boolean value

    • Rotor compare search along one row of numeric values.

      Steps from the current column in the given direction and moves to the first value that satisfies the comparison; reports the rotor boundary when nothing further qualifies. For the traces whose values are a plain numeric grid indexed [row][col]; a trace with a richer layout (the bar's orientation-normalised rows, the candlestick's segments) keeps its own.

      Parameters

      • rowValues: readonly number[]

        The values of the row being searched

      • direction: "left" | "right"

        Which way to search

      • type: "lower" | "higher"

        Whether a lower or a higher value is sought

      Returns boolean

      True when a matching value was found and moved to

    • Moves left in rotor mode, optionally filtering by lower or higher values.

      Parameters

      • Optional_mode: "lower" | "higher"

        Optional mode for filtering (lower or higher)

      Returns boolean

      Error always - subclasses must override this method

    • Moves right in rotor mode, optionally filtering by lower or higher values.

      Parameters

      • Optional_mode: "lower" | "higher"

        Optional mode for filtering (lower or higher)

      Returns boolean

      Error always - subclasses must override this method

    • Whether the rotor offers its lower and higher value modes on this trace.

      Exactly when the trace overrides moveToNextCompareValue. The base search is a no-op that reports a boundary, so offering the modes without one told a reader "No lower value found" with a lower value beside them, or said nothing at all; tying the offer to the search keeps the two from drifting apart again. A subclass can still override this to withhold the modes (scatter, whose arrows walk points rather than values), and a trace that compares only through the rotor's arrow methods must override it to offer them.

      Returns boolean

    • Returns the display name for the default data navigation mode. Override to provide a trace-specific name (e.g., "ROW AND COLUMN NAVIGATION" for scatter).

      Returns string

    • The format the layer's author declared for an axis, or null when they declared none.

      For a number the description states rather than tabulates. The table reads each column through the axis's declared format, and so does every announcement, but a stat printed the raw number: a margin drawn as a percentage was "Min value: 0.12" over a table and a cursor saying 12%. Null rather than the default format when nothing was declared, so a chart nobody formatted reads as it did, which is the rule the table follows.

      Parameters

      • axis: AxisType

        The axis whose format to read

      Returns FormatFunction | null

      The format, or null when the layer declared none

    • Get all highlight SVG elements for this trace Used by HighlightService for high contrast mode

      Returns SVGElement[]

      Array of all SVG elements, or empty array if none

    • The chart's own element a marker this trace drew stands for, where the trace marks a point with a dot of its own rather than with a copy of the mark. None by default.

      Parameters

      • _marker: SVGElement

        A marker in this trace's highlight values

      Returns SVGElement | null

      The element the marker stands for, or null

    • Get all original (visible) SVG elements for this trace. These are the actual rendered elements, not the hidden clones used for highlighting. Used by HighlightService for high contrast mode color changes.

      Returns SVGElement[]

      Array of all original SVG elements, or empty array if none

    • Computes the trace state at an arbitrary position without moving the user's cursor or notifying observers. Used by monitor mode to sonify and announce a newly appended point while the user stays put.

      The state getters read this.row/this.col internally, so the cursor is moved temporarily and always restored in a finally block — this method is the single owner of that pattern.

      Re-entrancy hazard: this is only safe because the entire call chain is synchronous (no await points), so timers (e.g. autoplay ticks) cannot interleave before the finally-restore, and state getters never notify observers. If a getter ever becomes async or triggers notifications, callers could observe the temporary cursor.

      Parameters

      • row: number

        The row of the position to compute state for

      • col: number

        The column of the position to compute state for

      Returns TraceState

      The trace state at the requested position

    • Returns a human-readable label for this trace's chart type (e.g., 'Bar Chart', 'Scatter Plot') for display in the description modal. Falls back to the raw layer type if no mapping is registered.

      Returns string

    • What the entry instruction calls this chart: the name the layer gives its own chart type (MaidrLayer.diagramType or MaidrLayer.typeLabel), or the trace's word.

      A trace that names itself -- a line "single line" or "multiline", a radar "polar area" -- passes its word through here, so a layer that names its chart type is called by that name whichever trace reads it, and the instruction a reader hears once in the chart says what the one built from the layer before it said.

      Parameters

      • own: string

        The trace's word for its type

      Returns string

      The word the instruction uses

    • Builds the axes object for the description state, carrying only the axes the layer actually authored a label for. Subclasses should call this instead of constructing the axes object inline so charts without a real z dimension don't surface the placeholder default.

      Every axis is gated, not just z. xAxis and yAxis fall back to the literal 'X' and 'Y' when the JSON authors no label -- legal, and common in adapter-generated specs -- and the dialog rendered that as "X: X", a line that says nothing twice. The figure-level branch of the description already showed only authored labels (DescriptionService.getFigureAxes), so gating here is what makes the two levels of the same dialog follow one rule.

      Blankness is tested with trim(), the same rule named applies when it decides whether to substitute the fallback in the first place. A whitespace-only z label is truthy but blank, so the untrimmed guard used to pass it through and then print the 'Level' placeholder the guard existed to keep out.

      Returns { x?: string; y?: string; z?: string }

    • Returns true if this trace supports point-by-point navigation mode. Opt-in per trace type: override to return true for traces that expose individual data points navigable in reading order (left/right) and column-major order (up/down). Currently only ScatterTrace.

      Returns boolean

    • Notifies the trace that the rotor is entering or leaving INTERSECTION_MODE. Default is a no-op; line-style traces don't need to track mode state because their state output is unchanged by the rotor mode. Traces whose audio/text output differs in intersection mode (e.g. ScatterTrace, which normally plays the whole x-column as a chord and must instead focus a single point) override this to flip an internal flag.

      Parameters

      • _enabled: boolean

        True when entering intersection mode, false when leaving.

      Returns void

    • Trace-specific rotor filter units appended to the rotor cycle after the built-in data/compare/grid/intersection modes. Each unit restricts navigation to points matching a predicate (e.g. only bullish candles). Default: none. Override to opt in (e.g. Candlestick exposes bullish/bearish/neutral units). The returned list is treated as read-only by the rotor service.

      Returns readonly RotorFilterUnit[]

    • Notifies the trace which of its getRotorFilterUnits the rotor is on, or null when it is on none of them. Default is a no-op: a unit usually changes only where Left and Right go, which moveToRotorFilter answers. A trace whose unit also changes what Control with them should reach -- a tree's Level, where Left and Right walk the whole level -- overrides this, because the jump is not routed through the rotor.

      Parameters

      Returns void

    • Moves within an active rotor filter unit along the filtered axis.

      Called by RotorNavigationService when the current rotor mode is one of this trace's getRotorFilterUnits. Filter units navigate a single axis, so only left/right are dispatched here — the service announces up/down as unavailable without calling the model (matching intersection mode). Implementations should move to the nearest point matching the unit identified by key and notify observers, returning true; when no such point exists they should call notifyRotorBounds and return false.

      Default is a no-op that reports bounds, so a trace advertising a filter unit but forgetting to implement movement fails safe (announces "no point found") rather than moving unexpectedly.

      Parameters

      • _key: string

        The RotorFilterUnit.key of the active unit

      • _direction: "left" | "right"

        The direction to search

      Returns boolean

      True if the cursor moved, false otherwise

    • Every object the o list offers on this chart, or null where there is none to offer.

      Null for every chart walked along x and y axes: the arrows already reach each point in order there, and a list of them would repeat the axis. A chart whose objects have no such order -- the nodes of a network, the tiles of a treemap -- overrides this and builds the list from its own structure, with the sorts and filters that make sense for it.

      List only, as the rotor units are, with no flag beside it: a flag that said yes over an empty list would open a dialog with nothing to choose. Labels are built on each call, because the trace outlives a change of language; anything expensive to compute is kept by the trace that computes it.

      Returns ChartObjectList | null

      The list, or null

    • Moves to the object the list knows by this key, announcing it through the usual observer chain.

      Looks the key up in a list built now rather than trusting a cell the dialog was handed when it opened, so a chart whose data changed under the dialog moves the reader to the object they chose or nowhere at all.

      Parameters

      • key: string

        The key the object list gave the object

      Returns boolean

      True when the cursor moved, false when no object has the key or its cell cannot be reached

    • Whether a mark of this trace sits at exactly this X, as moveToXValue finds one before it falls back to the nearest.

      A layer switch asks this to choose between the two X values a position can offer (see Trace.getAlternateXValue). Reads the x of each point; a trace that keeps its X some other way answers false unless it says otherwise, and the switch then carries what it always carried.

      Parameters

      • xValue: XValue

        The X a layer switch would carry

      Returns boolean

      True when some point's x is exactly xValue

    • Moves the active point to the pointer location and returns directional guidance toward the nearest data geometry in a single call.

      Combining both operations avoids running findNearestPoint twice per pointermove event — important on dense plots where the scan is the hot path.

      Parameters

      • x: number

        Screen-space x position of the pointer/finger

      • y: number

        Screen-space y position of the pointer/finger

      Returns PointerGuidanceState | null

      Guidance state relative to nearest point, or null when unavailable

    • Moves the trace to the nearest point when the pointer is within its bounds and the trace is not already focused on that point.

      onCurve is intentionally non-optional: the caller has already paid the cost of isPointInBounds to assemble guidance state, and forcing subclasses to accept the value makes the contract explicit so a future override cannot silently recompute (or worse, ignore) it.

      Subclasses override this to customise hover-driven navigation:

      • Box / ViolinBox no-op the move while still surfacing guidance.
      • Scatter switches into column navigation mode before delegating.

      Parameters

      Returns void

    • Checks if the specified coordinates are within bounds of the element.

      Parameters

      • x: number

        The x-coordinate

      • y: number

        The y-coordinate

      • element: NearestPoint

        Object containing the SVG element and its position

        • element: SVGElement
        • row: number
        • col: number
        • centerX: number
        • centerY: number

      Returns boolean

      True if the point is in bounds, false otherwise

    • Whether a series is listed from its right end to its left, and so is read turned round.

      False for a line: its points are walked in the order they are listed, which on a category axis is the order they are drawn in. A layer type whose producers may list a series either way round answers for it.

      Called from the constructor, before a subclass's own fields are set, so an override reads only the series it is given.

      Parameters

      • _series: readonly LinePoint[]

        The series' points, as listed

      Returns boolean

      True when the series is to be read in the reverse of its listed order

    • Name a line carries in the spec, or undefined when the data authors none. Consumers that have nothing meaningful to say without a real name (e.g. the position announcement) can then stay silent about groups.

      Protected for the same reason LineTrace.groupNameAt is: a subclass that names its series from its own data -- a contour from its level -- still has to answer for a series the layer named and nothing else did, and calling groupNameAt for that would recurse.

      Parameters

      • row: number

      Returns string | undefined

    • Human-readable name of a single line: the authored name when the spec provides one, otherwise a positional fallback ("Line 2").

      Protected rather than private because a subclass naming a series in its own description -- which competitor led, which observation is an outlier -- has to name it the way every other announcement does, and reaching for points[row][0].z directly would skip the fallback and report undefined for an unnamed series.

      The fallback takes its noun from LineTrace.seriesLabels rather than hardcoding the line's. A radar that renamed its series in the dialog still listed "Line 1, Line 2" under Series names, and put Line 1 in a column headed Series -- naming a chart type the reader is not on, and offering an index where a name was promised.

      Parameters

      • row: number

      Returns string

    • Gets the line series with human-readable labels. Used by the candlestick delta feature to list reference-line candidates (e.g., moving averages).

      Returns { label: string; points: readonly LinePoint[] }[]

      One entry per series with its label and points

    • Cleans up trace resources including values and highlighted SVG elements.

      Only removes elements MAIDR created (hidden clones, synthetic markers); traces that highlight the chart's original live elements in place (e.g. heatmap cells, line dots) merely drop their references so the visible chart geometry survives focusout and live-data rebuilds.

      Returns void

    • Where a cell sits in the stereo field.

      Split out because three places need it and they must agree: the tone for the cursor's own point, the tones of every series a chord sounds at an intersection, and the boundary tone of a move refused there. A subclass that hears its columns somewhere other than a straight left-to-right sweep -- a radar's spokes go out and back around a circle -- overrides this one method and all three follow, rather than one of them keeping the line's sweep and contradicting the others.

      Parameters

      • row: number

        The series index

      • col: number

        The column index

      Returns { y: number; x: number; rows: number; cols: number }

      The panning for that cell

    • Establishes the cursor on the first move into the trace.

      MovableGraph.handleInitialEntry tries (0, 0) and otherwise parks the cursor at (-1, -1). A ragged layer whose first series is empty -- a hue level with no data in the range, emitted before the ones that have some -- has points to land on all the same, so the cursor is moved to the first series that has any rather than left off the data.

      Returns void

    • Where an up or down move from the cursor lands.

      The series whose y at the cursor's own x is the nearest one in that direction, at the column carrying that x. Nothing at the cursor -- an empty series, or an entry that found no series at all -- has no x to match, so there is nowhere to go. A subclass whose series are not sampled at shared x values (a ROC curve, sampled at its own thresholds) overrides this to answer the same question by interpolation; moveOnce and isMovable ask only this.

      Parameters

      • direction: "UPWARD" | "DOWNWARD"

        UPWARD for the nearest series above, DOWNWARD for the nearest below

      Returns { row: number; col: number } | null

      The row and column to move to, or null when no series lies that way

    • Finds the column index for a given X value in a specific line Uses strict equality (===) for X value matching. Protected so a subclass that chooses the series differently (a radar, by series order) still finds that series' column the same way.

      Parameters

      • row: number

        The line index

      • xValue: string | number

        The X value to find

      Returns number

      The column index, or -1 if not found

    • Parameters

      • Optionalselectors: string[]

      Returns (SVGElement | SVGElement[])[][] | null

    • The elements whose geometry is the line itself, for renderers that need the drawn shape rather than the points on it.

      See lineElements for why the highlight markers are not that shape. Empty when this trace's markers are the chart's own, in which case the caller should fall back to them.

      Returns SVGElement[]

    • Records the stroke the chart drew through a series' own markers, when there is one to find.

      A chart that renders a dot per point usually draws the line through them as well, in the same group -- a radar's polygon, a Recharts line's path -- and that line is the series' shape where the dots are only its vertices. The selector named the dots, so the line is the one sibling of theirs that draws a stroke. It is offered as geometry so a renderer that wants the shape has it; nothing else about the trace reads it.

      Nothing is offered when the answer is unclear: markers spread over several groups, a group with two strokes in it (a line and its area), a stroke that does not reach the markers. A wrong shape on the display is worse than none.

      Parameters

      • markers: readonly SVGElement[]

        The chart's own elements for one series

      Returns void

    • Reconciles the vertices parsed out of a rendered <path> with the number of data points in a series, mutating coordinates in place so it ends up one entry per data point in data order.

      SVG renderers (e.g. Plotly) may simplify a path by dropping collinear vertices, leaving fewer coordinates than data points; those are recovered by interpolating along the surviving segments. Extra vertices are dropped from the end, which is right for a straight polyline whose vertices are its data points — subclasses whose rendered geometry has vertices that are not data points (see StepTrace) override this.

      Parameters

      • coordinates: LinePoint[]

        Vertices parsed from the path, mutated in place

      • row: number

        Index of the series these coordinates belong to

      Returns void

    • One vertex per data point, placed along an edge by x.

      Each point's x is mapped linearly from the series' x range onto [xMin, xMax], and its y is read off the edge there: at a vertex within snapWithin of that x, the vertex itself; otherwise interpolated along the segment that spans it. This is how a simplified path gets its dropped points back, and how a band drawn with more vertices than it has samples finds the samples among them (see AreaTrace).

      Parameters

      • edge: readonly LinePoint[]

        Vertices in drawing order

      • row: number

        Index of the series the edge belongs to

      • xMin: number

        The SVG x the series' first x maps onto

      • xMax: number

        The SVG x the series' last x maps onto

      • snapWithin: number = 0

        How close in x a vertex has to be to a point to stand in for it exactly; 0 always interpolates

      • Optionalonly: readonly number[]

        The indices of the points to place, in the order to place them; every point when omitted. The first and last of them map onto xMin and xMax.

      Returns LinePoint[]

      One vertex per data point placed, in the order placed

    • Returns { x: number; y: number; row: number; col: number; element: SVGElement }[] | null

    • Where a crossing strictly between two categories is, as the Go To dialog says it: the two categories and the value at the crossing.

      Parameters

      • from: string

        The category before the crossing

      • to: string

        The category after it

      • y: string

        The value at the crossing, formatted

      Returns string

      The coordinates, in the reader's language

    • Move the line plot to the position that matches the given X value

      Parameters

      • xValue: XValue

        The X value to move to

      Returns boolean

      true if the position was found and set, false otherwise

    • The rotor's LOWER and HIGHER VALUE search. The base is a no-op that reports the boundary: a trace that can compare overrides it, and supportsCompareMode offers the two modes exactly where it does.

      Parameters

      • direction: string
      • type: "lower" | "higher"

      Returns boolean

    • Moves up in rotor mode, optionally filtering by lower or higher values.

      Parameters

      • Optional_mode: "lower" | "higher"

        Optional mode for filtering (lower or higher)

      Returns boolean

      Error always - subclasses must override this method

    • Moves down in rotor mode, optionally filtering by lower or higher values.

      Parameters

      • Optional_mode: "lower" | "higher"

        Optional mode for filtering (lower or higher)

      Returns boolean

      Error always - subclasses must override this method

    • Intersection navigation mode is available only when the plot has multiple lines. points is a 2-D array whose outer dimension is the line index, so length > 1 means at least two lines exist — a prerequisite for any crossing between sampled series to be possible — and only where series meet at their values at all (seriesCanMeet).

      Returns boolean