測試數據視覺化常靠 Excel 手工繪圖,數據頻繁變更時極其繁瑣。本文展示如何用 WPF + DynamicDataDisplay (D3) 庫,從文本文件讀取數據自動生成專業級圖表,並延伸至散點圖繪製 13,509 個美國城市地理分佈。
Microsoft.Research.DynamicDataDisplay.dllBugInfo.txt (日期:打開數:關閉數)
<Window xmlns:d3="https://research.microsoft.com/DynamicDataDisplay/1.0"
Height="500" Width="800" Background="Wheat">
<d3:ChartPlotter Name="plotter" Margin="10,10,20,10">
<d3:ChartPlotter.HorizontalAxis>
<d3:HorizontalDateTimeAxis Name="dateAxis"/>
</d3:ChartPlotter.HorizontalAxis>
<d3:ChartPlotter.VerticalAxis>
<d3:VerticalIntegerAxis Name="countAxis"/>
</d3:ChartPlotter.VerticalAxis>
<d3:Header FontFamily="Arial" Content="Bug Information"/>
<d3:VerticalAxisTitle FontFamily="Arial" Content="Count"/>
<d3:HorizontalAxisTitle FontFamily="Arial" Content="Date"/>
</d3:ChartPlotter>
</Window>
public partial class Window1 : Window {
public Window1() {
InitializeComponent();
Loaded += Window1_Loaded;
}
void Window1_Loaded(object sender, RoutedEventArgs e) {
var list = LoadBugInfo(@"..\..\BugInfo.txt");
// 1. 拆分為三個陣列
var dates = list.Select(i => i.date).ToArray();
var open = list.Select(i => i.numberOpen).ToArray();
var closed = list.Select(i => i.numberClosed).ToArray();
// 2. 包裝為 EnumerableDataSource 並映射座標
var xSource = new EnumerableDataSource(dates);
xSource.SetXMapping(x => dateAxis.ConvertToDouble(x));
var yOpen = new EnumerableDataSource(open);
yOpen.SetYMapping(y => y);
var yClosed = new EnumerableDataSource(closed);
yClosed.SetYMapping(y => y);
// 3. 復合 X/Y 數據源
var compositeOpen = new CompositeDataSource(xSource, yOpen);
var compositeClosed = new CompositeDataSource(xSource, yClosed);
// 4. 繪製折線圖 + 標記 + 圖例
plotter.AddLineGraph(compositeOpen,
new Pen(Brushes.Blue, 2),
new CirclePointMarker { Size = 10, Fill = Brushes.Red },
new PenDescription("Number bugs open"));
plotter.AddLineGraph(compositeClosed,
new Pen(Brushes.Green, 2),
new TrianglePointMarker { Size = 10, Pen = new Pen(Brushes.Black, 2), Fill = Brushes.GreenYellow },
new PenDescription("Number bugs closed"));
plotter.Viewport.FitToView();
}
static List LoadBugInfo(string path) {
var result = new List();
using (var fs = new FileStream(path, FileMode.Open))
using (var sr = new StreamReader(fs)) {
string line;
while ((line = sr.ReadLine()) != null) {
var p = line.Split(':');
result.Add(new BugInfo(DateTime.Parse(p[0]), int.Parse(p[1]), int.Parse(p[2])));
}
}
return result;
}
}
public class BugInfo {
public DateTime date;
public int numberOpen, numberClosed;
public BugInfo(DateTime d, int o, int c) { date = d; numberOpen = o; numberClosed = c; }
}
EnumerableDataSource<T>:統一數據介面,泛型支援任意型別SetXMapping/SetYMapping:Lambda 將業務型別映射為 D3 內部 double 座標CompositeDataSource:將獨立 X/Y 源合成為 2D 點集合AddLineGraph:一行代碼完成線條、標記、圖例完整配置FitToView():自動縮放適應視窗usa13509.tsp (索引、緯度、經度)-1 修正東西向映射Pen(Brushes.White, 0) 線寬 0 隱藏連線,僅保留 CirclePointMarker 形成散點圖| 場景 | 優勢 |
|---|---|
| 獨立報表生成 | 數據頻繁更新,自動化替代手工 Excel |
| WPF/Silverlight 應用內嵌 | 純 .NET 技術棧,無跨技術整合成本 |
| 大數據點可視化 | D3 針對大量點優化渲染,效能優於手繪 |
WPF + DynamicDataDisplay 以極少代碼實現專業級動態圖表:聲明式 XAML 定義座標系/標題,程式碼專注數據流轉換與繪圖指令。掌握 EnumerableDataSource → CompositeDataSource → AddLineGraph 核心管線,即可將任意結構化數據轉化為洞察力可視化輸出。