1、安装livecharts2,勾选包括预发布版本,搜索下载 LiveChartsCore.SkiaSharpView.WPF

注意:使用lvc2 ,好像必须使用mvvm开发模式,建议安装一个communitytoolkit
也可以参考官方模版:samples.general.realTime - 实时图表2

2、xaml引用如下:

<UserControl x:Class="AEEG.Views.TestView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:lvc2="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
             xmlns:vm="clr-namespace:AEEG.ViewModels"
             xmlns:local="clr-namespace:AEEG.Views"
             xmlns:dv="clr-namespace:AEEG.AeegCanvas"
             mc:Ignorable="d" 
             d:DesignHeight="600" d:DesignWidth="800">

    <UserControl.DataContext>
        <vm:Test2ViewModel/>
    </UserControl.DataContext>

    <lvc2:CartesianChart
        SyncContext="{Binding Sync}"
        Series="{Binding Series}"
        YAxes="{Binding YAxes}"
        XAxes="{Binding XAxes}">
    </lvc2:CartesianChart>

</UserControl>

3、viewmodel代码如下

using System.Collections.ObjectModel;
using LiveChartsCore;
using LiveChartsCore.Defaults;
using LiveChartsCore.SkiaSharpView;
using LiveChartsCore.SkiaSharpView.Painting;
using SkiaSharp;

namespace AEEG.ViewModels
{
    public partial class Test2ViewModel
    {

        // 随机数生成器,用于生成测试数据
        private readonly Random _random = new();
        // 存储时间序列数据点的集合
        private const int MaxXValue = 71; // 修改最大点数为70,实现0-70点循环
        private ObservableCollection<ObservableCollection<ObservablePoint>> _curveData = [];
        public ObservableCollection<ISeries> Series { get; set; }
        private int i = 0;
        private bool Execute_action = true; 
        // X轴配置集合
        public Axis[] XAxes { get; set; }
        = [new Axis
        {
            IsVisible = false,
            MinLimit = 0,
            MaxLimit = 70,
            MinStep = 1,
        }];
        public Axis[] YAxes { get; set; } = [new Axis
        {
            IsVisible = false,
            MinLimit = -100,
            MaxLimit = 100,
        }];
        public object Sync { get; } = new object();
        public bool IsReading { get; set; } = true;
        public bool IsAdd { get; set; } = true;
        public bool IsFirstSegment{ get; set; } = true;


        // 构造函数,初始化图表配置并启动数据读取
        public Test2ViewModel()
        {
            _curveData.Add(new ObservableCollection<ObservablePoint>());
            _curveData.Add(new ObservableCollection<ObservablePoint>());

            Series = [
                new LineSeries<ObservablePoint>
                {
                    Values = _curveData[0],
                    Fill = null,
                    GeometryFill = null,
                    GeometryStroke = null,
                    Stroke = new SolidColorPaint(SKColors.DodgerBlue) { StrokeThickness = 1 },
                },
                 new LineSeries<ObservablePoint>
                {
                    Values = _curveData[1],
                    Fill = null,
                    GeometryFill = null,
                    GeometryStroke = null,
                    Stroke = new SolidColorPaint(SKColors.DodgerBlue) { StrokeThickness = 1 },
                }

            ];
            // 启动数据读取任务(不等待完成)
            _ = ReadData();
        }

        /// 异步读取数据并更新图表的方法
        private async Task ReadData()
        {
            // 当IsReading为true时持续运行

            while (IsReading)
            {
                await Task.Delay(100);
                // 使用Sync对象进行线程同步,确保线程安全
                lock (Sync)
                {
                    if (MaxXValue > _curveData[0].Count && IsAdd)
                    {
                        _curveData[0].Add(new ObservablePoint(i++, _random.Next(-10, 10)));
                    }
                    else
                    {
                        if (_curveData[0].Count >= MaxXValue)
                        {
                            i = 0;
                            IsAdd = false;
                            //线条颜色相关
                             if (IsFirstSegment)
                             {
                                ((LineSeries<ObservablePoint>)Series[0]).Stroke = new                     SolidColorPaint(SKColors.SlateGray);
                                 ((LineSeries<ObservablePoint>)Series[1]).Stroke = new SolidColorPaint(SKColors.DodgerBlue);
                                 IsFirstSegment = false;
                             }
                        }
                        _curveData[0].RemoveAt(0);
                        _curveData[1].Add(new ObservablePoint(i++, _random.Next(-10, 10)));
                        if (_curveData[1].Count >= MaxXValue && _curveData[0].Count == 0)
                        {
                            i = 0;
                            _curveData.Move(0, 1);
                            //始终保持新增曲线蓝色,递减曲线灰色
                            if (Execute_action)
                            {
                                ((LineSeries<ObservablePoint>)Series[0]).Stroke = new SolidColorPaint(SKColors.DodgerBlue);
                                ((LineSeries<ObservablePoint>)Series[1]).Stroke = new SolidColorPaint(SKColors.SlateGray);
                                Execute_action = false;
                            }
                            else
                            {
                                ((LineSeries<ObservablePoint>)Series[0]).Stroke = new SolidColorPaint(SKColors.SlateGray);
                                ((LineSeries<ObservablePoint>)Series[1]).Stroke = new SolidColorPaint(SKColors.DodgerBlue);
                                Execute_action = true;
                            }
                        }

                    }

                }

            }



        }
    }

}

4、运行效果如下,自己动态改变数据调节幅度大小即可

Logo

更多推荐