使用实时图表来数据日志传入的序列数据。从长远来看,我将有6组不同的变量从Arduino发送。从U-Z标记。当它简单地读取和绘制数据时,我的图表以相对较高的速度工作,但是一旦涉及"如果"语句,它就会大大减慢。我担心的是,一旦我合并了另外6个数据(尽管每张图只有2个数据,所以总共3个图)该程序运行速度太慢,无法使数据记录值得。
我添加了一个文本框来读取所有传入数据,并且正在按预期进行更新。除此之外
谢谢!
public partial class MainWindow : Window, INotifyPropertyChanged
{
private double _axisMax;
private double _axisMin;
Stopwatch stopwatch = new Stopwatch();
SerialPort myPort;
public MainWindow()
{
InitializeComponent();
myPort = new SerialPort("COM4", 9600, Parity.None, 8, StopBits.One);
myPort.Open();
//To handle live data easily, in this case we built a specialized type
//the MeasureModel class, it only contains 2 properties
//DateTime and Value
//We need to configure LiveCharts to handle MeasureModel class
//The next code configures MEasureModel globally, this means
//that livecharts learns to plot MeasureModel and will use this config every time
//a ChartValues instance uses this type.
//this code ideally should only run once, when application starts is reccomended.
//you can configure series in many ways, learn more at http://lvcharts.net/App/examples/v1/wpf/Types%20and%20Configuration
var mapper = Mappers.Xy<MeasureModel>()
.X(model => model.DateTime.Ticks) //use DateTime.Ticks as X
.Y(model => model.Value); //use the value property as Y
var mapper2 = Mappers.Xy<Graph1SecondVal>()
.X(model => model.DateTime.Ticks) //use DateTime.Ticks as X
.Y(model => model.Value);
//lets save the mapper globally.
Charting.For<MeasureModel>(mapper);
Charting.For<Graph1SecondVal>(mapper2);
//the values property will store our values array
ChartValues = new ChartValues<MeasureModel>();
ChartValuesTwo = new ChartValues<Graph1SecondVal>();
//lets set how to display the X Labels
DateTimeFormatter = value => new DateTime((long)value).ToString("hh:mm:ss");
AxisStep = TimeSpan.FromSeconds(1).Ticks;
SetAxisLimits(DateTime.Now);
//The next code simulates data changes every 300 ms
Timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(10)
};
Timer.Tick += TimerOnTick;
IsDataInjectionRunning = false;
R = new Random();
DataContext = this;
}
public ChartValues<Graph1SecondVal> ChartValuesTwo { get; set; }
public ChartValues<MeasureModel> ChartValues { get; set; }
public Func<double, string> DateTimeFormatter { get; set; }
public double AxisStep { get; set; }
public double AxisMax
{
get { return _axisMax; }
set
{
_axisMax = value;
OnPropertyChanged("AxisMax");
}
}
public double AxisMin
{
get { return _axisMin; }
set
{
_axisMin = value;
OnPropertyChanged("AxisMin");
}
}
public DispatcherTimer Timer { get; set; }
public bool IsDataInjectionRunning { get; set; }
public Random R { get; set; }
private void RunDataOnClick(object sender, RoutedEventArgs e)
{
if (IsDataInjectionRunning)
{
stopwatch.Stop();
Timer.Stop();
IsDataInjectionRunning = false;
}
else
{
stopwatch.Start();
Timer.Start();
IsDataInjectionRunning = true;
}
}
private void TimerOnTick(object sender, EventArgs eventArgs) // Class is referencing from here!
{
var now = DateTime.Now;
ProcessData();
SetAxisLimits(DateTime.Now);
//lets only use the last 30 values
if (ChartValues.Count > 50) ChartValues.RemoveAt(0);
}
private void SetAxisLimits(DateTime now)
{
AxisMax = now.Ticks + TimeSpan.FromSeconds(1).Ticks; // lets force the axis to be 100ms ahead
AxisMin = now.Ticks - TimeSpan.FromSeconds(8).Ticks; //we only care about the last 8 seconds
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
if (PropertyChanged != null) // if subrscribed to event
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
void ProcessData()
{
int NumberInt = 0;
string IncomingSerial = myPort.ReadLine(); // Read incomming serial data
string StrIncomingSerial = IncomingSerial.ToString(); // convert this data to workable string
if (StrIncomingSerial.Contains("Z"))
{
string Number = myPort.ReadLine(); // Read Serialport
double Num; // Create variable "Num"
bool isNum = double.TryParse(Number, out Num); // Is the incomming serial data a number?
if (isNum) // If it is a number...
{
NumberInt = Convert.ToInt16(Number); // convert string to int
textBox1.Text = NumberInt.ToString() + "," + textBox1.Text;
}
myPort.DiscardInBuffer();
ChartValues.Add(new MeasureModel
{
DateTime = DateTime.Now,
Value = NumberInt
});
}
if (StrIncomingSerial.Contains("Y"))
{
string Number = myPort.ReadLine(); // Read Serialport
double Num; // Create variable "Num"
bool isNum = double.TryParse(Number, out Num); // Is the incomming serial data a number?
if (isNum) // If it is a number...
{
NumberInt = Convert.ToInt16(Number); // convert string to int
textBox1.Text = NumberInt.ToString() + "," + textBox1.Text;
}
myPort.DiscardInBuffer();
ChartValuesTwo.Add(new Graph1SecondVal
{
DateTime = DateTime.Now,
Value = NumberInt
});
}
SetAxisLimits(DateTime.Now);
}
private void ReadSerial_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 10; i++)
{
string Number = myPort.ReadLine(); // Read Serialport
textBox1.Text = Number.ToString() + "," + textBox1.Text;
}
myPort.DiscardInBuffer();
}
}
<Window
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:graph_test_6"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
xmlns:geared="clr-namespace:LiveCharts.Geared;assembly=LiveCharts.Geared"
xmlns:chart="http://mindfusion.eu/charting/wpf" x:Class="graph_test_6.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Height="30" Click="RunDataOnClick">
Inject/Stop Data
</Button>
<lvc:CartesianChart Grid.Row="1" AnimationsSpeed="0:0:0" Hoverable="False">
<lvc:CartesianChart.Series>
<lvc:LineSeries Values="{Binding ChartValues}" PointGeometrySize="5" StrokeThickness="1" />
<lvc:LineSeries Values="{Binding ChartValues2}" PointGeometrySize="5" StrokeThickness="1" />
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis LabelFormatter="{Binding DateTimeFormatter}"
MaxValue="{Binding AxisMax}"
MinValue="{Binding AxisMin}"
DisableAnimations="True">
<lvc:Axis.Separator>
<lvc:Separator Step="{Binding AxisStep}"></lvc:Separator>
</lvc:Axis.Separator>
</lvc:Axis>
</lvc:CartesianChart.AxisX>
</lvc:CartesianChart>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="323,-71,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<TextBox x:Name="textBox1" HorizontalAlignment="Left" Height="189" Margin="43,299,0,-199" Grid.Row="1" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Width="203"/>
<Button x:Name="ReadSerial" Content="Button" HorizontalAlignment="Left" Height="54" Margin="43,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="75" Click="ReadSerial_Click"/>
</Grid>
public class MeasureModel
{
public DateTime DateTime { get; set; }
public double Value { get; set; }
}
public class Graph1SecondVal
{
public DateTime DateTime { get; set; }
public double Value { get; set; }
}
阅读以下内容:
https://lvcharts.net/app/examples/v1/wpf/performance Tips
如果使用这些属性,则可以获得更高的速度:
<lvc:CartesianChart Hoverable="False" DataTooltip="{x:Null}" />
Attibute的" DatatoolTip"很大。
很难说,而无需在代码上找到探查器以查看主捏点在哪里。这是一些尝试
的thigns- 假设criscomingserial string只有一种类型的值 ,请使用其他模式
- 您试图将字符串解析为一个数字,然后再次转换,尝试使用以前使用过的NUM
- 看来您正在调用setaxislimits每滴两次,尝试删除其中一个
让我知道是否有帮助