前言
为什么我们需要动态图表?
日常开发中,我们经常需要将数据以图形化方式展示。最简单的做法是把数据导出到 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