Pre loader

Tag: Drag

Welcome to the SciChart Forums!

  • Please read our Question Asking Guidelines for how to format a good question
  • Some reputation is required to post answers. Get up-voted to avoid the spam filter!
  • We welcome community answers and upvotes. Every Q&A improves SciChart for everyone

WPF Forums | JavaScript Forums | Android Forums | iOS Forums

1 vote

I have a chart with a box annotation. When I try to resize the box annotation by dragging the left or right border, I got the “Uncaught TypeError: Cannot read properties of undefined (reading ‘x’)”. It’s not always reproducible and cannot be reproduced by dragging the whole box. Also, it only occurs with SciChart version 3 but not SciChart version 2. Please check the screenshots for more details.

  • Quyen Sy asked 1 year ago
  • last active 1 year ago
1 vote

I have a chart that allow users to add one BoxAnnotation and multiple CustomAnnotation (a marker). I got error and failed to drag the BoxAnnotation with the following steps:

Step 1: Call the addMarkerAnnotation() to add a CustomAnnotation

const markerSvgString = '<svg height="26" width="18" xmlns="">' +
    '<polygon id="SVG_ID" fill="#000" fill-opacity="0.5" stroke="#00fc00" stroke-width="1.5" points="0,12 8,0 16,12 8,24" clip-path="url(#clip_normal)" />' +
    '<clipPath id="clip_normal"><use xlink:href="#SVG_ID"/></clipPath>' +
    '<text x="5" y="16" fill="#00fc00" font-weight="bold" font-size = "12">MARKER_ID</text>' +

const deltaSvgString = '<svg height="28" width="28" xmlns="">' +
    '<polygon id="SVG_ID" fill="#000" fill-opacity="0.5" stroke="#00fc00" stroke-width="1.5" points="0,0 12,24 22,0" clip-path="url(#clip_delta)" />' +
    '<clipPath id="clip_delta"><use xlink:href="#SVG_ID"/></clipPath>' +
    '<text x="5" y="10" fill="#00fc00" font-weight="bold" font-size="10">MARKER_ID</text>' +

const addMarkerAnnotation = useCallback((markerId, mode, x1, y1) => {   
    x1 = parseFloat(x1);
    y1 = parseFloat(y1);

    if (x1 != null && y1 != null) {
        let svgString;
        const svgId = "markerSvg_" + markerId;

        if (mode.includes("Delta")) {
            const compareMarkerKey = mode.replace("Delta ", "");
            svgString = deltaSvgString.replace(/MARKER_ID/g, (parseInt(markerId)+1) + "-" + compareMarkerKey);
        } else {
            svgString = markerSvgString.replace(/MARKER_ID/g, parseInt(markerId)+1);
        svgString = svgString.replace(/SVG_ID/g, svgId);

        markerAnnotations.current[markerId] = new CustomAnnotation({
            id: markerId,
            isEditable: true,
            isSelected: true,
            verticalAnchorPoint: EVerticalAnchorPoint.Center,
            horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
            svgString: svgString

        markerAnnotations.current[markerId].dragEnded.handlers.push(() => {
            let annotation = markerAnnotations.current[markerId];
            let freq = annotation.x1 * FREQ_UNITS.KHZ;

            markersInfoSetter.current[markerId](origMarkerInfo => ({...origMarkerInfo, ...{freq: freq.toFixed(numDP.FREQ), power: annotation.y1.toFixed(numDP.POWER)}}));

            if (markersInfoObj.current[markerId].mode !== "Fixed") {
                getMarkerPeak(markerId, markersInfoObj.current[markerId].trace, annotation.x1 * FREQ_UNITS.GHZ);
}, [deltaSvgString, markerSvgString, getMarkerPeak, reorderMarkers, numDP]);

Step 2: Call the removeMarkerAnnotation() to remove the CustomAnnotation

const removeMarkerAnnotation = useCallback((markerId) => {
    if (markerAnnotations.current[markerId]) {
        markerAnnotations.current[markerId] = null;
}, []);

Step 3: Call addTriggerAnnotation() to add a BoxAnnotation

const addTriggerAnnotation = useCallback((x1, x2, y2) => {
    x1 = parseFloat(x1);
    x2 = parseFloat(x2);    
    y2 = parseFloat(y2);

    if (x1 != null && x2 != null) {
        console.log("addTriggerAnnotation: ", x1, x2, triggerAnnotation.current, sciChartSurfaceRef.current.annotations);
        if (!triggerAnnotation.current) {
            triggerAnnotation.current = new BoxAnnotation({
                id: "triggerBox",
                fill: "transparent",
                stroke: "#93A3B1",  //#93A3B1   //#6B818C
                strokeThickness: 2,
                xCoordinateMode: ECoordinateMode.DataValue,
                x1: x1,
                x2: x2,
                yCoordinateMode: ECoordinateMode.DataValue,
                y1: minY,
                y2: y2,
                isEditable: true,
                resizeDirections: EXyDirection.XyDirection,     

            triggerAnnotation.current.dragDelta.handlers.push(() => {
                triggerAnnotation.current.y1 = minY;

                const minX =  specSettingsRef.current.start/freqUnits.KHZ;
                const maxX = specSettingsRef.current.stop/freqUnits.KHZ;
                const maxY = specSettingsRef.current.refLevel;

                if (minX != null && maxX != null) {
                    if (triggerAnnotation.current.x1 < minX) {
                        triggerAnnotation.current.x1 = minX;
                    } else if (triggerAnnotation.current.x1 > maxX) {
                        triggerAnnotation.current.x1 = maxX;
                    } else if (triggerAnnotation.current.x2 > maxX) {
                        triggerAnnotation.current.x2 = maxX;
                    } else if (triggerAnnotation.current.x2 < minX) {
                        triggerAnnotation.current.x2 = minX;

                if (maxY != null) {
                    if (triggerAnnotation.current.y2 < minY) {
                        triggerAnnotation.current.y2 = minY;
                    } else if (triggerAnnotation.current.y2 > maxY) {
                        triggerAnnotation.current.y2 = maxY;

            triggerAnnotation.current.dragEnded.handlers.push(() => {
                const maxX = specSettingsRef.current.stop/freqUnits.KHZ;
                const x1 = triggerAnnotation.current.x1;
                const x2 = triggerAnnotation.current.x2;
                const y2 = triggerAnnotation.current.y2;

                if (x1 != null && x2 != null && maxX != null) {
                    if (x1 > x2) {
                        triggerAnnotation.current.x1 = x2;
                        triggerAnnotation.current.x2 = x1;
                    } else if (x2 < x1) {
                        triggerAnnotation.current.x1 = x2;
                        triggerAnnotation.current.x2 = x1;
                    } else if (x1 === x2) {
                        if (x2 + xInterval.current <= maxX) {
                            triggerAnnotation.current.x2 = x2 + xInterval.current;
                        } else {
                            triggerAnnotation.current.x1  = x1 - xInterval.current;

                    const origStartFreq = parseFloat(triggersRef.current.startFreq);
                    const origStopFreq = parseFloat(triggersRef.current.stopFreq);
                    const newStartFreq = parseFloat((triggerAnnotation.current.x1 * freqUnits.KHZ).toFixed(numDP.FREQ));
                    const newStopFreq = parseFloat((triggerAnnotation.current.x2 * freqUnits.KHZ).toFixed(numDP.FREQ));

                    if (origStartFreq !== newStartFreq || origStopFreq !== newStopFreq) {
                        setTriggers(origObj => ({...origObj, ...{
                            startFreq: newStartFreq, 
                            stopFreq: newStopFreq,
                            level: parseFloat(y2.toFixed(numDP.POWER)),
        } else {
            updateTriggerAnnotation(x1, x2, y2);
}, [setTriggers, freqUnits.KHZ, numDP.FREQ, numDP.POWER, minY, updateTriggerAnnotation]);

Step 4: Drag the BoxAnnotation. It’s failed to drag the box and got the error “Uncaught TypeError: Cannot read properties of undefined (reading ‘seriesViewRect’)”.

It’s a strange bug as it can only be reproduced with the steps above. With the following steps, I can drag the BoxAnnoation without problem:

Step 1 -> Step 3 -> Step 4
Step 3 -> Step 4
Step 3 -> Step 1 -> Step 2 -> Step 4

  • Quyen Sy asked 1 year ago
  • last active 1 year ago
1 vote
0 answers


I have annotation, users can it drag and drop. But for it first need select this annotation and after drag it(with re-touching).
How to immediately drag annotation(without re-touching)?

Thanks in advance.


0 votes


I have a list of 12 items, but at the start I only want to see the last 6 items on the chart (stacked column chart). I want to be able to scroll / drag to reveal the first part of the list. I use the index of the list for the x-axis, so the list has indexes with range from [0, 11]

I’m having some weird behaviour implementing this.
When the data is loaded, i see the complete bars:

creenshot 2020-09-18 at 11.04.14.png

but when I start to scroll, i’m never able to reveal the complete bars anymore:
![Screenshot 2020-09-18 at 11.04.40.png][2]
![Screenshot 2020-09-18 at 11.04.59.png][3]

When i start scrolling to the end (although the chart is already at the end), the UI jumps and only shows half a bar. Also when i scroll to the beginning, it only shows half a bar.

How can I make sure I always see the complete bars?

This is the code, specific to the x axis & the scrolling:

val xAxis = sciChartBuilder.newNumericAxis()
            .withVisibleRange(5.5, 11.5)

using half values for the range seems to be the only way I can see the full bars. Once I start scrolling I only see half bars at the start & end

val surfaceChartModifiers: ChartModifierCollection = chart.chartModifiers
val dragModifier = XAxisDragModifier()
dragModifier.dragMode = AxisDragModifierBase.AxisDragMode.Pan

val zoomPanModifier = ZoomPanModifier()
zoomPanModifier.clipModeX = ClipMode.ClipAtExtents
zoomPanModifier.direction = Direction2D.XDirection
zoomPanModifier.zoomExtentsY = false
0 votes


I’m wanting to switch to SciChart from a previous charting library. One neat thing that our previous library did that I cannot figure out how to do in SciChart is change the interaction between tooltips/rollover and panning.

What I would like to do is Pan/Drag the chart on short tap events, and do a rollover or tooltip cursor on long tap events. By default it looks like I get rollover and panning together on any tap event, which is not ideal behavior for my apps. Depending on the tap event type, I would like to do just one or the other, not both. How can I do something similar with SciChart?

Thank you,

  • C Bolton asked 4 years ago
  • last active 4 years ago
0 votes

I have placed a VerticalLineAnnotation on chart surface along with AxisMarkerAnnotation on X-Axis. The X1 of axis marker is bound to the vertical line annotation’s X1 so that they can move together.

I have set IsEditable=”True” and DragDirections=”XDirection” for both – the line annotation & its axis marker so that user can drag the line on chart horizontally by holding the mouse on either the vertical line or its axis marker.

The drag operation works fine when user holds the vertical line with mouse and drags it. The mouse pointer and annotation move together happily.

However, the problem occurs when user holds on the axis marker and tries to drag. In this case, the mouse pointer remains way behind and the annotation moves ahead very fast. There is no sync between mouse pointer position and line annotation which becomes very bad experience for user. Is there any way to address this issue?

  • Anil Soman asked 5 years ago
  • last active 5 years ago
0 votes

Or say, how can I prevent movement of HorizontalLineAnnotation when dragging the grip of X1(typically the left grip)?

0 votes

Hello, I have added YAxisDragModifier and ZoomPanModifier to my surface and when I try to drag on Y axis I can move the X axis too and that is not the behavior that I was trying to get. I want when I drag/move YAxis not to move on the YAxis also.

Here is my code:

Surface.ChartModifiers.Add(new PinchZoomModifier());
Surface.ChartModifiers.Add(new ZoomExtentsModifier());
Surface.ChartModifiers.Add(new YAxisDragModifier { DragMode = AxisDragModifierBase.AxisDragMode.Pan });
Surface.ChartModifiers.Add(new XAxisDragModifier { DragMode = AxisDragModifierBase.AxisDragMode.Pan, ClipModeX = ClipMode.None });
Surface.ChartModifiers.Add(new ZoomPanModifier
Direction = Direction2D.XDirection,
ZoomExtentsY = false

Here is the video with the behavior:

Help please!

0 votes

Hi, Andrew. sorry to bother you.

if i changed the YValue by drag the point on series(—part-5—select-and-drag-a-data-point), i want to set data repository dirty. how to notify the viewmodel, by even, or binding. could you tell me the better( rational, even best ) way?

sorry, i’m a newer to WPF.

many thanks

0 votes

The second question is that I want drag a curve from one chart to another chart. i found no sample about that. what shall i do?

0 votes


I have a VerticalLineAnnotation that can be dragged over the chart by clicking and dragging on the line itself. (See attached image). The problem is, whenever I put the chart in front of a user, they try to drag by clicking on the label (the blue label with the time in the image).

How can I make this label draggable like the line?


0 votes

I have a set of ChartModifiers on my SciChartSurface, carefully configured to work together like so:

        <s:LegendModifier x:Name="LegendModifier" />
        <s:ZoomPanModifier ExecuteOn="MouseRightButton" ClipModeX="None" />
        <s:RubberBandXyZoomModifier ExecuteOn="MouseLeftButton" />
        <s:SeriesSelectionModifier />
        <s:ZoomExtentsModifier ExecuteOn="MouseDoubleClick" />
        <s:MouseWheelZoomModifier />

I also have a pair of VerticalLineAnnotations, which I create in the C#. These are used to select points on the series that has been selected with the SeriesSelectionModifier.

The problem is that after the sliders are dragged, the mouse up event causes the selected series to be unselected. How can I prevent this from happening?

Showing 12 results

Try SciChart Today

Start a trial and discover why we are the choice
of demanding developers worldwide

Start TrialCase Studies