WPF 动态模拟CPU 使用率曲线图

前言

为什么我们需要动态图表?

日常开发中,我们经常需要将数据以图形化方式展示。最简单的做法是把数据导出到 Excel,然后手动绘制折线图或柱状图。但如果数据是实时变化的,比如监控 CPU、内存、网络流量等系统性能指标,手动绘图显然不现实。

本文将带大家使用 WPF + DynamicDataDisplay 实现一个实时动态更新的 CPU 使用率曲线图,支持自动刷新、缩放、拖拽浏览,并可一键复制图表到其他文档。

技术选型:DynamicDataDisplay 简介

DynamicDataDisplay (D3) 是微软研究院推出的一个强大的 WPF 数据可视化库,虽然项目已不再维护,但在轻量级实时图表场景下依然表现出色。

它支持:

  • 实时动态数据流绘图

  • 坐标轴自定义(整型、浮点、时间等)

  • 鼠标交互:拖拽、缩放、选择

  • 多种图形类型:折线、散点、区域图等

  • 图表导出与复制

注意:DynamicDataDisplay 仅支持 .NET Framework,不适用于 .NET Core / .NET 5+ 的跨平台项目。如需现代替代方案,可考虑 OxyPlot 或 LiveCharts。

项目搭建

1、创建 WPF 项目

使用 Visual Studio 创建一个新的 WPF 应用程序(.NET Framework)。

2、引入 DynamicDataDisplay

下载 DynamicDataDisplay.dll 并添加引用到项目中:

  • 可从 微软官方存档 获取
  • 或通过 NuGet 安装(非官方包):Install-Package DynamicDataDisplay

3、添加命名空间

MainWindow.xaml 中引入 D3 命名空间:

xml 复制代码
xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"

XAML 界面设计

xml 复制代码
<Window x:Class="WpfPerformance.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"
        Title="CPU Performance Monitor" 
        Loaded="Window_Loaded" 
        Height="400" Width="600">
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- 顶部状态栏 -->
        <StackPanel Orientation="Horizontal" Margin="20,10,0,10">
            <TextBlock Text="CPU Usage: " 
                       FontSize="16" FontWeight="SemiBold" VerticalAlignment="Center"/>
            <TextBlock x:Name="cpuUsageText" 
                       FontSize="16" Foreground="Blue" VerticalAlignment="Center"/>
        </StackPanel>

        <!-- 图表区域 -->
        <d3:ChartPlotter x:Name="plotter" Grid.Row="1" Margin="10">
            <d3:ChartPlotter.HorizontalAxis>
                <d3:HorizontalIntegerAxis />
            </d3:ChartPlotter.HorizontalAxis>
            <d3:ChartPlotter.VerticalAxis>
                <d3:VerticalIntegerAxis />
            </d3:ChartPlotter.VerticalAxis>

            <d3:Header Content="CPU Performance History" FontSize="18"/>
            <d3:VerticalAxisTitle Content="Usage (%)" />
        </d3:ChartPlotter>
    </Grid>
</Window>

控件说明

控件 作用
<d3:ChartPlotter> 图表容器,提供绘图区域
<d3:HorizontalIntegerAxis> X 轴(时间/序号)
<d3:VerticalIntegerAxis> Y 轴(百分比)
<d3:Header> 图表标题
<d3:VerticalAxisTitle> Y 轴标签

C# 后台逻辑实现

1、成员变量定义

csharp 复制代码
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.DataSources;

namespace WpfPerformance
{
    public partial class MainWindow : Window
    {
        private ObservableDataSource<Point> dataSource = new ObservableDataSource<Point>();
        private PerformanceCounter cpuCounter = new PerformanceCounter();
        private DispatcherTimer timer = new DispatcherTimer();
        private int xIndex = 0; // X轴时间点

        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

2、实时数据采集与绘图

csharp 复制代码
private void AnimatedPlot(object sender, EventArgs e)
{
    // 配置性能计数器
    cpuCounter.CategoryName = "Processor";
    cpuCounter.CounterName = "% Processor Time";
    cpuCounter.InstanceName = "_Total"; // 所有核心平均值

    // 获取当前CPU使用率
    float cpuUsage = cpuCounter.NextValue();
    Point newPoint = new Point(xIndex, cpuUsage);

    // 异步追加数据点(线程安全)
    dataSource.AppendAsync(Dispatcher, newPoint);

    // 更新UI文本
    cpuUsageText.Text = $"{cpuUsage:F0}%";

    xIndex++;
}

NextValue() 第一次调用会返回 0,建议在定时器启动前先调用一次预热。

3、窗口加载事件:初始化图表与定时器

csharp 复制代码
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // 将数据源绑定为折线图
    plotter.AddLineGraph(
        dataSource,
        Colors.Green,
        2.0,           // 线条粗细
        "CPU Usage"    // 图例名称
    );

    // 设置刷新频率:每秒一次
    timer.Interval = TimeSpan.FromSeconds(1);
    timer.Tick += AnimatedPlot;
    timer.Start();

    // 自动缩放视图以适应当前数据
    plotter.Viewport.FitToView();
}

运行效果与交互功能

实时动态曲线

  • 每秒获取一次 CPU 使用率

  • 数据点自动追加并绘制为绿色折线

  • 图表自动滚动更新

鼠标交互操作

操作 功能
左键拖拽 平移查看历史数据
中键滚轮 缩放图表区域
右键菜单 提供、Copy Plot"功能,可将图表复制为图像

复制后可直接粘贴到 Word、PPT、OneNote 等办公软件中,非常方便!

常见问题

为什么第一次 NextValue() 返回 0?

PerformanceCounter.NextValue()差值计算,需要至少两次调用才能得出有效结果。建议在启动定时器前先调用一次、预热":

csharp 复制代码
cpuCounter.NextValue(); // 预热
timer.Start();

如何限制历史数据长度?

避免内存无限增长,可定期清理旧数据:

csharp 复制代码
if (dataSource.Collection.Count > 100)
{
    dataSource.Collection.RemoveAt(0);
}

替代方案推荐(适用于 .NET 5+)

由于 DynamicDataDisplay 不支持新版本 .NET,推荐以下现代库:

库名 特点
OxyPlot 跨平台、轻量、支持 MVVM
LiveCharts 动画丰富、API 简洁、社区活跃
ScottPlot 高性能、适合大数据量实时绘图

完整源码下载

总结

本文通过一个完整的实例,展示了如何在 WPF 中使用 DynamicDataDisplay 实现:

  • 实时 CPU 使用率监控

  • 动态曲线图绘制

  • 用户交互与图表导出

  • 多线程安全数据更新

尽管 DynamicDataDisplay 已停止维护,但它仍然是学习 WPF 图表编程的优秀起点。掌握其核心思想后,可以轻松迁移到更现代的图表库。

开发启示

  • 实时数据可视化 ≠ 复杂
  • 选择合适的工具能极大提升开发效率
  • 图表不仅要好看,更要、好用

关键词: WPF、DynamicDataDisplay、CPU 使用率、实时图表、ObservableDataSource、PerformanceCounter

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

来源:cnblogs.com/gnielee/archive/2010/08/02/wpf-cpu-usage.html

相关推荐
我是谁的程序员6 小时前
让调试成为团队优势,如何把Charles融入前端与测试的工作流
后端
Java水解6 小时前
Spring AI Alibaba 入门教程:快速集成大模型到Spring Boot应用
后端·spring
Java水解6 小时前
Flowable工作流引擎:Spring Boot集成
后端
王中阳Go背后的男人6 小时前
订单支付后库存不扣减,如何用RabbitMQ来优化?
后端
聪明努力的积极向上6 小时前
【.NET】依赖注入浅显解释
c#·.net
IT_陈寒6 小时前
Vite 5新特性解析:10个提速技巧让你的开发效率翻倍 🚀
前端·人工智能·后端
yuuki2332336 小时前
【数据结构】单链表的实现
c语言·数据结构·后端
刘一说6 小时前
深入理解 Spring Boot Web 开发中的全局异常统一处理机制
前端·spring boot·后端
塔能物联运维6 小时前
物联网边缘节点数据缓存优化与一致性保障技术
java·后端·物联网·spring·缓存