Я изменил прокручиваемый пример , чтобы использовать VMache Рэйчел Лим с навигационным примером и получить данные из нашей базы данных.Я также перенес некоторую логику с выделенным кодом в ВМ.Все отлично работает с LiveCharts.ChartValues, но при использовании LiveCharts.Geared.GearedValues библиотека вылетает при увеличении / уменьшении масштаба до определенной точки.
Данные имеют 6 часовых значений с отметкой времени.Я группирую и суммирую значения по часам.Временная метка и значения никогда не равны нулю и не являются расчетными суммамиЯ не обновляю данные после того, как диаграмма нарисована.
Если я получу 1000 значений (~ 1000/6 точек данных) из базы данных, библиотека вылетает при уменьшении приблизительно в 5 раз от диапазона данных.Если я получу 10000 значений (~ 10000/6 точек данных), сбой произойдет, как только пользователь перейдет к управлению пользователем, где находится диаграмма.Если я получаю 100000 значений, происходит сбой при приближении приблизительно к тому же минимальному значению и максимальному значению.
Однако при использовании ChartValues вместо GearedValues или при использовании только нескольких точек данных я могу увеличивать масштаб настолько близко, насколько я хочу, и уменьшать масштаб доDateTime.minvalue.
My view.xaml (в основном пример, но с использованием ICommand RangeChangedCommand):
<UserControl
[ ....]
xmlns:geared="clr-namespace:LiveCharts.Geared;assembly=LiveCharts.Geared">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"></TextBlock>
<lvc:CartesianChart Grid.Row="1"
Zoom="X"
DisableAnimations="True"
Hoverable="False">
<lvc:CartesianChart.Resources>
<Style TargetType="lvc:Separator">
<Setter Property="StrokeThickness" Value="2.5"></Setter>
<Setter Property="Stroke" Value="#E7E7E7"></Setter>
<Style.Triggers>
<Trigger Property="AxisOrientation" Value="X">
<Setter Property="IsEnabled" Value="False"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</lvc:CartesianChart.Resources>
<lvc:CartesianChart.Series>
<geared:GLineSeries StrokeThickness="0"
Values="{Binding Values}"
Fill="#2194F1"
AreaLimit="0"
PointGeometry="{x:Null}"
LineSmoothness="0"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis LabelFormatter="{Binding Formatter}" RangeChangedCommand="{Binding Axis_OnRangeChangedCommand}"
MinValue="{Binding From, Mode=TwoWay}" MaxValue="{Binding To, Mode=TwoWay}"
Separator="{x:Static lvc:DefaultAxes.CleanSeparator}"/>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
<lvc:CartesianChart Grid.Row="2" DisableAnimations="True"
ScrollMode="X"
ScrollHorizontalFrom="{Binding From, Mode=TwoWay}"
ScrollHorizontalTo="{Binding To, Mode=TwoWay}"
ScrollBarFill="#25303030"
DataTooltip="{x:Null}"
Hoverable="False"
Margin="20 10">
<lvc:CartesianChart.Resources>
<Style TargetType="lvc:Separator">
<Setter Property="IsEnabled" Value="False"></Setter>
</Style>
</lvc:CartesianChart.Resources>
<lvc:CartesianChart.Series>
<geared:GLineSeries Values="{Binding Values}"
Fill="Silver"
StrokeThickness="0"
PointGeometry="{x:Null}"
AreaLimit="0"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis IsMerged="True"
LabelFormatter="{Binding Formatter, Mode=OneTime}"
Foreground="#98000000"
FontSize="22"
FontWeight="UltraBold"/>
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis ShowLabels="False" />
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</Grid>
My VM.cs
class ScrollableVM : ObservableObject, IPageViewModel
{
public string Name => "Scrollable";
private double _from;
private double _to;
private Func<double, string> _formatter;
private ICommand _axis_OnRangeChanged;
public GearedValues<DateTimePoint> Values { get; set; }
//public ChartValues<DateTimePoint> Values { get; set; }
#region setget
public double From
{
get { return _from; }
set
{
SetProperty(ref _from, value);
}
}
public double To
{
get { return _to; }
set
{
SetProperty(ref _to, value);
}
}
public Func<double, string> Formatter
{
get { return _formatter; }
set
{
SetProperty(ref _formatter, value);
}
}
#endregion
public ScrollableVM()
{
var l = new List<DateTimePoint>();
using (/***getting data from db***/)
{
var q =(/***getting data from db***/).Take(1000).ToList();
var grouped = q.GroupBy(t => new DateTime(t.Stamp.Value.Year, t.Stamp.Value.Month, t.Stamp.Value.Day, t.Stamp.Value.Hour, 0, 0));
foreach (var item in grouped)
{
l.Add(new DateTimePoint((DateTime)item.Key, (double)item.Sum(x => x.value)));
}
}
//Crashes
//quality doesn't affect crashing
Values = l.AsGearedValues().WithQuality(Quality.High);
////Works
//Values = new GearedValues<DateTimePoint>() { new DateTimePoint(DateTime.Now, 0), new DateTimePoint(DateTime.Now.AddHours(1), 1) , new DateTimePoint(DateTime.Now.AddHours(2), 2) };
////Works
//Values = l.AsChartValues();
From = Values.Min(x => x.DateTime).Ticks;
To = Values.Max(x => x.DateTime).Ticks;
Formatter = x => new DateTime((long)x).ToString("yyyy");
}
private void Axis_OnRangeChanged(RangeChangedEventArgs eventargs)
{
var currentRange = eventargs.Range;
if (currentRange < TimeSpan.TicksPerDay * 2)
{
Formatter = x => new DateTime((long)x).ToString("t");
return;
}
if (currentRange < TimeSpan.TicksPerDay * 60)
{
Formatter = x => new DateTime((long)x).ToString("dd MMM yy");
return;
}
if (currentRange < TimeSpan.TicksPerDay * 540)
{
Formatter = x => new DateTime((long)x).ToString("MMM yy");
return;
}
Formatter = x => new DateTime((long)x).ToString("yyyy");
}
public ICommand Axis_OnRangeChangedCommand
{
get
{
if (_axis_OnRangeChanged == null)
{
_axis_OnRangeChanged = new RelayCommand(a => Axis_OnRangeChanged((RangeChangedEventArgs)a));
}
return _axis_OnRangeChanged;
}
}
}
view.xaml.cs имеет только конструктор с InitializeComponent ()
Сведения об исключении:
System.ArgumentOutOfRangeException
HResult=0x80131502
Message=Specified argument was out of the range of valid values.
Parameter name: index
Source=WindowsBase
StackTrace:
at MS.Utility.FrugalStructList`1.Insert(Int32 index, T value)
at System.Windows.Media.PathSegmentCollection.Insert(Int32 index, PathSegment value)
at LiveCharts.Wpf.Points.HorizontalBezierPointView.DrawOrMove(ChartPoint previousDrawn, ChartPoint current, Int32 index, ChartCore chart)
at LiveCharts.SeriesAlgorithms.LineAlgorithm.Update()
at LiveCharts.ChartUpdater.Update(Boolean restartsAnimations, Boolean force)
at LiveCharts.Wpf.Components.ChartUpdater.UpdaterTick(Boolean restartView, Boolean force)
at LiveCharts.Wpf.Components.ChartUpdater.OnTimerOnTick(Object sender, EventArgs args)
at System.Windows.Threading.DispatcherTimer.FireTick(Object unused)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at medidata.App.Main() in ....\source\repos\medidata\medidata\obj\Debug\App.g.cs:line 51
Версии:
- LiveCharts 0.9.7.0
- LiveCharts.Geared 1.2.8.2
- LiveCharts.Wpf 0.9.7
Есть ли в моем коде / логике что-то напуганное, или я должен сообщить об этой ошибке??Я не нашел подобных проблем, о которых кто-либо еще сообщал.Заранее спасибо.