C# WPF上位机开发(动态数据采集与监控项目)

2023-12-26 19:29:37

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

? ? ? ? 数据采集和监控是上位机开发一项很基础的功能。采集数据的多少,采集的频率,这个取决于具体的项目类型。采集数据之后的处理,一般由于项目的不同,也是不一样的。总之,对于制造业的朋友,特别是生产端的程序员来说,数据采集是他们经常遇到的一个工作任务。

? ? ? ? 目前关于数据的显示和调整,有很多的方式和方法。不过,我还是建议大家可以自己写一个canvas,累积一下相关的知识点,这样在应用的时候才会得心应手。为了实现这样一个demo程序,我们可以用随机数来进行代替。同样为了说明采集频率,我们也可以用定时器来模拟一下。

1、准备界面

? ? ? ? 界面的部分其实很简单,主要就是一个canvas。但实际应用的时候,可能还会有一些子对话框、子控件等等。当然,我们学会了canvas之后,就可以把它放在自己的项目当中去。

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="SensorDataChart" Height="400" Width="600">
    <Grid x:Name="grid">
        <Canvas Name="chartCanvas" Background="LightGray" />
    </Grid>
</Window>

2、实现代码

? ? ? ? 要实现一个动态显示的效果,有几点需要注意一下。第一,需要一个定时器,模拟一下采样频率;第二,需要一个随机数,模拟一下传感器的采集量;第三,就是添加相关的逻辑判断,特别是一次显示多少数据。

? ? ? ? 目前,代码是一次展示100个点的采集。超过100个点之后,第一个点将被扔掉,最后一个点补上。后续的逻辑也是如此。此外,每次显示的时候,都选择清空画布和重新绘制折线图。绘制的方法就比较简单了,相连两点直接连接起来就可以了。

? ? ? ? 因为有定时器的缘故,所以相关数据会不停地生成出来,并显示。这和实际传感器的效果几乎是一样的。有兴趣的同学,可以把这个chart移植到真实的传感器上面,相信会有更加深刻的认识。

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApp
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<Point> dataPoints = new List<Point>();
        private DispatcherTimer timer;
        private int num = 0;

        public MainWindow()
        {
            InitializeComponent();

            // 创建定时器
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(50); // 设置定时器间隔(40ms)
            timer.Tick += Timer_Tick;

            // 启动定时器
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // 生成随机y值,x值为固定值
            Random random = new Random();
            double randomY = random.Next(140, 200);

            if (num < 500)
            {
                Point randomPoint = new Point(80 + num, randomY);
                num += 5;
                dataPoints.Add(randomPoint);
            }
            else
            {
                List<Point> new_dataPoints = new List<Point>();
                for(int i = 1; i < 100; i+=1)
                {
                    Point Point = new Point(dataPoints[i].X-5, dataPoints[i].Y);
                    new_dataPoints.Add(Point);
                }

                Point randomPoint = new Point(80 + num - 5, randomY);
                new_dataPoints.Add(randomPoint);
                dataPoints = new_dataPoints;

            }
            // 清空画布
            chartCanvas.Children.Clear();

            // 重新绘制折线图
            DrawLineChart(dataPoints);
        }

        private void DrawLineChart(List<Point> points)
        {
            if (points == null || points.Count < 2)
                return;

            // 创建画笔
            SolidColorBrush lineColor = Brushes.Blue;
            double lineWidth = 2;
            Pen linePen = new Pen(lineColor, lineWidth);

            // 绘制折线
            for (int i = 0; i < points.Count - 1; i++)
            {
                Line line = new Line
                {
                    X1 = points[i].X,
                    Y1 = points[i].Y,
                    X2 = points[i + 1].X,
                    Y2 = points[i + 1].Y,
                    Stroke = lineColor,
                    StrokeThickness = lineWidth
                };

                chartCanvas.Children.Add(line);
            }
        }
    }
}

3、编译和测试

? ? ? ? 代码编写完整后,没有问题的话,就可以开始测试。一开始数据还没有满的时候,折线是慢慢添加上去的,

? ? ? ? 等到100个数据全部采集完之后,数据开始流动了,如下所示,

? ? ? ? 如果能够同时看到以上这两个现象,基本就达到我们设计的效果了。

文章来源:https://blog.csdn.net/feixiaoxing/article/details/135227452
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。