Pre loader

Tag: CustomAnnotation

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
1k views

I want to make label on yAxis.
SCIChart provides AxisMarkerAnnotation, but I want to use CustomAnnotation because I need something custom.
So I tried drawing a CustomAnnotation on the yAxis but failed.
Android succeeds in drawing CustomAnnotation on the yAxis using the method below, but iOS doesn’t provide it?
On iOS, Can’t customAnnotation only set the value of the yAxis like AxisMarkerAnnotation?
Android was possible…

error message like this
Exception raised with reason: CALayer position contains NaN: [nan 248.71]. Layer: <CALayer:0x280c10bc0; position = CGPoint (0 0); bounds = CGRect (0 0; 0 0); delegate = <BTChart.CurrentPriceAnnotationView: 0x13d74d8f0; frame = (0 0; 0 0); layer = <CALayer: 0x280c10bc0>>; sublayers = (<_UILabelLayer: 0x282d15860>); opaque = YES; allowsGroupOpacity = YES; >

1 vote
1k views

As if right now, I have create a custom annotation, which is a red circle and the idea is to show some info when hovering on it, like a tooltip.

Right now, when hovering on the red circle, I am adding another custom annotation to show the info and then removing it when not hovering anymore. The issue with this is that it is not very stable, as in if I don’t point my cursor right in the middle of the red circle, it won’t register as hit. I tried putting hitTestRadius to 50 on CursorModifier, but doesn’t seem to make any difference.

I have also try with xyScatterRenderableSeries and EllipsePointMarker, the issue I find with it is that it is interfering with my data series tooltip, as the cursor modifier recognize it as a chart series and try to show on the tooltip, which I don’t want. I only want the red circle to be trigger only when cursor is right on it.

The first image is my code and how I am trying to achieve it at the moment, it does work, but I don’t think it’s very stable, I wish there is a more natural way to do it.

The second image is how my current solution looks like, as you can see, the data series tooltip is overlapping it, which I want to avoid. I can’t think of a way to solve the overlapping issue yet. Other than unstableness and the tooltip overlapping, it work fine.

The third image is how I want it to look like.

  • Nung Khual asked 5 months ago
  • last active 5 months ago
1 vote
5k views

Hello support team,

I’m using a SciChartSurface Chart with a CategoryDateTimeAxis (xAxis).
The chart should contain three stacked bar columns and Annotations between the columns.

How can I place the Annotations exactly between the columns with consideration of the dynamic width of chart surface? I haven’t found the exactly property or solution for this particular case.

Thanks for your support in advanced!

1 vote
4k views

How can we change the color(Red) of custom box annotation when it is clicked .
thanks

1 vote
8k views

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 1 year ago
  • last active 1 year ago
1 vote
5k views

Previously I used AnnotationCreationModifier and my custom annotations were added by one left button mouse click on the chart surface (the annotation was added to the collection and the event handler “AnnotationCreated” fired). Now I’m trying to switch to using the mvvm pattern and I have problems adding my custom annotations using AnnotationCreationModifierMVVM.

Now it works like this:
1) I click (mouse left button) on the chart surface to add an annotation and it is added to the collection and displayed.
2) I click on the chart surface again, and only after that the event handler “AnnotationCreated” is called.

If I carry out some external manipulations with the added annotation between first and second click (for example, moving to the given coordinates by the button click), annotation moved, but when I hover the mouse over the chart surface, it returns to it’s original position. And this behavior will be until I click again on the chart surface so that the event handler “AnnotationCreated” is called.

The built-in annotations work fine though (for examle, VerticalLineAnnotationViewModel or HorizontalLineAnnotationViewModel are successfully added to the collection and call the event handler “AnnotationCreated” by one click on chart surface).

Is it possible to somehow fix this behavior of the custom annotation so that it is added to the collection and triggers an event “AnnotationCreated” for one click on the chart surface, as was the case with AnnotationCreationModifier? I am attaching an example code:

MainWindow.xaml

<Window x:Class="WpfAppMvvm.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
    xmlns:ext="http://schemas.abtsoftware.co.uk/scichart/exampleExternals"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <s:SciChartSurface Annotations="{s:AnnotationsBinding Annotations}">
        <s:SciChartSurface.XAxis>
            <s:NumericAxis AxisTitle="X"/>
        </s:SciChartSurface.XAxis>
        <s:SciChartSurface.YAxis>
            <s:NumericAxis AxisAlignment="Left" AxisTitle="Y"/>
        </s:SciChartSurface.YAxis>
        <s:SciChartSurface.ChartModifier>
            <s:ModifierGroup>
                <s:AnnotationCreationModifierMVVM IsEnabled="True" AnnotationViewModelsCollection="{Binding Annotations}" AnnotationViewModelType="{Binding AnnotationType}">
                    <i:Interaction.Behaviors>
                        <ext:EventToCommandBehavior Command="{Binding AnnotationCreatedCommand}" Event="AnnotationCreated" PassArguments="True"/>
                    </i:Interaction.Behaviors>
                </s:AnnotationCreationModifierMVVM>
            </s:ModifierGroup>
        </s:SciChartSurface.ChartModifier>
    </s:SciChartSurface>
</Grid>

MainWindow.xaml.cs

using System.Windows;
namespace WpfAppMvvm
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowViewModel();
        }
    }
}

MainWindowViewModel.cs

using SciChart.Charting.ChartModifiers;
using SciChart.Charting.Common.Helpers;
using SciChart.Charting.Model.ChartSeries;
using SciChart.Examples.ExternalDependencies.Common;
using System;
using System.Collections.ObjectModel;
using System.Windows;
namespace WpfAppMvvm
{
    internal class MainWindowViewModel:BaseViewModel
    {
        public ObservableCollection<IAnnotationViewModel> Annotations { get; private set; }
        public Type AnnotationType { get; private set; }
        public ActionCommand<AnnotationCreationMVVMArgs> AnnotationCreatedCommand { get; private set; }

        public MainWindowViewModel()
        {
            Annotations = new ObservableCollection<IAnnotationViewModel>();
            AnnotationType = typeof(MyCustomAnnotationViewModel);
            AnnotationCreatedCommand = new ActionCommand<AnnotationCreationMVVMArgs>(ExecCmd, e => true);
        }
        private void ExecCmd(AnnotationCreationMVVMArgs e)
        {
            MessageBox.Show("OnAnnotationCreated executed");
        }
    }
}

MyCustomAnnotation.xaml

<s:CustomAnnotationForMvvm x:Class="WpfAppMvvm.MyCustomAnnotation"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
         d:DesignHeight="450" d:DesignWidth="800">
<Grid>
    <Ellipse
        Width="20"
        Height="20"
        Fill="Transparent"
        Stroke="Red"
        StrokeThickness="3"
    />
</Grid>

MyCustomAnnotation.xaml.cs

using SciChart.Charting.Visuals.Annotations;

namespace WpfAppMvvm
{
    public partial class MyCustomAnnotation : CustomAnnotationForMvvm
    {
        public MyCustomAnnotation()
        {
            InitializeComponent();
        }
    }
}

MyCustomAnnotationViewModel.cs

using SciChart.Charting.Model.ChartSeries;
using System;

namespace WpfAppMvvm
{
    public class MyCustomAnnotationViewModel:CustomAnnotationViewModel
    {
    public override Type ViewType => typeof(MyCustomAnnotation);
    }
}
0 votes
0 answers
2k views

Hi All,
Im trying to kind of reproduce trademarkers example, but i cant get the datacontext of Annotation bound to show the tooltip data.

this is the way im doing things:

first i let the user select an area to place a box annotation via SimpleSelectionModifier

View XAML

s:SciChartSurface x:Name="_chart" Annotations="{s:AnnotationsBinding Annotations}"
   <!-- axis not showed for legibility !--
    s:SciChartSurface.ChartModifier 
      s:ModifierGroup
          mods:SimpleSelectionModifier IsEnabled="{Binding EnableAnnotation}"
                             i:Interaction.Triggers
                                i:EventTrigger EventName="RangeSelected"  
                                                            SourceObject="{Binding RelativeSource={RelativeSource  AncestorType={x:Type 
                                                                                            mods:SimpleSelectionModifier }}}"
                                    prism:InvokeCommandAction Command="{Binding RangeSelectedEvent}"  TriggerParameterPath="Coordinates"/
                               /i:EventTrigger
                            /i:Interaction.Triggers
                        /mods:SimpleDataPointSelectionModifier
        /s:ModifierGroup
       /s:SciChartSurface.ChartModifier
/s:SciChartSurface

On the VieModel side i’ve got this property to save CustomAnnotationViewmodels , bound to the scichart.Annotations property

private ObservableCollection<IAnnotationViewModel _annotations = new   ObservableCollection<IAnnotationViewModel>();
public ObservableCollection<IAnnotationViewModel> Annotations
 {
    get { return _annotations; }
    set { SetProperty(ref _annotations, value); }
}

and this Command executed on the rangeSelectedEvent when i create the annotation on the coordinates selected by the user viewmodel and add some custom ddata

   void ExecuteRangeSelectedEvent(Coordinates parameter)
        {
            var annotation = new CustomAnnotationViewModel
            {
                IsEditable = true,
                CanEditText = true,

                X1 = parameter.X1,
                X2 = parameter.X2,
                Y1 = parameter.Y1,
                Y2 = parameter.Y2,
                Data = new Data("test", "text tooltip", DataType.CoolData)
            };
            Annotations.Add(annotation);
            EnableAnnotation = false;
        }

The CustomAnnotationViewModel is based on the BuyMarkerAnnotationViewModel of the tradeMarkers Example.

and interface to support Data management and CustomAnnottionVIewModel that implementado the interface

public interface ISupportData : IAnnotationViewModel
{
    Data Data { get; set; }
}

 public class CustomAnnotationViewModel : CompositeAnnotationViewModel,  ISupportData
{
    private Wave _data;

    public Wave Data
    {
        get { return _data; }
        set
        {
            _data = value;
            OnPropertyChanged("Data");
        }
    }

    public override Type ViewType
    {
        get { return typeof(CustomAnnotation); }
    }
}

and finally de XAML on CustomAnnotation where everything should be bound

 s:CompositeAnnotation x:Class="CustomAnnotation"
                           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                           xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
                           X1="{Binding X1, Mode=TwoWay}"
                           Y1="{Binding Y1, Mode=TwoWay}"
                           X2="{Binding X2, Mode=TwoWay}"
                           Y2="{Binding Y2, Mode=TwoWay}"
                           AnnotationCanvas="BelowChart"
                           IsEditable="true"

        s:CompositeAnnotation.Annotations 
            s:BoxAnnotation Background="Coral"
                             CoordinateMode="Relative"
                             Opacity="0.3"
                             X1="0"
                             X2="1"
                             Y1="0"
                             Y2="1" /
            s:LineArrowAnnotation CoordinateMode="Relative"
                                   Stroke="Coral"
                                   StrokeDashArray="2,4"
                                   StrokeThickness="1"
                                   X1="0"
                                   X2="1"
                                   Y1="0.5"
                                   Y2="0.5" /
            s:LineArrowAnnotation CoordinateMode="Relative"
                                   Stroke="Coral"
                                   StrokeDashArray="2,4"
                                   StrokeThickness="1"
                                   X1="0.5"
                                   X2="0.5"
                                   Y1="0"
                                   Y2="1" /
            s:TextAnnotation x:Name="MeasureText"
                              Background="CornflowerBlue"
                              CoordinateMode="Relative"
                              CornerRadius="3"
                              Foreground="White"
                              HorizontalAnchorPoint="Center"
                              X1="0.5"
                              Y1="1"

              ToolTipService.ToolTip
                    ToolTip Foreground="#222"
                        Grid Margin="6" DataContext="{**Binding Data**}"
                            Grid.RowDefinitions
                                RowDefinition Height="Auto" /
                                RowDefinition Height="Auto" /

                            /Grid.RowDefinitions
                            Grid.ColumnDefinitions
                                ColumnDefinition Width="Auto" /
                                ColumnDefinition Width="Auto" /
                                ColumnDefinition Width="Auto" /
                            /Grid.ColumnDefinitions
                            TextBlock Grid.Row="0" Grid.Column="0" Text="Type: " /
                            TextBlock Grid.Row="1" Grid.Column="0" Text="Text: " /
                            TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Type}" Foreground="#FF00B400"/
                            TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LabelText}" /

                        /Grid
                    /ToolTip
                /ToolTipService.ToolTip
            /s:TextAnnotation
        /s:CompositeAnnotation.Annotations
    /s:CompositeAnnotation

I dont mind if everything is shown on tooltip or other way. but when oi run it a get this binding error.

Data is not found on ViewModel

Any ideas? Can anybody see where im making a mistake?
any help would be very appreciated.
thanks

1 vote
6k views

Hello,

I want my HeatmapColorMap to be part of my chart, so that when I export it, the HeatmapColorMap is visible on the PNG / XPS.
In order to this, I put the HeatmapColorMap inside a CustomAnnotation.
I can see it nicely on my Surface but when I try to export it as XPS or as PNG with some specific size, the numbers and ticks have disappeared, only leaving the rectangle with color gradient (see attached picture)
Is there a way to solve this ?

Thank you !

0 votes
6k views

SciChart supports exporting to BitmapSource at a specific size, however, this feature does not work for us because we are using custom types for our chart annotations, and we get the following error:

“Please be advised that SciChart doesn’t handle serialization of objects with properties of interface type, collection type or custom type. You need to implement IXmlSerializable in such objects to have them handled properly.”

We haven’t found any example of how to implement IXmlSerializable in on custom type, and were wondering if some guidelines about what is needed to implement that interface could be provided.

The custom type that we are using is an AnnotatedPointMarker, which inherits the sci chart interface IPointMarker. It consists on a square, marking a data point, plus a text annotation on top, and a small line joining the square and the text.

  • malú Diaz asked 2 years ago
  • last active 2 years ago
0 votes
7k views

Hi,

There is a strange displaying behavior of custom annotation. I added custom annotation using the code below.

let imageView = UIImageView(image: UIImage(named: imageName))
imageView.frame = CGRect(origin: .zero, size: CGSize(width: 10, height: 10))

let customAnnotation = SCICustomAnnotation()
customAnnotation.customView = imageView
customAnnotation.verticalAnchorPoint = .bottom
customAnnotation.horizontalAnchorPoint = .center
customAnnotation.set(x1: xCoordinate)
customAnnotation.set(y1: yCoordinate)
sciChartSurface?.annotations.add(items: customAnnotation)

The result looks good, but when I move surface left and right, custom annotation would go outside of bounds. Like the image I uploaded.

Please help me solve the issue.

Thanks.

0 votes
8k views

I would like to be able to use a triangle annotation that has a size parameter, so that I can add triangles of different sizes to chart.
I have seen the “Trade Markers” example that uses custom annotations defined by a path. But those annotations are a fixed size. How can I give them a size parameter?

I have tried this, but the point of the triangle doesn’t align with the X value, instead the triangle starts to the right of the X value.
public static CustomAnnotation UpTriangle(int x, double y, double size, Brush color, string axis)
//——————————————————————————————————————-
{
PointCollection myPointCollection = new PointCollection
{
new Point(0, 0),
new Point(1, 1),
new Point(-1, 1)
};

  return new CustomAnnotation()
  {
    X1 = x,
    Y1 = y,

    Content = new Polygon()
    {
      Points = myPointCollection,
      Height = size,
      Width = size,
      Stretch = Stretch.Fill,
      Fill = color,
      Stroke = color,
      StrokeThickness = 1,
    },
    YAxisId = axis
  };
}

Thank you for your help.

  • Steven M asked 4 years ago
  • last active 4 years ago
0 votes
0 answers
10k views

Hi SciChart,

Our requirement is to have polygon shapes be drawn at runtime, and to have a “rich” tooltip display for the user when the user hovers over one of these polygons.

Using a CustomRenderableSeries, we’re able to plot polygons, each as its own CustomRenderableSeries. The tooltip displays on a mouse hover when the mouse is within a few pixels of the edge of polygon, but it does not display when the mouse hover is in the middle of a polygon.

We have also explored creating CustomAnnotations of these polygonal shapes – however, the CustomAnnotation object type does not have a ‘Path’ or ‘Points’ property as is shown in the arrow shapes declared in the XAML of the ‘Annotations are Easy’ WPF example. Because we won’t know the paths of these shapes until runtime, this does not meet our requirement.

Is there a way to have tooltips appear within polygons, or a way to assign ‘Path’ data to a CustomAnnotation? Or any other ChartModifier that might suit our needs?

Thanks!
Matt

0 votes
10k views

Hi,

I’m trying to follow the instructions here: https://www.scichart.com/documentation/v5.x/Tutorial%2007%20-%20Adding%20Annotations.html
to create a subclass of CustomAnnotation. I have copied the attributes given in the example (VerticalAnchorPoint=”Bottom” HorizontalAnchorPoint=”Center”) but I still get the error “An attribute name is missing” on anything I put after the attributes. Are there other attributes that may be required for CustomAnnotation, not given in this example?

Thanks,
Rachel

0 votes
5k views

EDIT 3:

I figured out the problem. The reason why I did not see them was two-fold. The annotation view for some reason cannot infere the height of the parent (the chart) so setting match_parent as height doesn’t work and the view doesn’t have height. Second problem was that I have set .withPosition() with Y value as 0, and that would draw the view under the visible area of the chart.

So let me now ask new questions

1 Is there a possibility to move the annotation just by grabbing it, without first selecting it?
2 How can I change the red border when selecting the annotation?
3 How to set the annotation to return X value of it’s position from the center of its view and not from the start of its view
4 How do I restrict movement of the annotation to only X axis?

/// original question
Hello.

I have a problem with annotations. What I need to achieve, is to draw custom view (it’s fairly simple) on my chart, and this view should have always the height of the chart.

I can’t make it work, I am adding the annotation in exact same way as in example android project, and I even copied annotation code from your example project to mine, but for some reason it doesn’t work in my project.

this is the drawable:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:width="40dp">
<color android:color="@color/secondary_18"/>
</item>
<item android:gravity="center_horizontal" android:width="4dp">
<color android:color="@color/secondary"/>
</item>
</layer-list>

EDIT: There is no < br > in this code ^

what I already tried:
1. Wrapping the drawable into layout consisting of <ImageView> with src= set to drawable
2. Creating a class extending View() class and then setting the imageResource there
3. inflating my layout first and then putting it inside .withContent()
4. using .withContent() directly with R.layout.some_layout_view
5. using it with .withBackgroundDrawableId()
6. various combinations with setting different widths and heights and .withPosition() and whatever you can think of

I managed to display the CustomAnnotation once (don’t remember with which combination of settings) but it wouldn’t move anyway despite the .withIsEditable(true) and despite it was “selected” (red border around it appeared on click)

my axes:

        val xAxis = sciChartBuilder.newNumericAxis()
        .withAxisId(X_AXIS_ID)
        .withDrawMajorBands(false)
        .withDrawMajorGridLines(false)
        .withDrawLabels(false)
        .withIsCenterAxis(true)
        .withDrawMinorTicks(false)
        .withDrawMinorGridLines(false)
        .withDrawMajorTicks(false)
        .build()

    val yAxis = sciChartBuilder.newNumericAxis()
        .withAutoRangeMode(AutoRange.Always)
        .withAxisId(Y_AXIS_ID)
        .withDrawMajorBands(false)
        .withDrawMajorGridLines(false)
        .withDrawMinorGridLines(false)
        .withDrawLabels(false)
        .withIsCenterAxis(true)
        .withDrawMajorTicks(false)
        .withDrawMinorTicks(false)
        .build()

    chartSurface.xAxes.add(xAxis)
    chartSurface.yAxes.add(yAxis)

my series:

 chartSurface.renderableSeriesAreaFillStyle = SolidBrushStyle(chartBackgroundColor)
    chartSurface.renderableSeriesAreaBorderStyle = SolidPenStyle(0x0, false, 0f, null)

    val mountainSeries = sciChartBuilder.newMountainSeries()
        .withDataSeries(dataSeries)
        .withStrokeStyle(SolidPenStyle(-0x1, true, 0f, null))
        .withAreaFillLinearGradientColors(-0x1, -0xed7422)
        .withXAxisId(X_AXIS_ID)
        .withYAxisId(Y_AXIS_ID)
        .build()

    chartSurface.renderableSeries.add(mountainSeries)

my control modifiers:

   val chartModifiers = sciChartBuilder.newModifierGroup()
        .withPinchZoomModifier()
        .withXyDirection(Direction2D.XDirection)
        .withReceiveHandledEvents(true)
        .withScaleFactor(0.8f)
        .build()
        .withZoomPanModifier()
        .withXyDirection(Direction2D.XDirection)
        .withClipModeX(ClipMode.ClipAtExtents)
        .withZoomExtentsY(true)
        .withReceiveHandledEvents(true)
        .build()
        .withZoomExtentsModifier()
        .withReceiveHandledEvents(true)
        .withXyDirection(Direction2D.XyDirection)
        .build()
        .build()

    chartSurface.chartModifiers.add(chartModifiers)

one example of many of how I tried to add the annotations:

        chartSurface.annotations.add(
        sciChartBuilder.newBoxAnnotation()
            .withContent(CustomView(context))
            .withXAxisId(X_AXIS_ID)
            .withYAxisId(Y_AXIS_ID)
            .withIsEditable(true)
            .build()
    )

ofc I also tried the same with CustomAnnotation and like I said with various other settings I could think of like .withPosition() and withResizingGrip. Curious thing is that VerticalLineAnnotation works with no problems really.

EDIT2:

Alternatively I could go with two VerticalLineAnnotations on top of each other moving together but I would have to be able to move them instantly, without selecting them first, because those circular handles look really bad and I have to disable them.

But later on I need to have box annotation working anyway, there will be X values selecting feature

0 votes
8k views

In WPF, I am trying to allow user to resize a box annotation by holding the mouse on its side edges and dragging the mouse to left or right. By default, the box annotation allows to resize only by its round shaped holders appearing on top corners. Is there any way to allow such functionality?

So far, I have thought of placing two vertical annotations inside the box annotation template exactly on its edges and then sync their X coordinates with that of the box by two way binding. However, it is not an easy way to do it and also it does not work when used together as a single custom annotation or composite annotation.

Please suggest if any property can be tweaked for box annotation to achieve this?

  • Anil Soman asked 5 years ago
  • last active 5 years ago
0 votes
9k views

XAxis Labels

I want to have a label on the x axis for each custom annotations. Is this possible. if so how do i do that.

Thanks

0 votes
10k views

I’m trying to implement custom annotations using the MVVM pattern. I’ve been using your tutorial as an example (https://www.scichart.com/databinding-annotations-with-mvvm/). Everything works as expected if I manually load some example data to the annotations collection. When I actually try to load the data from our database using async method, the annotations are no longer drawn.

Is this by design or am I doing something wrong? Do you have any suggestions how to load annotations when using async code and MVVM patterns? I haven’t had any problems loading the actual time series on the chart using the same pattern.

I also tried binding the SciChartSurface’s Annotations property to AnnotationCollection and then calling ChartAnnotations.ParentSurface.InvalidateElement(), but the issue still persists.

You can easily reproduce this behavior by adding an async call to the examples’s source code:

private async Task Initialize()
{
    var ds0 = new XyDataSeries<double, double>();
    var someData = new RandomWalkGenerator().GetRandomWalkSeries(200); // RandomWalkGenerator is found in the examples source code

    ds0.Append(someData.XData, someData.YData);

    _chartSeries = new ObservableCollection<IChartSeriesViewModel>();
    _chartSeries.Add(new ChartSeriesViewModel(ds0, new FastLineRenderableSeries()));

    // Now create the labels
    _chartLabels = new List<LabelViewModel>
                       {
                           new LabelViewModel(5, -2.5, "Label0", "Label0 Tooltip!"),
                           new LabelViewModel(20, -2, "Label1", "Label1 Tooltip!"),
                           new LabelViewModel(35, 3, "Label2", "Label2 Tooltip!"),
                           new LabelViewModel(50, 1.5, "Label3", "Label3 Tooltip!"),
                       };

    await Test();

    _chartLabels.Add(new LabelViewModel(65, -0.5, "AFTER ASYNC", "Label4 Tooltip!"));
}

private async Task Test()
{
    await Task.Delay(5000);
}
  • Juho asked 7 years ago
  • last active 7 years ago
0 votes
9k views

How do you place a CustomAnnotation on the axis like an AxisMarkerAnnotation?

  • abc def asked 7 years ago
  • last active 7 years ago
0 votes
10k views

I did modify this CustomAnnotationChartModifier. I added a databinding to bing the ShowLabelProperty to the IsSelectedProperty.

    // Recreate all annotations, called when LabelsSource property changes or when the
    // CustomAnnotationChartModifier is attached to the parent surface
    private void RebuildAnnotations() {
        if (base.ParentSurface == null || LabelsSource == null)
            return;
        var annotationCollection = base.ParentSurface.Annotations;
        annotationCollection.Clear();
        foreach (var item in LabelsSource) {
            var vla = new VerticalLineAnnotation();
            vla.DataContext = item;
            vla.SetBinding(AnnotationBase.X1Property, new Binding("X1") { Mode = BindingMode.OneWay });
            // bind ShowLabelProperty
            vla.SetBinding(VerticalLineAnnotation.ShowLabelProperty,
                new Binding("IsSelected") { RelativeSource = RelativeSource.Self, Mode=BindingMode.OneWay });
            vla.IsEditable = this.IsEditable;
            // after manipulation: write X1Property back to Viewmodel 
            vla.DragEnded += Annotation_DragEnded;
            vla.LabelPlacement = LabelPlacement.Top;
            // test to set directly ShowLabel = (bool)e.NewValue;
            //vla.Unselected += annotation_SelectionChanged;
            //vla.Selected += annotation_SelectionChanged; 
            if (this.MarkerManipulatedCommand != null)
                vla.ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(manipulationCompleted_EventHandler);
            annotationCollection.Add(vla);
        }
    }

    private void annotation_SelectionChanged(object sender, EventArgs e) {
        var vla = sender as VerticalLineAnnotation;
        if (vla == null) return;
        vla.ShowLabel =vla.IsSelected;
    }

Result: Select the annoation will show the label. Unselect will not remove the label.
I did try the unselected and selected-event to do the same on other way ->same result.
I can see also that each new selection lighter the label (is it shown more than one time?).

How can I add ToolTipLabel inside that CustomAnnotationChartModifier to see the y-values?

Frank

0 votes
12k views

I have a custom annotation class that I would like to bind the geometries.

<Path.Data>

</Path.Data>

    public GeometryGroup Elements
    {
        get { return _elements; }
        set
        {
            _elements = value;
            InvokePropertyChanged("Elements");
        }
    }

When I create the class in code it only works if Path was set in xaml, doesn’t work if set in code.

            Path p = new Path();
            p.Data = Geometry.Parse("m 0 0 10 0 10 10 0 10 z");             
            GeometryGroup g = new GeometryGroup();
            g.Children.Add(p.RenderedGeometry);
            CustomPathAnnotation cpa = new CustomPathAnnotation()
            {
                Elements = g,
                X1 = .55,
                Y1 = .5, 
                CoordinateMode = AnnotationCoordinateMode.Relative,
                XAxisId = "DefaultAxisId",
                YAxisId = "DefaultAxisId",
                Visibility = Visibility.Visible
            };
            ChartAnnotation.Add(cpa);
0 votes
11k views

I have a CompositeAnnotation and set CoordinateMode to RelativeX.

How to get absolute X position of the annotation in code behind?

<s:CompositeAnnotation.Annotations>
    <s:VerticalLineAnnotation
                              CoordinateMode="RelativeX"                               
                              IsEditable="True" 
                              CanEditText="True"
                              x:Name="MainAnnotation">
        <s:VerticalLineAnnotation.AnnotationLabels>
            <s:AnnotationLabel Text="My annotation"
                               CanEditText="True"
                               LabelPlacement ="Right"
                               />

        </s:VerticalLineAnnotation.AnnotationLabels>

    </s:VerticalLineAnnotation>
0 votes
12k views

To whom this may concern:

I’m having a slight issue (bug, possibly?) with custom annotations. I have created a custom annotation with an image (XAML shown below)

<s:CustomAnnotation x:Class="Dashboard.SciChartCustomComponents.CustomAnnotations.MicrostructureAnnotation"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                    xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
                    xmlns:local="clr-namespace:Dashboard.SciChartCustomComponents.CustomAnnotations"
                    mc:Ignorable="d">

    <Border BorderBrush="White" BorderThickness="2" Background="Black">
        <StackPanel>
            <Image x:Name="annotationImage" Stretch="None" Width="150" Height="100" Visibility="Collapsed"/>
            <TextBlock x:Name="annotationText" HorizontalAlignment="Center"/>
            <TextBlock x:Name="parameterText" HorizontalAlignment="Center" Visibility="Collapsed"/>
        </StackPanel>
    </Border>

</s:CustomAnnotation>

The image is applied with the following code (note the anchor points are bottom-right):

var annotation = new MicrostructureAnnotation
{
    HorizontalAnchorPoint = HorizontalAnchorPoint.Right,
    VerticalAnchorPoint = VerticalAnchorPoint.Bottom,
    IsEditable = true,
    X1 = xValue, // Both Obtained from hitpoint X- and Y-Values
    Y1 = yValue
};

annotation.annotationImage.Source = // some image Uri
annotation.annotationText.Text = // some text
annotation.parameterText.Text = // some other text

So this successfully shows the annotation as i liked, shown in 1.png.

Now I have a function that collapses the visibility of the image, which yields an annotation that is removed from its anchor point (although the top-left location remains the same), shown in 2.png.

If I try to move the annotation after removing the image, the anchor point is in the location of where the top-left anchor should be when the image collapses but the image is still in the wrong location, shown in 3.png.

When I finally do move the annotation, the annotation moves away from the cursor to the top-left anchor point, shown in 4.png.

Again i’m not sure if this is a bug, but could someone please advise?

Thanks kindly!

— Ari

Edit: I don’t have this problem when setting the anchor points to top-left.

  • Ari Sagiv asked 8 years ago
  • last active 8 years ago
0 votes
11k views

I just found that if you have two y-axis on your graph, you need to define the YAxisId for your CustomAnnotation. Otherwise, it would look like the Y1 property does not work.

Posting here in case someone else run into the same problem I had.

<SciChart:CustomAnnotation
                AnnotationCanvas="BelowChart"
                CoordinateMode="Relative"            
                Opacity="0.50"          
                HorizontalAnchorPoint="Right"
                VerticalAnchorPoint="Bottom"
                X1="0.99"
                Y1="0.99" 
                YAxisId="GroupAAxisY">
  • Kwokon Ng asked 8 years ago
  • last active 8 years ago
0 votes
0 answers
10k views

Hi,

I’m looking to draw a BoxAnnotation onto a SciChartGroup ItemTemplate SciStockChart where the user will left mouse click, drag to define the size and releases to create the BoxAnnotation.

How should I go about doing this? Should I be looking at CustomModifiers or CustomAnnotations?

Any pointers will be very helpful

Thanks

David

1 vote
13k views

Hi.

I need to change CustomAnnotation visual view, when property IsSelected = true.

I tried next code:

<Style x:Key="CustomAnnotationStyle" TargetType="{x:Type sc:CustomAnnotation}">
    <Setter Property="IsEditable" Value="True"/>
    <Style.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter Property="BorderBrush" Value="Orange"/>
            <Setter Property="BorderThickness" Value="2"/>
        </Trigger>
    </Style.Triggers>
</Style>

But it has no effect.
When I select the Annotation by mouse click, then it still have LightGreen rectangle.

In the Goal I need the Orange circle around of the Content of the Annotation.

Thanks.

1 vote
11k views

Hi,

After I’ve added some TextAnnotations on the graph, I’ve noticed that the TextAnnotations and CustomaAnnotations doesn’t resize with the view. They all stay constant in size. I’ve found a previous question about this in here: https://www.scichart.com/questions/question/text-annotation-size

But I’m not getting the results I hoped for with this. The test is still not resizing with the surface. Since it’s been a while that a question was asked about this, maybe there are new methods to do this in Scichart?

Thanks

  • kewur asked 9 years ago
  • last active 9 years ago
0 votes
19k views

Hi,
I’ve created a custom annotation and have set it’s .IsEditable property in code so the user can reposition it. I have two issues:
1.I want the user to be able to resize the “PPZLine” in the X direction, but I can’t figure out how to get the anchor points to appear.

  1. I want to be able to see the chart data that the annotation is covering. I tried setting AnnotationCanvas = BelowChart, but then I couldn’t move the annotation or get any annotation mouse handlers to trigger.

Here’s the annoation’s xaml:

<s:CustomAnnotation x:Class="CinchV2DemoWPF.Views.SciChart.PPZView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:CinchV2="clr-namespace:Cinch;assembly=Cinch.WPF"
             xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
             xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:s="clr-namespace:Abt.Controls.SciChart;assembly=Abt.Controls.SciChart.Wpf" 
             meffed:ViewModelLocator.ViewModel="PPZViewModel"

             X1="{Binding X1}"
             Y1="{Binding Y1}"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

    <!-- price line must use margin 0,0 or obj will not be visible-->
        <s:BoxAnnotation Name="LongEntryMarker" Grid.Row="0"
                       Width="20"    Height="10"  Background="DarkViolet" Margin="0,0"  VerticalAlignment="Top" 
                         HorizontalAlignment="Right"
                         >
        </s:BoxAnnotation>

        <!-- long marker line MouseRightButtonDown="LongEntryMarker_OnMouseRightButtonDown"-->
        <s:BoxAnnotation Name="PPZLine" Grid.Row="1"
                       Width="150"    Height="5"  Background="red" Margin="0,0"  VerticalAlignment="Top" 
                         >
        </s:BoxAnnotation>
</Grid>
</s:CustomAnnotation>
  • tecman234 asked 11 years ago
  • last active 9 years ago
Showing 28 results

Try SciChart Today

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

Start TrialCase Studies