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.
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:
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:
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
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 }); |
} |
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