issue on DateTimeAxis with 1 value

May 31, 2010 at 12:23 PM

If a chart only contains 1 single datetime value the chart will generate a Nullreference exception (see below).

1 single datapoint in a chart item will cause this, but also multiple datapoints with the same datetime value. If I set a minimum and maximum value in the XAML it works well, but if I want to bind to a maximum value that I make let's say a minute more than the maximum datapoint datetime value I'm back to the same exception again.

If somebody already found a workaround for this I would be truly happy!

 

   at System.Windows.Controls.DataVisualization.Charting.DateTimeAxis.OverrideDataRange(Range`1 range) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Axis\DateTimeAxis.cs:line 989
   at System.Windows.Controls.DataVisualization.Charting.RangeAxis.<UpdateActualRange>b__9() in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Axis\RangeAxis.cs:line 293
   at System.Windows.Controls.DataVisualization.Charting.RangeAxis.UpdateActualRange() in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Axis\RangeAxis.cs:line 308
   at System.Windows.Controls.DataVisualization.Charting.RangeAxis.OnObjectRegistered(IAxisListener series) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Axis\RangeAxis.cs:line 522
   at System.Windows.Controls.DataVisualization.Charting.Axis.RegisteredListenersCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Axis\Axis.cs:line 216
   at System.Collections.Specialized.NotifyCollectionChangedEventHandler.Invoke(Object sender, NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.OnCollectionChanged(NotifyCollectionChangedEventArgs e)
   at System.Collections.ObjectModel.ObservableCollection`1.InsertItem(Int32 index, T item)
   at System.Windows.Controls.DataVisualization.UniqueObservableCollection`1.InsertItem(Int32 index, T item) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\UniqueObservableCollection.cs:line 26
   at System.Collections.ObjectModel.Collection`1.Add(T item)
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeriesWithAxes.GetAxes(DataPoint firstDataPoint, Func`2 independentAxisPredicate, Func`1 independentAxisFactory, Func`2 dependentAxisPredicate, Func`1 dependentAxisFactory) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeriesWithAxes.cs:line 489
   at System.Windows.Controls.DataVisualization.Charting.LineSeries.GetAxes(DataPoint firstDataPoint) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\LineSeries.cs:line 98
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeriesWithAxes.GetAxes() in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeriesWithAxes.cs:line 394
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeriesWithAxes.OnDataPointsChanged(IList`1 newDataPoints, IList`1 oldDataPoints) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeriesWithAxes.cs:line 319
   at System.Windows.Controls.DataVisualization.Charting.DataPointSingleSeriesWithAxes.OnDataPointsChanged(IList`1 newDataPoints, IList`1 oldDataPoints) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSingleSeriesWithAxes.cs:line 277
   at System.Windows.Controls.DataVisualization.Charting.LineAreaBaseSeries`1.OnDataPointsChanged(IList`1 newDataPoints, IList`1 oldDataPoints) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\LineAreaBaseSeries.cs:line 168
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeries.LoadDataPoints(IEnumerable newItems, IEnumerable oldItems) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeries.cs:line 826
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeries.Refresh() in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeries.cs:line 994
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeries.OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeries.cs:line 232
   at System.Windows.Controls.DataVisualization.Charting.DataPointSeries.OnItemsSourceChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) in C:\dd\WPF_1\src\wpf\src\ControlsPack\WPFToolkit\DataVisualization\Charting\Series\DataPointSeries.cs:line 197
   at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
   at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
   at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
   at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp)
   at System.Windows.Data.BindingExpression.Invalidate(Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
   at System.Windows.Data.BindingExpression.Activate(Object item)
   at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
   at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
   at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
   at MS.Internal.Data.DataBindEngine.Run(Object arg)
   at MS.Internal.Data.DataBindEngine.OnLayoutUpdated(Object sender, EventArgs e)
   at System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
   at System.Windows.ContextLayoutManager.UpdateLayout()
   at System.Windows.UIElement.UpdateLayout()
   at System.Windows.Interop.HwndSource.SetLayoutSize()
   at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value)
   at System.Windows.Interop.HwndSource.set_RootVisual(Visual value)
   at System.Windows.Window.SetRootVisual()
   at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight)
   at System.Windows.Window.CreateSourceWindowImpl()
   at System.Windows.Window.SafeCreateWindow()
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.Show()
   at System.Windows.Window.ShowDialog()

Jul 2, 2010 at 6:18 PM
Edited Jul 2, 2010 at 6:22 PM
Hi,

I seem to be running into the same problem.

- In DateTimeAxis.OverrideDataRange(), there's a "while (maxLeftOverlapValueMargin.LeftOverlap > 0 || maxRightOverlapValueMargin.RightOverlap > 0)" loop.
- The crash occurs since maxLeftOverlapValueMargin is null.
- maxLeftOverlapValueMargin is found in the line right before that loop: GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin);
- GetMaxLeftAndRightOverlap() is defined in the RangeAxis as a static function.
- There's a check if (leftOverlap > maxLeftOverlap) that does not seem to become true because at this point the leftOverlap = -Infinity...
- double leftOverlap = valueMargin.LeftOverlap where valueMargin is passed in as parameter.


Has there been any update to this issue? Seems like there might be some boundary condition bug with this function?
Jul 2, 2010 at 7:20 PM
Edited Jul 2, 2010 at 7:21 PM
I managed to find a fix in DateTimeAxis.OverrideDataRange().

It's a little hacky as it simply bypasses the valueMargins that causes the crash. I guess there's something greater at work here but I don't understand the rest of the system :(

Anyway, replacing the while loop in the function with this will bypass null errors and -ve values.

while ( (maxLeftOverlapValueMargin != null && maxLeftOverlapValueMargin.LeftOverlap > 0) ||
(maxRightOverlapValueMargin != null && maxRightOverlapValueMargin.RightOverlap > 0))
{
long unitOverPixels = currentRange.GetLength().Value.Ticks / ((long) actualLength);
long minDateTimeTicks = currentRange.Minimum.Ticks;
long maxDateTimeTicks = currentRange.Maximum.Ticks;


if(maxLeftOverlapValueMargin != null)
{
long leftOverlapOffset = (long)((maxLeftOverlapValueMargin.LeftOverlap + 0.5) * unitOverPixels);
if (leftOverlapOffset > 0)
{
minDateTimeTicks -= leftOverlapOffset;
}
Debug.Assert(maxDateTimeTicks >= DateTime.MinValue.Ticks && maxDateTimeTicks <= DateTime.MaxValue.Ticks);
}


if (maxRightOverlapValueMargin != null)
{
long rightOverlapOffset = (long)((maxRightOverlapValueMargin.RightOverlap + 0.5) * unitOverPixels);
if (rightOverlapOffset > 0)
{
maxDateTimeTicks += rightOverlapOffset;
}
Debug.Assert(maxDateTimeTicks >= DateTime.MinValue.Ticks && maxDateTimeTicks <= DateTime.MaxValue.Ticks);
}


DateTime newMinimum = new DateTime(minDateTimeTicks);
DateTime newMaximum = new DateTime(maxDateTimeTicks);


currentRange = new Range<DateTime>(newMinimum, newMaximum);
UpdateValueMargins(valueMargins, currentRange.ToComparableRange());
GetMaxLeftAndRightOverlap(valueMargins, out maxLeftOverlapValueMargin, out maxRightOverlapValueMargin);
}


Please let us know if anyone knows of a proper fix!
Feb 18, 2011 at 7:36 PM

Any update with this issue?