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

相关推荐
绿荫阿广10 分钟前
使用.NET开发并上线一个小智AI对话机器人的MCP服务转接平台
.net·asp.net core·mcp
q***697732 分钟前
Spring Boot与MyBatis
spring boot·后端·mybatis
Eiceblue1 小时前
通过 C# 将 HTML 转换为 RTF 富文本格式
开发语言·c#·html
IUGEI2 小时前
synchronized的工作机制是怎样的?深入解析synchronized底层原理
java·开发语言·后端·c#
间彧2 小时前
GraalVM Native Image:跨平台能力与编译模式深度解析
后端
间彧2 小时前
GraalVM Native Image 与传统 JVM 内存管理:云原生时代的技术选型指南
后端
r***12382 小时前
SpringBoot最佳实践之 - 使用AOP记录操作日志
java·spring boot·后端
b***74882 小时前
前端GraphQL案例
前端·后端·graphql
LSL666_3 小时前
SpringBoot自动配置类
java·spring boot·后端·自动配置类
q***78373 小时前
Spring Boot 3.X:Unable to connect to Redis错误记录
spring boot·redis·后端