處理大量數據(十萬至百萬點)的即時波形顯示,標準 `Chart` 控件或 Office Web Components 常因效能不足而卡頓。National Instruments (NI) **Measurement Studio** 套件中的 **CWGraph** 控件專為測試量測領域設計,支援高效能繪圖、多種圖表類型、縮放平移、游標標記等專業功能。本文記錄引用安裝與基本使用流程。
using NationalInstruments.UI;
using NationalInstruments.UI.WindowsForms;
public partial class MainForm : Form
{
private CWGraph _graph;
private ScatterPlot _plot;
private Random _rand = new Random();
public MainForm()
{
InitializeComponent();
InitGraph();
}
private void InitGraph()
{
_graph = new CWGraph();
_graph.Dock = DockStyle.Fill;
this.Controls.Add(_graph);
// 建立繪圖區
var plotArea = new PlotArea();
_graph.PlotAreas.Add(plotArea);
// 建立 X/Y 軸
var xAxis = new Axis { Orientation = AxisOrientation.Horizontal };
var yAxis = new Axis { Orientation = AxisOrientation.Vertical };
plotArea.Axes.Add(xAxis);
plotArea.Axes.Add(yAxis);
// 建立散點圖
_plot = new ScatterPlot
{
XAxis = xAxis,
YAxis = yAxis,
PointStyle = PointStyle.Empty, // 不畫點,僅連線
LineStyle = LineStyle.Solid,
LineWidth = 1,
Color = Color.Blue
};
plotArea.Plots.Add(_plot);
// 互動功能
_graph.InteractionMode = InteractionMode.ZoomX | InteractionMode.PanX;
_graph.Cursors.Add(new Cursor { Plot = _plot, Mode = CursorMode.Expand });
}
// 追加數據點(模擬即時波形)
public void AppendData(double x, double y)
{
_plot.AppendPoint(x, y); // 高效能單點追加
// 可選:維持固定視窗寬度(捨棄舊點)
if (_plot.HistoryCapacity > 10000)
_plot.HistoryCapacity = 10000;
}
// 批次載入大量數據
public void LoadBulkData(double[] xData, double[] yData)
{
_plot.PlotY(yData); // 若 X 等距,僅需 Y 陣列
// 或
_plot.PlotXY(xData, yData);
}
}
| 特性 | 說明 |
|---|---|
| 大數據量 | 百萬點級別流暢渲染,優化記憶體管理 |
| 即時追加 | `AppendPoint`/`AppendPoints` 非重繪整圖,極低延遲 |
| 多圖層 | 支援多 `PlotArea`、多 `Axis`、多 `Plot` 疊加 |
| 互動 | 縮放、平移、游標、標記、範選內建 |
| 圖表類型 | 散點、線條、柱狀、面積、步階、極座標、3D 水波圖 |
| 匯出 | 圖片 (BMP/EMF/WMF)、列印、剪貼簿 |
xAxis.FormatMode = FormatMode.DateTime;
xAxis.FormatString = "HH:mm:ss.fff";
private void _graph_CursorMoved(object sender, CursorEventArgs e)
{
if (e.Cursor.Plot == _plot)
{
double x = e.Cursor.XPosition;
double y = e.Cursor.YPosition;
lblCursor.Text = $"X={x:F3}, Y={y:F3}";
}
}
// 背景執行緒產生數據,UI 執行緒追加
Task.Run(() =>
{
while (running)
{
double x = DateTime.Now.ToOADate();
double y = Math.Sin(x) + _rand.NextDouble() * 0.1;
// 必須在 UI 執行緒呼叫 AppendPoint
this.Invoke((Action)(() => _plot.AppendPoint(x, y)));
Thread.Sleep(10);
}
});
若預算有限,可考慮:
nuget install ScottPlot.WinFormsNI CWGraph 是**測控領域專業級圖表控件**的代表,大數據量、即時波形、專業互動功能開箱即用。對於工業監控、訊號分析、科學繪圖專案,授權成本通常可由開發效能節省回收。現代專案若無嚴格 NI 生態綁定,開源庫 ScottPlot 提供相近效能與更靈活授權,值得優先評估。