Pre loader

TrendlineAnnotationPlacement modifier

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

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.

Try SciChart Today

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

Start TrialCase Studies