SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and iOS Chart & Android Chart Components

Welcome to the SciChart Community Forums!

Please use the forums below to ask questions about SciChart. Take a moment to read our Question asking guidelines on how to ask a good question and our support policy. We also have a tag=SciChart on Stackoverflow.com where you can earn rep for your questions!

Please note: SciChart team will only answer questions from customers with active support subscriptions. Expired support questions will be ignored. If your support status shows incorrectly, contact us and we will be glad to help.

0
0

Hi,

I’m having an exception thrown when I try to dynamically add an annotation. I’m using the example on your site as reference.I’m sure its something I’m overlooking. But I can’t figure out what it is. I have attached my code here, can you tell me what I’m doing wrong here. I’m trying to add a Line annotation when the user clicks on the context menu.

Thanks,
Deepak

Attachments
  • You must to post comments
0
0

Ok, I had a quick look at this. The problem is two-fold.

1.) The AnnotationCreationModifier requires knowledge of the XAxisId and YAxisId. Since you have added four axes and given them all Ids, the AnnotationCreationModifier does not know which axis to place the annotations on.

2.) The AnnotationCreationModifier has a YAxisId property but is not configured to allow placement on multiple XAxis.

I suggest what you do is this:

  • Forget about the AnnotationCreationModifier. Instead, create a class, derive it from ChartModifierBase (calling it TrendlineAnnotationPlacement) and override OnModifierMouseDown, OnModifierMouseUp, OnModifierMouseMove
  • Add TrendlineAnnotationPlacement to your chart ChartModifiers collection, setting IsEnabled=False
  • Next in your Context Menu, set IsEnabled=True on your TrendlineAnnotationPlacement modifier.

Now to implement the TrendlineAnnotationPlacement modifier. I suggest overriding OnModifierMouseDown, OnModifierMouseMove. These methods are called whenever the user clicks, moves on the chart. You will need to listen to MouseDown and then place a line annotation with X1Y1 X2Y2 on the chart at the given data-coordinates.

As the mouse moves, update only X2Y2

As the mouse-down occurs for a second time, set X2Y2 to the final position and set the entire ChartModifier to disabled (e.g. this.IsEnabled=false).

I’ve created a sample below. If you try this code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abt.Controls.SciChart.ChartModifiers;
using Abt.Controls.SciChart.Visuals.Annotations;

namespace SampleChart
{
    /// <summary>
    /// An example of how to create a custom modifier to draw Trendlines. 
    /// 
    /// You can disable it by setting IsEnabled = False and enable with IsEnabled = True. 
    /// 
    /// You could easily create a base class for each Annotation type you wanted to create so that creating modifiers
    /// for Text, Label, Arrow would be simple
    /// </summary>
    public class TrendlineAnnotationModifier : ChartModifierBase
    {
        // Note: these could be DependencyProperties, or, you could 
        // ensure your default X/Y Axis do not have an id set, in which case
        // the ids would be AxisBase.DefaultAxisId
        private static readonly string XAxisId = "XAxisBottom";
        private static readonly string YAxisId = "YAxisRight";
        private LineAnnotation _line;

        public override void OnModifierMouseDown(ModifierMouseArgs e)
        {
            base.OnModifierMouseDown(e);

            if (_line == null)
            {
                // Create new line
                ParentSurface.ModifierSurface.CaptureMouse();

                _line = new LineAnnotation();
                _line.XAxisId = XAxisId;
                _line.YAxisId = YAxisId;

                // Get data value from mouse coordinate            
                _line.X1 = GetXAxis(XAxisId).GetDataValue(e.MousePoint.X);
                _line.Y1 = GetYAxis(YAxisId).GetDataValue(e.MousePoint.Y);
                _line.X2 = _line.X1;
                _line.Y2 = _line.Y1;

                ParentSurface.Annotations.Add(_line);

                _line.IsSelected = true;
            }
            else
            {
                // Complete line creation 

                // Get data value from mouse coordinate            
                _line.X2 = GetXAxis(XAxisId).GetDataValue(e.MousePoint.X);
                _line.Y2 = GetYAxis(YAxisId).GetDataValue(e.MousePoint.Y);

                _line.IsSelected = false;
                e.Handled = true;
                _line = null;

                ParentSurface.ModifierSurface.ReleaseMouseCapture();
            }
            
            e.Handled = true;
        }

        public override void OnModifierMouseMove(ModifierMouseArgs e)
        {
            base.OnModifierMouseMove(e);

            if (_line == null) return;

            // Get data value from mouse coordinate            
            _line.X2 = GetXAxis(XAxisId).GetDataValue(e.MousePoint.X);
            _line.Y2 = GetYAxis(YAxisId).GetDataValue(e.MousePoint.Y);

            e.Handled = true;
        }
    }
}

Then use it like this

<SciChart:SciChartSurface.ChartModifier>
                <SciChart:ModifierGroup>
                    <sampleChart:TrendlineAnnotationModifier ReceiveHandledEvents="True" IsEnabled="True"/>

It should give you a pretty good starting point.

Best regards,
Andrew

  • deepakb1
    Thanks Andrew. This worked.
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.