Knowledgebase
Custom ChartModifiers - Part 4 - Custom Legend Data Sources
Posted by Andrew BT on 05 February 2019 07:49 PM

The ChartModifier API

If you haven't read it already, please see our article on Custom ChartModifier API Overview. In this article, we introduce the basics of the ChartModifier API including an overview of this powerful base class. 

The ChartModifier API is by far the most powerful API in the SciChart library. Using this API you can create behaviours which you can attach to a chart to perform custom Zooming, Panning, Annotation & Markers, Legend output and much much more. Any time you want to do something in C# code to alter the behaviour of a SciChartSurface you should be thinking about creating a custom modifier to do it.

Custom ChartModifiers Part 4 - Custom Legend Data Source

The fourth part in our series on Custom Chart Modifiers demonstrates how we create a Legend Data Source. In this example we're going to create something similar to what the SciChart LegendModifier does - expose a Collection of SeriesInfo that we can bind to in the view. You can easily take this custom modifier and extend it if you wanted to provide extra metadata to bind to in the legend. Watch the video below to see how we did this.

The SimpleLegendModifier Source

The entire SimpleLegendModifier class is included below. The code is fairly self-explanatory. Whenever the SciChartSurface renders, we perform a hit-test on all the RenderableSeries on the parent SciChartSurface using the right-most point on the Viewport. Then, we convert the HitTestInfo results into SeriesInfo - a flexible ViewModel containing information about the underlying Series. We can then bind to the SeriesInfo in the view, either by using a Legend control or even a simple ItemsControl

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using SciChart.Charting.ChartModifiers;
using SciChart.Charting.Model.ChartData;
using SciChart.Charting.Utility;
using SciChart.Charting.Visuals.RenderableSeries;

namespace TestSuite.ExampleSandbox.CustomModifiers
{
    public class SimpleLegendModifier : ChartModifierBase
    {
        /// 
        /// Defines the LegendData Dependency property
        /// 
        public static readonly DependencyProperty LegendDataProperty = DependencyProperty.Register("LegendData", typeof(ChartDataObject), typeof(SimpleLegendModifier));

        public SimpleLegendModifier()
        {
            this.SetCurrentValue(LegendDataProperty, new ChartDataObject { SeriesInfo = new ObservableCollection<SeriesInfo>() });
        }

        /// 
        /// Gets or sets the  which may be bound to
        /// 
        public ChartDataObject LegendData
        {
            get { return (ChartDataObject)GetValue(LegendDataProperty); }
            set { SetValue(LegendDataProperty, value); }
        }

        public override void OnParentSurfaceRendered(SciChartRenderedMessage e)
        {
            base.OnParentSurfaceRendered(e);

            // TODO here: Modify which RenderableSeries are passed in to GetSeriesInfo to alter output
            var seriesInfos = this.GetSeriesInfo(ParentSurface.RenderableSeries);

            // TODO here: if you experience flicker, it is a .NET4.5 bug. This occurs when updating an ObservableCollection
            // the solution believe it or not is to do a differential update, e.g. only change the SeriesInfo instance if a series was added or removed
            LegendData.SeriesInfo = new ObservableCollection<SeriesInfo>(seriesInfos);
        }

        private ObservableCollection<SeriesInfo> GetSeriesInfo(IEnumerable<IRenderableSeries> allSeries)
        {
            var seriesInfo = new ObservableCollection<SeriesInfo>();

            if (allSeries != null)
            {
                foreach (var renderableSeries in allSeries)
                {
                    if (renderableSeries == null || renderableSeries.DataSeries == null)
                    {
                        continue;
                    }

                    var hitResult = renderableSeries.DataSeries.HasValues
                                        ? renderableSeries.HitTest(new Point(ModifierSurface.ActualWidth, 0))
                                        : default(HitTestInfo);

                    var s = renderableSeries.GetSeriesInfo(hitResult);

                    seriesInfo.Add(s);
                }
            }

            return seriesInfo;
        }
    }
}

Download the Custom Modifier Sandbox Example

The complete application with all our custom chart modifiers can be downloaded in Part 1.

(6 vote(s))
Helpful
Not helpful

CONTACT US

Not sure where to start? Contact us, we are happy to help!


CONTACT US

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL. Email: Legal Company Number: 07430048, VAT Number: 101957725