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

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions