我的应用程序通过给定的公式计算点。以较小的间隔向图表中添加新的点。使用滑块,我可以调整这些点的值。
出于优化目的,不必要的点开始从列表中删除。但删除后,移动滑块时,下一个点的值开始计算错误。
删除点之前(gif(
点删除后(gif(
如何解决这个问题?
类别:
using System.Windows;
using LiveCharts;
using LiveCharts.Wpf;
using LiveCharts.Defaults;
using System.Windows.Media;
using System.Threading.Tasks;
using System;
using System.Threading;
namespace TestChartApp
{
public partial class MainWindow : Window
{
SeriesCollection series = new SeriesCollection();
ChartValues<ObservableValue> observableValues = new ChartValues<ObservableValue>();
LineSeries lineSeries = new LineSeries
{
Stroke = Brushes.Blue,
Fill = Brushes.Transparent,
PointGeometry = null
};
double currentStep = 0;
public MainWindow()
{
InitializeComponent();
lineSeries.Values = observableValues;
series.Add(lineSeries);
myChart.Series = series;
myChart.DataTooltip = null;
myChart.Hoverable = false;
Task.Factory.StartNew(AddValues);
}
private void AddValues()
{
Application.Current.Dispatcher.Invoke(() =>
{
ObservableValue value = new ObservableValue(sAmplitude.Value * Math.Sin(2 * Math.PI * 0.25 * currentStep));
currentStep += 0.06;
observableValues.Add(value);
if (observableValues.Count > 100)
{
SetAxisLimits(observableValues.Count);
}
if (observableValues.Count > 150)
{
observableValues.RemoveAt(0);
}
});
Thread.Sleep(35);
Task.Factory.StartNew(AddValues);
}
private void SetAxisLimits(double value)
{
Axis axis = myChart.AxisX[0];
axis.MinValue += value - axis.MaxValue;
axis.MaxValue = value;
}
private void ChangeObservableValues()
{
int j = 0;
for (double i = 0.0; j < observableValues.Count; i += 0.06)
{
observableValues[j++].Value = sAmplitude.Value * Math.Sin(2 * Math.PI * 0.25 * i);
}
}
private void sAmplitude_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (lineSeries.Values != null)
{
ChangeObservableValues();
}
}
}
}
XAML:
<Window x:Class="TestChartApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestChartApp"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.8*"/>
<RowDefinition Height="0.2*"/>
</Grid.RowDefinitions>
<lvc:CartesianChart x:Name="myChart" DisableAnimations="True">
<lvc:CartesianChart.AxisX>
<lvc:Axis MaxValue="100" MinValue="0" Labels="" Unit="1">
<lvc:Axis.Separator>
<lvc:Separator Step="20">
<lvc:Separator.Stroke>
<SolidColorBrush Color="Gray" />
</lvc:Separator.Stroke>
</lvc:Separator>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis MaxValue="100" MinValue="-100" Labels="">
<lvc:Axis.Separator>
<lvc:Separator>
<lvc:Separator.Stroke>
<SolidColorBrush Color="Gray" />
</lvc:Separator.Stroke>
</lvc:Separator>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Slider x:Name="sAmplitude" HorizontalAlignment="Stretch" Margin="30 30 30 0" Grid.Row="1" VerticalAlignment="Top" Maximum="100" Value="50" LargeChange="10" ValueChanged="sAmplitude_ValueChanged"/>
</Grid>
</Grid>
</Window>
在更新旧数据时,似乎计算了错误的值ChangeObservableValues
正在计算自己的currentSteps
值,总是从0
开始,这是错误的,因为当前数据点的原始值更大:
CurrentDataPoint的原始CurrentStepsOf=绝对当前数据点位置*0.06。
为了便于重构并消除潜在的错误源,值0.06
应该是常量字段或只读属性。
private const double Step = 0.06;
private void ChangeObservableValues()
{
// Because the collection only contains the latest 150 values,
// we can calculate the absolute position using the collection's Count
var restoredCurrentStep =
this.currentStep - this.observableValues.Count * MainWindow.Step;
for (int index = 0; index < observableValues.Count; index++)
{
observableValues[index].Value =
sAmplitude.Value * Math.Sin(2 * Math.PI * 0.25 * restoredCurrentStep);
restoredCurrentStep += MainWindow.Step;
}
}