「实战应用」如何使用图表控件LightningChart创建数据采集系统?(三)

LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点。 LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼/甜甜圈,地理地图和GIS图表以及适用于科学、工程、医学、航空、贸易、能源和其他领域的体绘制功能。

在上文中(点击这里回归>>)介绍了什么是高速数据采集图以及项目概述、系统设置等,本文将继续介绍Visual Studio项目、具体的代码审查等,持续关注获取完整版教程哦~

立即获取LightningChart新版下载

Visual Studio项目

现在让我们使用Visual Studio,使用LightningChart可视化工具和使用Visual Studio的主要区别在于,我们将能够分析和实验源代码中的许多特性。在LC可视化器中,选择Hi Speed DAQ图表并运行示例:

LightningChart.NET实战使用教程

在窗口的右上方区域,您将看到以下选项:

LightningChart.NET实战使用教程

对于试用SDK,我们可以使用WPF框架。在点击要使用的框架后,需要指定一个文件夹来创建项目:

LightningChart.NET实战使用教程

最后将创建Hi Speed DAQ图表项目,打开Visual Studio并准备执行数字信号处理滤波器应用程序。

LightningChart.NET实战使用教程

代码审查

主代码将被封装在MainWindow.xaml.cs中,这里可以找到UI控件的代码。

LightningChart.NET实战使用教程

在代码内部我们将检查两个方法,它们会创建正确绘制高速DAQ图表所需的属性。交互式的示例是建立各种用户控件,来操纵和改变Hi Speed DAQ图表的视觉属性。生成这个图不需要这些控件,因此重点关注负责生成对象的代码。

CreateChart()

该方法将创建Hi Speed DAQ图表对象,该对象将显示在XAML框架中。我们需要创建一个lightningchart类型对象,这个构造函数将允许创建图表的实例、指定图表的类型、并访问不同的属性。

//Create new chart
_chart = new LightningChart();
//Disable rendering, strongly recommended before updating chart properties
_chart.BeginUpdate();
//Chart name
_chart.ChartName = "High-speed DAQ chart";

BeginUpdate函数将允许停止绘制图表,这将允许设置想要自定义的属性。只要更新没有关闭,图表就不会显示所做的更改,这将有助于图表构建的性能。

//Reduce memory usage and increase performance
_chart.ViewXY.DropOldSeriesData = true;
_chart.ViewXY.DropOldEventMarkers = true;

上述属性将帮助我们减少内存使用,消除值小于x轴最小值的数据序列。建议将这些属性设置为“true”,因为它们有助于实时监控图表的性能。

_chart.ViewXY.XAxes[0].Maximum = 10;
_chart.ViewXY.XAxes[0].SweepingGap = 2;
_chart.ViewXY.XAxes[0].ScrollMode = XAxisScrollMode.Sweeping;
_chart.ViewXY.XAxes[0].Title.Text = "Time";

我们正在构造的图表是XY型的,这意味着有两个轴和两个维度。要配置轴,只需要使用XAxes/YAxes属性并指定轴索引。我们可以有多个x轴和y轴,但在本例中将只有一个x轴(因此使用索引0)。

最大值表示x轴的最大值,扫描间隙是图表宽度的百分比,用于扫描图表。本示例的ScrollMode是sweeping,但可以使用scrollingsteppingtriggering, 或 none类型。

_chart.Title.Font = new WpfFont("Segoe UI", 20f, true, false);
_chart.Title.Align = ChartTitleAlignment.TopRight;
_chart.Title.Offset.SetValues(-10, 14);

title属性是指数据采集系统应用图表的主要文本或名称,可以配置它的文本样式、位置和对齐方式。

for (int channel = 0; channel < _chanelCount; channel++)
{
//New y-axis
AxisY axisY = new AxisY(_chart.ViewXY)
{
Minimum = -50,
Maximum = 50
};
axisY.MiniScale.Visible = false;
axisY.MajorDivTickStyle.Alignment = Alignment.Far;
axisY.MajorDivTickStyle.Color = Colors.Gray;
axisY.MinorDivTickStyle.Alignment = Alignment.Far;
axisY.MinorDivTickStyle.Color = Colors.Gray;
axisY.MajorGrid.Visible = gridVisible;
axisY.MinorGrid.Visible = gridVisible;
axisY.Title.Visible = false;
axisY.Units.Visible = true;
axisY.Units.Color = Colors.OrangeRed;
axisY.Units.Text = "µV";
axisY.Units.Font = new WpfFont("Lucida console", 12f, true, false);
axisY.Units.VerticalAlign = YAxisTitleAlignmentVertical.Bottom;
axisY.Units.HorizontalAlign = YAxisTitleAlignmentHorizontal.Right;
axisY.AutoDivSeparationPercent = 10;
axisY.Units.Angle = 30;
axisY.Units.Shadow.Style = TextShadowStyle.Off;
axisY.LabelsColor = Colors.White;
axisY.Alignment = AlignmentHorizontal.Right;
_chart.ViewXY.YAxes.Add(axisY);

在上面的代码块中,我们可以观察到y轴配置。该配置在一个循环中执行,该循环将为_chanelCount变量中指定的通道数量创建一个y轴。对于每个y轴,我们将创建一条称为series的线,这将表示信号数据。

SampleDataBlockSeries series = new SampleDataBlockSeries(_chart.ViewXY, _chart.ViewXY.XAxes[0], axisY);
_chart.ViewXY.SampleDataBlockSeries.Add(series);
series.Color = DefaultColors.SeriesForBlackBackgroundWpf[channel % DefaultColors.SeriesForBlackBackgroundWpf.Length];
series.AllowUserInteraction = false;
series.ScrollModePointsKeepLevel = 1;

现在要创建一条常数线,常数线固定在y轴上,并表示为信号数据上方的水平线。

ConstantLine cls = new ConstantLine(_chart.ViewXY, _chart.ViewXY.XAxes[0], axisY);
cls.Title.Text = "Constant line";
cls.Title.Visible = false;
cls.LineStyle.Color = Color.FromArgb(150, 255, 192, 0);
cls.Behind = true;
cls.LineStyle.Width = 2;
cls.AllowUserInteraction = false;
cls.Value = 0;
_chart.ViewXY.ConstantLines.Add(cls);

LightningChart.NET实战使用教程

创建游标

现在我们将为信号创建一个游标,行系列游标可以通过X坐标跟踪值来对行系列数据进行可视化分析。

LightningChart.NET实战使用教程

LineSeriesCursor cursor1 = new LineSeriesCursor(_chart.ViewXY, _chart.ViewXY.XAxes[0])
{
ValueAtXAxis = 1
};
cursor1.LineStyle.Width = 5;
Color color = Colors.OrangeRed;
cursor1.LineStyle.Color = Color.FromArgb(180, color.R, color.G, color.B);
cursor1.FullHeight = true;
cursor1.SnapToPoints = true;
cursor1.Style = CursorStyle.PointTracking;
cursor1.TrackPoint.Color1 = Colors.Yellow;
cursor1.TrackPoint.Color2 = Colors.Transparent;
cursor1.TrackPoint.Shape = Shape.Circle;
_chart.ViewXY.LineSeriesCursors.Add(cursor1);
CreateSignalGenerators()

SignalGenerator组件可用于实时生成信号,信号是由不同波形的和产生的。多个SignalGenerator组件可以使用父子关系链接起来,以产生同步的多通道输出。

private void CreateSignalGenerators()
{
int channelCount = int.Parse(textBoxChannelCount.Text);
int samplingFrequency = int.Parse(textBoxFreq.Text);
//Generator per channel
_generators = new SignalGenerator[channelCount];
for (int i = 0; i < channelCount; i++)
{
string name = "Ch " + (i + 1).ToString();
//Create and initialize generator
SignalGenerator generator = new SignalGenerator
{
GeneratorName = name
};
generator.WaveformSines.Clear();
generator.WaveformRandomNoises.Clear();
generator.SamplingFrequency = samplingFrequency;
generator.OutputInterval = 2;
generator.ThreadType = ThreadType.Timer;
创建形状

现在我们将为标志创建形状,将创建正弦、正方形和三角形,它们会被添加到信号(SignalGenerator)中。

foreach (SineComponent sc in RandomizeSineWaveformComponents())
{
generator.WaveformSines.Add(sc);
}
foreach (SquareComponent sqc in RandomizeSquareWaveformComponents())
{
generator.WaveformSquares.Add(sqc);
}
foreach (TriangleComponent tc in RandomizeTriangleWaveformComponents())
{
generator.WaveformTriangles.Add(tc);
}

为了创建多个表单,我们将使用WaveFormComponents函数,它将返回一个包含随机数量元素的列表。

// Sine Component
private List<SineComponent> RandomizeSineWaveformComponents()
{
List<SineComponent> listSines = new List<SineComponent>();
int counter = (int)(4.0 * rand.NextDouble());
for (int i = 0; i < counter; i++)
{
SineComponent sineComp = new SineComponent
{
Amplitude = rand.NextDouble() * 20.0,
DelayMs = rand.NextDouble() * 1000.0,
Frequency = rand.NextDouble() * 10.0,
Offset = 0,
Enabled = true
};
listSines.Add(sineComp);
}
return listSines;

// Square Component
private List<SquareComponent> RandomizeSquareWaveformComponents()
{
List<SquareComponent> listSquares = new List<SquareComponent>();
int counter = (int)(4.0 * rand.NextDouble());
for (int i = 0; i < counter; i++)
{
SquareComponent squareComp = new SquareComponent
{
Amplitude = rand.NextDouble() * 20.0,
DelayMs = rand.NextDouble() * 1000.0,
Frequency = rand.NextDouble() * 10.0,
Offset = 0,
//set in range 0.1...0.9
Symmetry = 0.1 + rand.NextDouble() * 0.8,
Enabled = true
};
listSquares.Add(squareComp);

// Trangle Component
private List<TriangleComponent> RandomizeTriangleWaveformComponents()
{
List<TriangleComponent> listTriangles = new List<TriangleComponent>();
int counter = (int)(4.0 * rand.NextDouble());
for (int i = 0; i < counter; i++)
{
TriangleComponent triangleComp = new TriangleComponent
{
Amplitude = rand.NextDouble() * 20.0,
DelayMs = rand.NextDouble() * 1000.0,
Frequency = rand.NextDouble() * 10.0,
Offset = 0,
Symmetry = 0.1 + rand.NextDouble() * 0.8, //set in range 0.1...0.9
Enabled = true
};
listTriangles.Add(triangleComp);
}
return listTriangles;

最后,在前一步没有产生波形的情况下,我们产生噪声信号。

if (generator.WaveformSines.Count + generator.WaveformSquares.Count + generator.WaveformTriangles.Count == 0)
{
SineComponent sineComp = new SineComponent
{
Amplitude = 20.0,
DelayMs = 0,
Frequency = 5,
Offset = 0,
Enabled = true
};
generator.WaveformSines.Add(sineComp);
RandomNoiseComponent noiseComp = new RandomNoiseComponent
{
Amplitude = 2.0,
Offset = 0,
Enabled = true
};
generator.WaveformRandomNoises.Add(noiseComp);
}
_generators[i] = generator;
最终数据采集系统应用

LightningChart.NET实战使用教程

数据采集系统的应用是当今一个非常有趣和重要的话题,数据采集系统应用程序远程传输数据。传输到高速DAQ图表的数据是由传感器产生的,这些传感器集中在我们希望分析的源的类型上。DAQ(数据采集)是一种工具,它允许我们操作通过这些传感器获得的数据。

使用LightningChart.NET,您将有可能生成自己的数据采集系统应用程序图表,无论是出于好奇还是专业工作,都不必担心从头开始构建。

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值