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="http://www.w3.org/2000/svg">' +
'<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>' +
'</svg>';
const deltaSvgString = '<svg height="28" width="28" xmlns="http://www.w3.org/2000/svg">' +
'<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>' +
'</svg>';
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({
x1,
y1,
id: markerId,
isEditable: true,
isSelected: true,
verticalAnchorPoint: EVerticalAnchorPoint.Center,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
svgString: svgString
});
sciChartSurfaceRef.current.annotations.add(markerAnnotations.current[markerId]);
reorderMarkers(markerId);
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);
}
reorderMarkers(markerId);
});
}
}, [deltaSvgString, markerSvgString, getMarkerPeak, reorderMarkers, numDP]);
Step 2: Call the removeMarkerAnnotation() to remove the CustomAnnotation
const removeMarkerAnnotation = useCallback((markerId) => {
if (markerAnnotations.current[markerId]) {
sciChartSurfaceRef.current.annotations.remove(markerAnnotations.current[markerId]);
markerAnnotations.current[markerId].delete();
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,
});
sciChartSurfaceRef.current.annotations.add(triggerAnnotation.current);
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 2 years ago
- last edited 2 years ago
- Hi Quyen, when requesting support could you please (1) format code correctly, use the code button or indent four spaces to format a code sample. (2) if you have a complete code sample to share with us that our engineers can just run, it would help. This can be a GitHub repo with an npm project, or it can be shared via codesandbox.io or just a zip file uploaded. This will save our engineers time trying to reproduce your problems & result in a faster turnaround. Best regards, Andrew
- Hi Andrew, thanks for your reminder for how to format the codes in the question. As the complete codes is complicated and contain many non related codes. I tried to show you segments of codes which related to the issue. I updated the my question to show the complete functions, hope it can help. Or could you let me know what more info do you need?
- Hi Quyen, we’re going to try to reproduce this from the code provided. I’ll ask if we need more info. Thanks, Andrew
- You must login to post comments
Hi Quyen,
The error you get “can’t read properties of undefined reading seriesViewRect at SvgAnnotationBase.onDragStarted” means that the BoxAnnotation’s parentSurface property is undefined. Which probably means that the annotation is not attached to the SciChartSurface any more. Therefore, something must be happening that removes the BoxAnnotation in this particular order of steps 1 – 4. I went through the code you provided and have not found any issues. The problem might be specific to the React code. In order to proceed with your issue please provide a minimal example which we can run and reproduce the problem. Please use any of these examples as a template.
- Michael Klishevich answered 2 years ago
- last edited 2 years ago
- You must login to post comments
Please login first to submit.