Charting scenario: combine DataSeries and SeriesMapping in the same chart

4 posts, 0 answers
  1. Wolfgang Kaiser
    Wolfgang Kaiser avatar
    9 posts
    Member since:
    Dec 2009

    Posted 29 Apr 2010 Link to this post

    I was wondering if the following charting scenario can be implemented using RadChart:
    I have two sources of measurement values (both sources are time based): the first data source has a fixed time interval and one value for each time slot, the second data source has only a few values at random time intervals (it is also possible that this datasource has multiple values per time slot).  I would like to display both data sources in the same chart.  In addition I also like to use the Zoom/Scroll function for the time (X) axis.  I can display the data source with fixed time interval using SeriesMappings and the zoom/scroll feature, however, I can't add a DataSeries item with my random timed data to the same chart.  Is there a way to do this and also have the Zoom/scroll feature working (my understanding is that zoom/scoll only works with ItemsSource + SeriesMappings).
    Thanks,

  2. Vladimir Milev
    Admin
    Vladimir Milev avatar
    1061 posts

    Posted 04 May 2010 Link to this post

    Hello Wolfgang Kaiser,

    Yes, zoom & scroll works with ItemsSource + SeriesMappings. How does your data object look like? Do you have separate data objects for the two souces? Can you describe the business object(s) please and I will do my best to advise you how to proceed.

    Best wishes,
    Vladimir Milev
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
  3. Wolfgang Kaiser
    Wolfgang Kaiser avatar
    9 posts
    Member since:
    Dec 2009

    Posted 04 May 2010 Link to this post

    Thanks for the help, but I think I answered my own question in the meantime.  I managed to implement my requirements by using "Nest Collections", which fullfills my requirements, but there are some problems with data points disappearing from the Chart. 
    Below is my sample code that illustrates what I like to do - mainly displaying lines (and points) on the same chart where the X-Axis dates are not the same across the various mapping series.

    <UserControl   
        xmlns:my="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Charting"  x:Class="TestChart.MainPage" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:userControls="clr-namespace:TestChart" 
        xmlns:telerikCharting="clr-namespace:Telerik.Windows.Controls.Charting;assembly=Telerik.Windows.Controls.Charting" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"   
        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">  
     
        <Grid x:Name="LayoutRoot">  
            <StackPanel> 
                <my:RadChart Name="RadChartTest" Height="300"></my:RadChart> 
            </StackPanel> 
        </Grid> 
    </UserControl> 
     
    using System;  
    using System.Collections.Generic;  
    using System.Windows;  
    using System.Windows.Controls;  
    using System.Windows.Media;  
    using Telerik.Windows.Controls.Charting;  
    using System.ComponentModel;  
    using System.Collections.ObjectModel;  
     
    namespace TestChart  
    {  
        public partial class MainPage : UserControl  
        {  
            public MainPage()  
            {  
                InitializeComponent();  
     
                /// Test  
     
                DateTime today = Convert.ToDateTime(DateTime.Now.ToShortDateString());  
                //RadChartTest.DefaultView.ChartArea.AxisX.MinValue = today.ToOADate();  
                //RadChartTest.DefaultView.ChartArea.AxisX.MaxValue = today.AddYears(1).ToOADate();  
                RadChartTest.DefaultView.ChartArea.EnableAnimations = false;  
     
                RadChartTest.DefaultView.ChartArea.ZoomScrollSettingsX.RangeEnd = 0.25;  
                RadChartTest.DefaultView.ChartArea.ZoomScrollSettingsX.MinZoomRange = 0.001;  
                RadChartTest.DefaultView.ChartArea.ZoomScrollSettingsX.ScrollMode = ScrollMode.ScrollAndZoom;  
                RadChartTest.DefaultView.ChartArea.ZoomScrollSettingsX.PropertyChanged += ZoomScrollSettingsXText_PropertyChanged;  
                RadChartTest.DefaultView.ChartLegend.Visibility = Visibility.Collapsed;  
     
                RadChartTest.DefaultView.ChartArea.AxisY.Title = "Events";  
     
                RadChartTest.DefaultView.ChartArea.AxisX.IsDateTime = true;  
                RadChartTest.DefaultView.ChartArea.AxisX.Title = "Time";  
                RadChartTest.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "MMMM yyyy";  
     
                  
     
                List<ObservableCollection<TradeData>> sampleData = new List<ObservableCollection<TradeData>>();  
                sampleData.Add(GetSampleData("CSCO", 200));  
                sampleData.Add(GetSampleData("MSFT", 200));  
                sampleData.Add(GetSampleData("RFMD", 200));  
     
                sampleData.Add(GetSampleData("CTIC", 200));  
     
                for (int iColIndex = 0; iColIndex < sampleData.Count; iColIndex++)  
                {  
                    SeriesMapping seriesMapping = new SeriesMapping();  
                    seriesMapping.CollectionIndex = iColIndex;  
                    seriesMapping.LegendLabel = sampleData[iColIndex][0].Symbol;  
                    if (iColIndex < 3)  
                        seriesMapping.SeriesDefinition = new LineSeriesDefinition();  
                    else 
                    {  
                        seriesMapping.SeriesDefinition = new AreaSeriesDefinition();  
                        seriesMapping.SeriesDefinition.Appearance.Fill = new SolidColorBrush(Color.FromArgb(20, 0, 128, 255));  
                        seriesMapping.SeriesDefinition.Appearance.Stroke = new SolidColorBrush(Color.FromArgb(255, 0, 128, 255));  
                        seriesMapping.SeriesDefinition.Appearance.StrokeThickness = 1;  
                        (seriesMapping.SeriesDefinition as AreaSeriesDefinition).ShowPointMarks = false;  
                    }  
                    seriesMapping.SeriesDefinition.ShowItemLabels = false;  
                    seriesMapping.ItemMappings.Add(new ItemMapping("RecordDate", DataPointMember.XValue));  
                    seriesMapping.ItemMappings.Add(new ItemMapping("Close", DataPointMember.YValue));  
                    RadChartTest.SeriesMappings.Add(seriesMapping);  
                }
    #if DontUse  
                ChartFilterDescriptor descriptor = new ChartFilterDescriptor();  
                descriptor.Member = "Close";  
                descriptor.MemberType = typeof(int);  
                descriptor.Operator = Telerik.Windows.Data.FilterOperator.IsGreaterThan;  
                descriptor.Value = 240;  
                foreach (SeriesMapping sM in RadChartTest.SeriesMappings)  
                {  
                    sM.FilterDescriptors.Add(descriptor);  
                }
    #endif  
                RadChartTest.ItemsSource = sampleData;  
     
     
            }  
            public class TradeData  
            {  
                public string Symbol { getset; }  
                public DateTime RecordDate { getset; }  
                public double Open { getset; }  
                public double High { getset; }  
                public double Low { getset; }  
                public int Close { getset; }  
                public double Volume { getset; }  
            }  
            private static Random price = new Random();  
                private static int iMaxDays = 100;  
     
            private ObservableCollection<TradeData> GetSampleData(string sStockSymbol, int dOffset)  
            {  
                ObservableCollection<TradeData> tData = new ObservableCollection<TradeData>();  
                int iStep = 1;  
                DateTime today = DateTime.Now;  
                today = new DateTime(today.Year, today.Month, today.Day);  
                for (int iDays = 0; iDays < iMaxDays; iDays += iStep++)  
                {  
                    TradeData td = new TradeData();  
                    td.Symbol = sStockSymbol;  
                    td.RecordDate = today.AddDays(iDays);  
                    td.Close = dOffset + price.Next(0, 50);  
                    tData.Add(td);  
                }  
                iMaxDays += 100;  
                return tData;  
     
            }  
     
            private void ZoomScrollSettingsXText_PropertyChanged(object sender, PropertyChangedEventArgs e)  
            {  
                double range = (sender as ZoomScrollSettings).Range;  
     
                if (range > 0.7d)  
                {  
                    RadChartTest.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "yyyy";  
                    RadChartTest.DefaultView.ChartArea.AxisX.StepLabelLevelCount = 1;  
                }  
                else if (range > 1d / 12d)  
                {  
                    RadChartTest.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "MMMM yyyy";  
                    RadChartTest.DefaultView.ChartArea.AxisX.StepLabelLevelCount = 2;  
                }  
                else if (range > 1d / 12d / 30d)  
                {  
                    RadChartTest.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "dd MMM yyyy";  
                    RadChartTest.DefaultView.ChartArea.AxisX.StepLabelLevelCount = 2;  
                }  
                else 
                {  
                    RadChartTest.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "dd-MMM (HH:mm)";  
                    RadChartTest.DefaultView.ChartArea.AxisX.StepLabelLevelCount = 2;  
                }  
            }  
     
        }  
    }  
     

    So what happens is that when you move the left or right side of the zoom/scroll to the center points will start missing on the left and right side of the chart (see attached image).  I can't attach the sample code since .zip can't be attached, but I think the above code snippets might be enough.
    Is there something I am doing wrong - or maybe a workaround for a potential bug?

    Thanks,
    Wolfgang

  4. Vladimir Milev
    Admin
    Vladimir Milev avatar
    1061 posts

    Posted 06 May 2010 Link to this post

    Hi Wolfgang Kaiser,

    What you are seeing is one of the side effects of using the "Nested Collections" feature together with zooming and scrolling and XAxis AutoRange. I will try to explain what happens:

    If you use AutoRange on XAxis (turned on by default) the chart control does not know the range of the XAxis being zoomed. This is because the axis range is calculated later, after the data is already databound. So what it tries do to is measure the range internally by finding the largest and smallest values within the collection being bound. After it does so it assumes that to be the absolute range and applies zooming on that range.

    Now if you have different collections with (nested collections) and each collection has different XValues and therefore different ranges for the XAxis it is not possible for the chart control to measure the maximum and minimum of all collections and thus this side effect occurs.

    A work-around would be to manually set the XAxis range and then zooming and scrolling will use that range for all series and nested collections. You only need to do this once in the beginning and zooming and scrolling functions will update the visible range automatically.

    Regards,
    Vladimir Milev
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
Back to Top