Bug: DataSeries with DateTime shifted to same starting date

5 posts, 1 answers
  1. Tomas
    Tomas avatar
    9 posts
    Member since:
    Feb 2009

    Posted 24 Feb 2009 Link to this post

    There is a bug when presenting multiple dataseries (DateTime) with different starting points.
    All series are shifted to the same starting point (to the left).

    The bug is easy to reproduce, and I have attached some sample code (updated for better formatting).

    Is this possible to get around?

    Also, is there a way to get a smaller presentation (eg. day/month/yr) of the dates along the x-axis? (so they do not overlap).

    Best regards,

    Tomas Wangen.



    Window1.xaml

     

     

     

     

    <Window x:Class="GraphTest.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
        Title="Window1" Height="400" Width="600" Loaded="Window_Loaded">  
        <Grid> 
            <telerik:RadChart x:Name="MainChart"></telerik:RadChart> 
        </Grid> 
    </Window> 
     

    Window1.xaml.cs

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Windows;  
    using System.Windows.Controls;  
    using System.Windows.Data;  
    using System.Windows.Documents;  
    using System.Windows.Input;  
    using System.Windows.Media;  
    using System.Windows.Media.Imaging;  
    using System.Windows.Navigation;  
    using System.Windows.Shapes;  
    using Telerik.Windows.Controls.Charting;  
     
    namespace GraphTest  
    {  
        /// <summary>  
        /// Interaction logic for Window1.xaml  
        /// </summary>  
        public partial class Window1 : Window  
        {  
            public Window1()  
            {  
                InitializeComponent();  
            }  
     
            class DataEntry  
            {  
                public DateTime dt { getset; }  
                public double value { getset; }  
            }  
            private void Window_Loaded(object sender, RoutedEventArgs e)  
            {  
                MainChart.DefaultView.ChartArea.AxisX.IsDateTime = true;  
     
                ISeriesDefinition definition = new StackedBarSeriesDefinition();  
     
                DataSeries dataSeries1 = new DataSeries() { Definition = definition };  
                DataSeries dataSeries2 = new DataSeries() { Definition = definition };  
     
                DateTime time1 = DateTime.Today;  
                DateTime time2 = time1 + new TimeSpan(1, 0, 0, 0);  
                DateTime time3 = time2 + new TimeSpan(1, 0, 0, 0);  
                DateTime time4 = time3 + new TimeSpan(1, 0, 0, 0);  
     
                List<DataEntry> testData1 = new List<DataEntry>() {   
                    new DataEntry() { dt = time1, value = 10.0 },   
                    new DataEntry() { dt = time2, value = 15.0 },  
                    new DataEntry() { dt = time3, value = 20.0 }};  
     
                // notice that testData2 is shiftet 24 hrs from testData1  
     
                List<DataEntry> testData2 = new List<DataEntry>() {   
                    new DataEntry() { dt = time2, value = 30.0 },   
                    new DataEntry() { dt = time3, value = 40.0 },  
                    new DataEntry() { dt = time4, value = 20.0 }};  
     
                foreach (DataEntry entry in testData1)  
                    dataSeries1.Add( new DataPoint(entry.dt) { YValue = (double)entry.value });  
     
                foreach (DataEntry entry in testData2)  
                    dataSeries2.Add(new DataPoint(entry.dt) { YValue = (double)entry.value });  
     
                MainChart.DefaultView.ChartArea.DataSeries.Add(dataSeries1);  
                MainChart.DefaultView.ChartArea.DataSeries.Add(dataSeries2);  
            }  
        }  
    }  
     
  2. Answer
    Velin
    Admin
    Velin avatar
    391 posts

    Posted 26 Feb 2009 Link to this post

    Hi Tomas,

    In fact, you need a feature called "Strict mode" which, if present, enables the X axis to order the elements according to their X value and not their index. Unfortunately, at this time "strict mode" is still not supported by RadChart for WPF but we have planned to implement it in a future release.

    Onto your second question - you could change the date formatting on the X axis by setting its "DefaultFormat" property to a value like this "MMM/dd/yy". Here is how this could be done with code:
       
    RadChart1.DefaultView.ChartArea.AxisX.DefaultFormat = "MMM/dd/yy"

    Hope this will help.

    Regards,
    Velin
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
  3. Tomas
    Tomas avatar
    9 posts
    Member since:
    Feb 2009

    Posted 26 Feb 2009 Link to this post

    Velin,

    Thanks yes this helps.

    I guess I'll have to preprocess all the data before populating the graphs for now.

    -Tomas

  4. Tomas
    Tomas avatar
    9 posts
    Member since:
    Feb 2009

    Posted 27 Feb 2009 Link to this post

    The attached code-snippet is what I currently use as a workaround.

    This takes a collection of named dataseries and returns a collection of the same dataseries with missing x-values set to 0. Missing slots can optionally be filled (CreateContinuousIntegerXAxis = true).

    This works best with bar-type graphs due to the inserted 0 values.

    I hope you integrate this in the package in a later version as empty values should definately be handled upon rendering the graphs and not while populating the data.

    If you (or anyone else) have a more elegant workaround, I would appreciate that :).

    -Tomas

    public static Dictionary<string, DataSeries> ExpandSeries(Dictionary<string, DataSeries> Dataseries, bool CreateContinuousIntegerXAxis)  
    {  
        // find all x-values in dataseries  
        HashSet<double> xvalues = new HashSet<double>();  
     
        foreach (DataSeries ds in Dataseries.Values)  
        {  
            foreach (DataPoint entry in ds.AsEnumerable())  
                if (!xvalues.Contains(entry.XValue))  
                    xvalues.Add(entry.XValue);  
        }  
     
        // sort x-values  
        IEnumerable<double> sortedxvalues = from x in xvalues orderby x select x;  
     
        if (CreateContinuousIntegerXAxis)   
        {  
            // add x-values missing in all dataseries  
            int floor = (int)sortedxvalues.First();  
            int roof = (int)sortedxvalues.Last();  
     
            List<double> IntegerXValues = new List<double>();  
     
            for (int i = floor; i <= roof; i++)  
                IntegerXValues.Add(i);  
     
            sortedxvalues = IntegerXValues.AsEnumerable();  
        }  
     
        // create a value matrix for new dataseries  
        Dictionary<string, Dictionary<doubledouble>> ValueMatrix = new Dictionary<string, Dictionary<doubledouble>>();  
     
        int tuplecount = sortedxvalues.Count();  
     
        // initialize matrix with 0 values  
     
        foreach (string seriesname in Dataseries.Keys)  
        {  
            ValueMatrix[seriesname] = new Dictionary<doubledouble>();  
     
            foreach (double x in sortedxvalues)  
            {  
                ValueMatrix[seriesname][x] = 0;  
            }  
        }  
     
        // copy values from source datasets  
        foreach (KeyValuePair<string, DataSeries> dsp in Dataseries)  
        {  
            string seriesname = dsp.Key;  
     
            foreach (DataPoint entry in dsp.Value.AsEnumerable())  
            {  
                ValueMatrix[seriesname][entry.XValue] = entry.YValue;  
            }  
        }  
     
        // construct and populate new dataseries based on calculated matrix  
        Dictionary<string, DataSeries> ret = new Dictionary<string, DataSeries>();  
     
        foreach (KeyValuePair<string, DataSeries> dsp in Dataseries)  
        {  
            ret[dsp.Key] = new DataSeries() { Definition = dsp.Value.Definition, LegendLabel = dsp.Value.LegendLabel };  
     
            foreach (double x in sortedxvalues)  
                ret[dsp.Key].Add(new DataPoint() { XValue = x, YValue = ValueMatrix[dsp.Key][x] });  
     
        }  
     
        return ret;  
     
    }  
     
  5. Ves
    Admin
    Ves avatar
    2926 posts

    Posted 02 Mar 2009 Link to this post

    Hello Tomas,

    We realize this is an important feature for any chart control, so its implementation will be considered with the appropriate attention. Thank you for the code provided. It has already been forwarded to our developers. I have updated your Telerik points as small token of gratitude for the valuable feedback.

    Kind regards,
    Ves
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Check out the tips for optimizing your support resource searches.
Back to Top