Multiple problems with dynamic line chart

8 posts, 0 answers
  1. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 04 Sep 2009 Link to this post

    Hi,

    I have a chart (Line) bound to an ObservableCollection containing objects with a DateTime and an int value.
    There are a number of problems I ran into with this solution.
    So let me first explain the solution (desired result).
    The YAxis should display values from 0 to 255 (byte range).
    The XAxsi should display a certain number of seconds from the beginning of the data to the end.
    To explain it assume 10 seconds of display.
    So I check the first datapoint subtract 0.5 seconds (for better display) and set this as XMin.
    Then I add 10 seconds and set this as XMax.

    While running the programm I add values to the collection and if the latest value is older than the first value + 10 seconds I remove items from the front of the collection.
    So what I get is a "growing" display of datapoint - than a "scroll" and again it adds data point....
    I have this working - but now my problems (I guess I do something wrong) start.
    You can imagine the solution as some kind of "live trend display".

    Here the code to setup the chart.
    private void InitGrid() {  
        rcData.DefaultView.ChartArea.EnableAnimations = false;  
        rcData.DefaultView.ChartLegend.Visibility = System.Windows.Visibility.Collapsed;  
        rcData.DefaultSeriesDefinition = new LineSeriesDefinition();  
        rcData.DefaultSeriesDefinition.Appearance.Stroke = Brushes.Red;  
        rcData.DefaultSeriesDefinition.Appearance.StrokeThickness = 2;  
        rcData.DefaultSeriesDefinition.ShowItemToolTips = true;  
        rcData.DefaultView.ChartArea.AxisX.IsDateTime = true;  
        rcData.DefaultView.ChartArea.AxisX.LabelRotationAngle = 80;  
        //60 would be better - but then the last label is truncated...  
        rcData.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "HH:mm:ss";  
        rcData.DefaultView.ChartArea.AxisX.LayoutMode = AxisLayoutMode.Normal;  
        rcData.DefaultView.ChartArea.AxisX.AutoRange = false;  
     
        if(m_ocData.Count > 0) {  
            rcData.DefaultView.ChartArea.AxisX.MinValue = m_ocData.First().MeassureTime.AddSeconds(-0.5).ToOADate();  
            rcData.DefaultView.ChartArea.AxisX.MaxValue = m_ocData.First().MeassureTime.AddSeconds(ms_nWindowLength + 1).ToOADate();  
        }  
     
        rcData.DefaultView.ChartArea.AxisX.LabelStep = 1;  
        rcData.DefaultView.ChartArea.AxisX.MajorGridLinesVisibility = Visibility.Visible;  
        rcData.DefaultView.ChartArea.AxisX.Step = 0.000022890946517388029 / 2;  
     
        rcData.DefaultView.ChartArea.AxisY.AutoRange = false;  
        rcData.DefaultView.ChartArea.AxisY.MinValue = 0;  
        rcData.DefaultView.ChartArea.AxisY.MaxValue = 255;  
        rcData.DefaultView.ChartArea.AxisY.MinorTicksVisibility = Visibility.Collapsed;  
     
          
     
        rcData.DefaultView.ChartArea.ItemToolTipOpening += new ItemToolTipEventHandler(ChartArea_ItemToolTipOpening);  
        SeriesMapping seriesMapping = new SeriesMapping();  
        seriesMapping.ItemMappings.Add(new ItemMapping("TheValue", DataPointMember.YValue));  
        seriesMapping.ItemMappings.Add(new ItemMapping("MeassureTime", DataPointMember.XValue));  
        rcData.SeriesMappings.Add(seriesMapping);  
        rcData.ItemsSource = m_ocData;  
        //if done before binding it doesn't work :(  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Clear();  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 0 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 50 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 100 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 150 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 200 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 255 });  
     
    }  
     
     
    By the way: DataPoints near 0 (0-15) have their label outside the chart - only partial visible

    First problem:
    When I add the first entry (my collection has one entry) I see a little part of a line - but not no DataPoint (label).

    The next problems.
    For YAxis I have min==0 max==255 (or 260 if this would help - it doesn't)
    I messed around a lot with YAxis settings to have a scale showing 0, 50, 100, 150, 200, 255 (250 or 260 would be OK also).
    The Step property doesn't help.
    If I set it to 50 I get 51, 102, 153, 205, 255
    Setting it to 49, 48 and 47 brings the same result.
    With 46 I get 42.5, 85, 127,5.... :)
    The only solution I found was to clear the TickPoints and add my values manually.
    The problem - the TickPoints are newly created after I bind the data.
    I solved this (although I don't understand why it is like this - I said "AutoRange" to off) by clearing / adding the ticks AFTER data binding.

    When I reach the end of the space in the chart I do some kind of scroll. This means I remove the first xxx Items till the data fits again.
    And because I have "manual XAxis" I change the XMinValue and the XMaxValue to reflect the changes.
    The code looks (shoul look) like this:
        if(m_ocData.Count > 0) {  
            rcData.DefaultView.ChartArea.AxisX.MinValue = m_ocData.First().MeassureTime.AddSeconds(-0.5).ToOADate();  
            rcData.DefaultView.ChartArea.AxisX.MaxValue = m_ocData.First().MeassureTime.AddSeconds(ms_nWindowLength+1).ToOADate();  
        }  
     

    Here is the next Problem:
    AxisX seems to "forget" the setting for Step when I do this.
    So I have to set it again!!!

    And the next "interesting" thing:
     YAxis also resets it's TickPoints after I do this
    So I have to set the values again.
    Finally I had to use:
    private void ScrollGrid() {  
        if(m_ocData.Count > 0) {  
            rcData.DefaultView.ChartArea.AxisX.MinValue = m_ocData.First().MeassureTime.AddSeconds(-0.5).ToOADate();  
            rcData.DefaultView.ChartArea.AxisX.MaxValue = m_ocData.First().MeassureTime.AddSeconds(ms_nWindowLength+1).ToOADate();  
        }  
        //set some values again - they get lost  
        rcData.DefaultView.ChartArea.AxisX.Step = 0.000022890946517388029 / 2;  
          
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Clear();  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 0 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 50 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 100 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 150 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 200 });  
        rcData.DefaultView.ChartArea.AxisY.TickPoints.Add(new TickPoint() { Value = 255 });  
    }  
     

    I guess I do something wrong because:
    a.) Why should the chart overwrite settings I made when I change a ( totally different) setting
    --like with XMinValue and XMaxValue which overrides AxisY.TickPoints
    b.) Why should the chart change my TickPoints when I bind data?
    --although I told it that I don't want AutoRange
    c.) Why is there no easy way to tell the chart "pleas divide my XAxis to seconds"
    --OK - would not help here - I need the "free space" to add points (and I found no X-Range property)
    --I tried "continuous" scrolling (simply adding a point to the end - and remove on on the front of my collection)
    --This flickers so much - unusable :(
    d.) Why is "step" for the AxisY divider and not step?
    --If Step 50 would (on 0 to 255) would bring 0, 50, 100, 150, 200, 250) would be great (and expected)

    My Intention (and the results from what I found):
    Have a chart with Y-Labels 0, 50, 100, 150, 200, 250 (or 255)
    Has to be done manually - no problem if these values wouldn't been overridden by databind or changing XAxis min / max.
    Have an XAxis with a label every second and a display range of 15 seconds (just a number).
    Not possible
    - I found no way to declare "1 second label distance"
    - I found no way to say "XRange 30 seconds"
    So I had to do it manually.
    But I ran in the problem that AxisX.Step is overwritten when I change the min/max.

    I hope someone can tell me what I'm doing wrong.
    I have it working - but I guess what I do is "hacking in the dark" :)

    Regards

    Manfred
  2. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 04 Sep 2009 Link to this post

    Just a little follow up:

    It seems as if XAxis assumes the first point is position 0.
    I set it (via MinValue) to have some "border" (otherwise the first point looks bad) of 0.5 seconds.
    When I later add the data the display doesn't match the time (it has a delta):
    Here 2 Pictures about it:
    The first point should be at 17:00
    The second point should be behind 18:00

    And here the thing with labels near zero:

    Regards

    Manfred
  3. UI for WPF is Visual Studio 2017 Ready
  4. Velin
    Admin
    Velin avatar
    391 posts

    Posted 09 Sep 2009 Link to this post

    Hi ManniAT,

    Onto your questions:
    1. "So I check the first datapoint subtract 0.5 seconds (for better display) and set this as XMin.
      Then I add 10 seconds and set this as XMax.
      " - Please do not subtract seconds from the min value. Instead, set the LayoutMode of the XAxis to Inside.
      RadChart1.DefaultView.ChartArea.AxisX.LayoutMode = AxisLayoutMode.Inside; 
      Another thing you could do is to change the labels format like this: 
      rcData.DefaultView.ChartArea.AxisX.DefaultLabelFormat = "HH:mm:ss:ff"
      This will give you a better view of the actual axis label values.
    2. " DataPoints near 0 (0-15) have their label outside the chart - only partial visible" - our developers  will consider the possible ways to fix this. 
    3. "When I add the first entry (my collection has one entry) I see a little part of a line - but not no DataPoint (label)" - could you please explain in more details ?
    4. "If I set it to 50 I get 51, 102, 153, 205, 255
      Setting it to 49, 48 and 47 brings the same result.
      With 46 I get 42.5, 85, 127,5
      " - unfortunately, in your case (YMaxValue - YMinValue) is not dividable by YStep and the undergoing axis logic automatically adjusts the step to a more suitable value. For example, If you set the YMaxValue to 250 you'll see that the step is preserved(50). 
    5. "the TickPoints are newly created after I bind the data." - The Axis tick points get recreated when the data has changed and this is the way the axis work. We strongly recommend you to avoid adding TickPoints of your own to the axis. Please, note that if you set the YMaxValue to 250, there will be no need to add custom tick points, because the automatically generated tick points values will be have the desired step. 

    Greetings,
    Velin
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  5. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 09 Sep 2009 Link to this post

    Hi Velin,

    thanks for the detailed answer - I'll give it a try the next days.
    About question 3:
    Add data with ONE entry only to a line chart and you'll see what I mean.
    Expected: Circle with label (no line of course - where should if connect to)
    Got: no circle - no label - just a little line fragment.

    Regards
    Manfred
  6. ManniAT
    ManniAT avatar
    877 posts
    Member since:
    Nov 2003

    Posted 09 Sep 2009 Link to this post

    Hi Velin,

    now to your (very helpful) answers
    1.) looks OK I'll use it like this
    2.) Part of seconds ..:ss.ff - is to much for the labels - I already use it in ToolTip
    4.) OK
    5.) here a screenshot http://www.pp-p.com/SFiles/Charterror5.png
    6.) a fact - but no solution for me if I use (what's correct and common in automation) 255 - I have the "bad values"
    if I use (as suggested) 250 then that's the result:
    http://www.pp-p.com/SFiles/Charterror6.png
    7.) event if I don't use "custom tick points" -- when I scroll then I always have to set ...XAxis.Step again - the value get's lost.
    and your (quote from 7) "there will be no need to add custom tick points" is (at the current state - see 6. - wrong

    Maybe we can figure out a solution

    Regards
    Manfred

  7. Velin
    Admin
    Velin avatar
    391 posts

    Posted 11 Sep 2009 Link to this post

    Hi ManniAT,

    2. This was just a suggestion which was to allow you to compare the actual values of the axis labels and the item labels above more easily.
    5. By default a line needs at least two points to render - in case of only one RadChart should not render any data. Our developers will research the problem and provide a solution with a future release.
    6. You could use a different Y range. For example, 0-300 or 100-300 if your data falls within this range. This will make the line graph appear vertically centered.
    7. Indeed there seems to be a problem with the X axis step. Our developers will research this too.

    Thank you for the valuable feedback.

    Kind regards,
    Velin
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  8. Schley
    Schley avatar
    7 posts
    Member since:
    Jan 2009

    Posted 14 Feb 2012 Link to this post

    This seems to be the exact issue I'm facing. I cannot get the RadChart's X-axis to show any labels tick marks for date time intervals measured in seconds even when I modify my Step. Any follow up with this? Thanks!
  9. Petar Marchev
    Admin
    Petar Marchev avatar
    968 posts

    Posted 17 Feb 2012 Link to this post

    Hi,

    If I understand correctly you have issues with the axis not showing ticks for any second. Are you using the latest version of our controls?

    I have attached some code and a snapshot of the result I get. As you can see in the image - the axis is showing the ticks correctly.

    If you keep experiencing issues with this I would suggest that you open a new thread and let us know more about your project - you can include a sample code and snapshots.

    Regards,
    Petar Marchev
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Back to Top
UI for WPF is Visual Studio 2017 Ready