The annotations API allows you to mark any annotation as editable by setting isEditable true. Editable annotations can be selected and dragged, and some can be resized. This page describes how you can respond to a user's interaction with an annotation, and how to customise the style of the selected view of the annotation.
Annotation Interactions
All annotations have the following properties and events which can be used to run code on user interaction:
| AnnotationBase Property | Description |
| isEditable | When true, an annotation is editable. It may be selected, dragged or resized. Individual behaviours can be controlled by the following properties. |
| isSelected |
Set true when an editable annotation is clicked. This causes the selection box and the drag points to be shown. These are known as the adorners. Setting this programatically is not advised |
| selectedChanged |
An event that is fired when isSelected changes. |
| dragStarted / onDragStarted |
dragStarted is an event which fires on mouseDown of an editable annotation. This is fired by the call to onDragStarted which is overridden in various annotations to determine which dragging point is being used, setting the adornerDraggingPoint property. If this is not set, dragging will not be performed. You can pass a callback for the event via the onDragStarted property of the IAnnotationsBase options object when constructing. |
|
dragDelta / onDragAdorner
|
dragDelta is the event which fires during dragging. This is fired by the call to onDragAdorner which translates the mouse point to xy coordinates and calls calcDragDistance, which is where the coordinates of the annotation are updated. You can pass a callback for the event via the onDrag property of the IAnnotationsBase options object when constructing. |
| dragEnded / onDragEnded |
dragDelta is an event which is fires on mouseUp when dragging has finished. This is fired by the call to onDragEnded. You can pass a callback for the event via the onDragEnded property of the IAnnotationsBase options object when constructing. |
| resizeDirections | Controls which direction an annotation may be resized in, e.g. X, Y or Xy |
Enabling and Subscribing to Drag Events in Annotations
Below is an example of how to enable editing (dragging) on a TextAnnotation, as well as how to get a callback on when the annotation is updated.
Try it out below by dragging the annotation.
<div id="scichart-root"></div>
body {
margin: 0;
}
#scichart-root {
width: 100%;
height: 100vh;
}
const {
TextAnnotation,
NumericAxis,
SciChartSurface,
SciChartJsNavyTheme,
ECoordinateMode,
EHorizontalAnchorPoint,
} = SciChart;
// or for npm import { SciChartSurface, ... } from "scichart"
async function addAnnotationToChart(divElementId) {
const { wasmContext, sciChartSurface } = await SciChartSurface.create(
divElementId,
{
theme: new SciChartJsNavyTheme(),
}
);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext));
// #region ExampleA
// A TextAnnotation which can be dragged and updates its value on drag
const textAnnotation = new TextAnnotation({
x1: 1,
y1: 3,
fontSize: 24,
fontFamily: "Arial",
text: "{{ DRAG ME! }}",
isEditable: true,
});
textAnnotation.dragDelta.subscribe((args) => {
textAnnotation.text = `I was dragged to ${textAnnotation.x1.toFixed(
2
)}, ${textAnnotation.y1.toFixed(2)}`;
});
sciChartSurface.annotations.add(textAnnotation);
// #endregion
const addChartTitle = (sciChartSurface, titleText, subTitleText) => {
sciChartSurface.annotations.add(
new TextAnnotation({
text: titleText,
x1: 0.5,
y1: 0.5,
yCoordShift: -50,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.5,
fontSize: 32,
fontWeight: "Bold",
textColor: "White",
})
);
sciChartSurface.annotations.add(
new TextAnnotation({
text: subTitleText,
x1: 0.5,
y1: 0.5,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.4,
fontSize: 17,
textColor: "White",
})
);
};
addChartTitle(
sciChartSurface,
"Editable Text Annotations",
"Drag the text annotation to see the value update"
);
}
addAnnotationToChart("scichart-root");
Dragging to discrete values
Sometimes you want an annotation to snap to particular values as you drag. The way to do this is to override onDragAdorner and convert to discete points there, then pass these to calcDragDistance. Here is an example of an AxisMarkerAnnotation that can only take discrete values, from our Rich Interactions Demo.
Try it out below by dragging the axis marker:
<div id="scichart-root"></div>
body {
margin: 0;
}
#scichart-root {
width: 100%;
height: 100vh;
}
const {
AxisMarkerAnnotation,
NumericAxis,
SciChartSurface,
SciChartJsNavyTheme,
AnnotationDragDeltaEventArgs,
TextAnnotation,
ECoordinateMode,
EHorizontalAnchorPoint,
Point,
} = SciChart;
// or for npm import { SciChartSurface, ... } from "scichart"
// #region ExampleA
class DiscreteAxisMarker extends AxisMarkerAnnotation {
stepSize = 1;
minValue = 0;
maxValue = 10;
constructor(options) {
super(options);
}
onDragAdorner(args) {
super.onDragAdorner(args);
const xyValues = this.getValuesFromCoordinates(args.mousePoint, true);
if (xyValues) {
let { x, y } = xyValues;
if (this.x1 !== undefined) {
x = Math.floor(x / this.stepSize) * this.stepSize;
} else if (this.y1 !== undefined) {
y = Math.floor(y / this.stepSize) * this.stepSize;
}
this.calcDragDistance(new Point(x, y));
if (this.x1 !== undefined) {
this.x1 = Math.min(Math.max(this.x1, this.minValue), this.maxValue);
} else if (this.y1 !== undefined) {
this.y1 = Math.min(Math.max(this.y1, this.minValue), this.maxValue);
}
}
this.dragDelta.raiseEvent(new AnnotationDragDeltaEventArgs());
}
}
// Now add to the SciChartSurface
// sciChartSurface.annotations.add(new DiscreteAxisMarker({ y1: 5, formattedValue: "Drag Me!" }));
// #endregion
async function addAnnotationToChart(divElementId) {
const { wasmContext, sciChartSurface } = await SciChartSurface.create(
divElementId,
{
theme: new SciChartJsNavyTheme(),
}
);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext));
sciChartSurface.annotations.add(
new DiscreteAxisMarker({
isEditable: true,
y1: 5,
formattedValue: "Drag Me!",
})
);
const addChartTitle = (sciChartSurface, titleText, subTitleText) => {
sciChartSurface.annotations.add(
new TextAnnotation({
text: titleText,
x1: 0.5,
y1: 0.5,
yCoordShift: -50,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.5,
fontSize: 32,
fontWeight: "Bold",
textColor: "White",
})
);
sciChartSurface.annotations.add(
new TextAnnotation({
text: subTitleText,
x1: 0.5,
y1: 0.5,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.4,
fontSize: 17,
textColor: "White",
})
);
};
addChartTitle(
sciChartSurface,
"Discrete Draggable Annotations",
"Drag the axis marker annotation to see the value update"
);
}
addAnnotationToChart("scichart-root");
Limiting Resize to Specific Directions (x,y)
Another property of interactable annotation is the dimension where it can be moved or resized. By default it is possible to move a BoxAnnotation towards each side of the chart. In the next example we will demonstrate a usage of the AnnotationBase.resizeDirections property. We will limit the annotation to resize and move only along the X Axis.
It is also possible to restrict the drag direction of the box annotation by subscribing to the dragDelta event callback. Find an example below.
This results in the following output
<div id="scichart-root"></div>
body {
margin: 0;
}
#scichart-root {
width: 100%;
height: 100vh;
}
const {
BoxAnnotation,
TextAnnotation,
EXyDirection,
ECoordinateMode,
EHorizontalAnchorPoint,
NumericAxis,
SciChartSurface,
SciChartJsNavyTheme,
} = SciChart;
// or for npm import { SciChartSurface, ... } from "scichart"
async function addAnnotationToChart(divElementId) {
const { wasmContext, sciChartSurface } = await SciChartSurface.create(
divElementId,
{
theme: new SciChartJsNavyTheme(),
}
);
sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
sciChartSurface.yAxes.add(new NumericAxis(wasmContext));
// #region ExampleA
// A box annotation which can only be dragged in the X-direction
const boxAnnotation = new BoxAnnotation({
x1: 3,
x2: 7,
y1: 3,
y2: 7,
isEditable: true,
isSelected: true,
// Restricts resize direction in the X-direction only
resizeDirections: EXyDirection.XDirection,
});
// Restricts drag direction in the X-direction only
boxAnnotation.dragDelta.subscribe((arg) => {
boxAnnotation.y1 = 3;
boxAnnotation.y2 = 7;
});
sciChartSurface.annotations.add(boxAnnotation);
// #endregion
const addChartTitle = (sciChartSurface, titleText, subTitleText) => {
sciChartSurface.annotations.add(
new TextAnnotation({
text: titleText,
x1: 0.5,
y1: 0.5,
yCoordShift: -50,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.5,
fontSize: 32,
fontWeight: "Bold",
textColor: "White",
})
);
sciChartSurface.annotations.add(
new TextAnnotation({
text: subTitleText,
x1: 0.5,
y1: 0.5,
xCoordinateMode: ECoordinateMode.Relative,
yCoordinateMode: ECoordinateMode.Relative,
horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
opacity: 0.4,
fontSize: 17,
textColor: "White",
})
);
};
addChartTitle(
sciChartSurface,
"Restricting Resize Direction",
"Resize the Box in the X-Direction only"
);
}
addAnnotationToChart("scichart-root");
async function builderExample(divElementId) {
// #region ExampleB
const { chartBuilder, EAnnotationType } = SciChart;
// or for npm import { SciChartSurface, ... } from "scichart"
const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(
divElementId,
{
annotations: [
{
type: EAnnotationType.RenderContextBoxAnnotation,
options: {
x1: 3,
x2: 7,
y1: 3,
y2: 7,
isEditable: true,
isSelected: true,
// custom resize direction
resizeDirections: EXyDirection.XDirection,
},
},
],
}
);
// #endregion
}
// Uncomment this to use the builder example //builderExample("scichart-root");