Skip to content

Assignment typo in RolloverMarkerSvgAnnotation.create (currentColor === color) — rollover marker SVG destroyed and re-created on every mousemove (4.0.944 → 5.2.35 → 6.0.0-alpha) #290

@nikeo01

Description

@nikeo01

Summary

RolloverMarkerSvgAnnotation.create contains an assignment typo — this.currentColor === color; (a no-op comparison) where this.currentColor = color; was clearly intended. As a result currentColor is never assigned, the "color changed" check at the top of create() is always true, and the rollover marker SVG node is destroyed and re-created on every single update — i.e. on every mousemove over the chart, for every rollover-enabled series.

Affected versions

Verified present in the published npm packages:

  • 4.0.944
  • 5.2.35 (latest stable at the time of writing)
  • 6.0.0-alpha.120

The bug

Charting/Visuals/Annotations/RolloverMarkerSvgAnnotation.js (line numbers from 5.2.35):

RolloverMarkerSvgAnnotation.prototype.create = function (xCalc, yCalc, xCoordSvgTrans, yCoordSvgTrans) {
    var _a = this.tooltipProps, tooltipColor = _a.tooltipColor, markerColor = _a.markerColor;
    var color = markerColor !== null && markerColor !== void 0 ? markerColor : tooltipColor;
    if (this.svg && this.currentColor !== color) {   // ← always true: currentColor is never set
        this.clear();
    }
    if (!this.svg) {
        this.currentColor === color;                 // ← line 54: comparison, no effect (typo for `=`)
        var svgString = tooltipSvgTemplate(color);
        var clippedSvgString = this.applyClipping(svgString, this.clipping);
        var svgNode = annotationHelpers_1.annotationHelpers.createSvg(clippedSvgString, this.svgRoot, this.nextSibling);
        this.setSvg(svgNode);
    }
};

Since this.currentColor stays undefined forever:

  1. First update: svg is undefined → marker SVG created (but currentColor not recorded).
  2. Every subsequent update while the mouse is in the series area: this.svg && this.currentColor !== colorclear() removes the SVG node → re-created via createContextualFragment + DOM insertion.

So each mousemove pays one fragment parse + node removal + node insertion per rollover marker, forever. The marker is tiny, but the DOM/GC churn is measurable on busy pages and it defeats the entire purpose of the currentColor caching check.

Measured impact

Instrumented Range.prototype.createContextualFragment in a real application (one rollover-enabled series): exactly 1 marker SVG re-creation per mousemove. After patching the assignment (workaround below): 1 creation per session, marker repositioned via attributes as intended.

Suggested fix

this.currentColor = color;

Workaround we currently use

import { RolloverMarkerSvgAnnotation } from 'scichart';

const proto = RolloverMarkerSvgAnnotation.prototype as any;
const origCreate = proto.create;
proto.create = function (...args: unknown[]) {
  origCreate.apply(this, args);
  this.currentColor = this.tooltipProps.markerColor ?? this.tooltipProps.tooltipColor;
};

Related

While verifying this against 5.2.35 we also confirmed that the label cache texture poisoning reported in #289 is fixed in 5.2.35 (the deleteSafe call on entry replacement in LabelCache.setLabel is commented out there) — that one only affects the 4.x line.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions