一、概述
本文介紹使用ScottPlot.WPF繪制折線圖。
二、折線圖
第一步:新建項目
1.新建項目:SPLineDemo
2.添加Nuget包:ScottPlot.WPF
第二步:在MainWindow中編寫以下代碼
<Window x:Class="SPLineDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SPLineDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="折線圖"
Width="800"
Height="450"
mc:Ignorable="d">
<Grid>
<WpfPlot x:Name="plot" />
</Grid>
</Window>
第三步:在MainWindow.xaml.cs中分別進行各功能的代碼演示
1.基礎折線圖
功能演示
實現(xiàn)代碼
using System.Windows;
namespace SPLineDemo
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
InitBasicLineChart();
}
// 折線圖
private void InitBasicLineChart()
{
// 1.定義數(shù)據(jù)
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 20 };
// 2.添加折線
plot.Plot.AddScatterLines(xs, ys);
// 3.刷新界面
plot.Refresh();
}
}
}
首先用數(shù)組的形式定義了數(shù)據(jù)源,然后調(diào)用AddScatterLines將數(shù)據(jù)源傳入,繪制折線,最后調(diào)用Refresh方法刷新界面
Refresh方法必須調(diào)用,否則界面會有警示消息
注:為方便閱讀,下面僅展示核心代碼,其調(diào)用方式與此例無異
2.曲線圖
功能演示
實現(xiàn)代碼
// 曲線圖
private void InitSmoothLineChart()
{
// 1.定義數(shù)據(jù)
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 20 };
// 2.添加折線
var sp = plot.Plot.AddScatterLines(xs, ys);
sp.Smooth = true; // 指定曲線為平滑曲線
// 3.刷新界面
plot.Refresh();
}
- 將折線的Smooth屬性設置為true,使曲線便平滑
3.折線圖-點樣式
功能演示
實現(xiàn)代碼
// 折線圖-點樣式
private void InitLineWithMarker()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 20 };
// 添加折線
plot.Plot.AddScatter(xs, ys);
plot.Refresh();
}
- 之前用AddScatterLines添加無點折線,用AddScatter添加帶點的折線
4.折線圖-僅繪制點
功能演示
實現(xiàn)代碼
// 折線圖-僅繪制點
private void InitOnlyMarker()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 20 };
// 僅繪制點
plot.Plot.AddScatterPoints(xs, ys, Color.Navy, 10, MarkerShape.filledCircle);
plot.Refresh();
}
- 使用AddScatterPoints來繪制點,這其實是散點圖了。
5.多折線圖
功能演示
實現(xiàn)代碼
// 多折線圖
private void InitMultiLines()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys1 = { 1, 4, 9, 16, 20 };
double[] ys2 = { 2, 8, 18, 32, 40 };
// 添加折線1
plot.Plot.AddScatter(xs, ys1);
// 添加折線2
plot.Plot.AddScatter(xs, ys2);
plot.Refresh();
}
- 多次調(diào)用AddScatter方法可以添加更多折線
6.自定義點樣式
功能演示
實現(xiàn)代碼
// 自定義點樣式
private void InitCustomMarkers()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys1 = { 1, 4, 9, 16, 20 };
double[] ys2 = { 2, 8, 18, 32, 40 };
var sp1 = plot.Plot.AddScatter(xs, ys1, markerSize: 8); // markerSize定義marker大小
sp1.MarkerShape = MarkerShape.openCircle; // 空心圓
var sp2 = plot.Plot.AddScatter(xs, ys2, markerSize: 6);
sp2.MarkerShape = MarkerShape.filledSquare; // 實體方
plot.Refresh();
}
通過改變MarkerSize屬性改變marker的大小
通過改變MarkerShape屬性改變marker的樣式
MarkerShape是個枚舉類型,支持樣式如下:
7.添加折線圖圖例
功能演示
實現(xiàn)代碼
// 添加折線圖圖例
private void InitLineLegends()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys1 = { 1, 4, 9, 16, 20 };
double[] ys2 = { 2, 8, 18, 32, 40 };
var sp1 = plot.Plot.AddScatter(xs, ys1);
sp1.Label = "折線1"; // 折線1標簽
var sp2 = plot.Plot.AddScatter(xs, ys2);
sp2.Label = "折線2"; // 折線2標簽
// 添加圖例,并設置位置為右下
var legend = plot.Plot.Legend(location: Alignment.LowerRight);
legend.FontSize = 10; // 圖例字體大小
plot.Refresh();
}
首先為折線設置標簽名稱
然后添加圖例,并設置圖例的位置
最后設置了圖例字體大小
8.折線圖樣式
功能演示
實現(xiàn)代碼
// 折線圖樣式
private void InitLineStyles()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys1 = { 1, 4, 9, 16, 20 };
double[] ys2 = { 2, 8, 18, 32, 40 };
// color:顏色,lineWidth:線寬,lineStyle:線樣式
plot.Plot.AddScatter(xs, ys1, color: Color.Blue, lineWidth: 1);
plot.Plot.AddScatter(xs, ys2, color: Color.Orange, lineWidth: 2, lineStyle: LineStyle.Dash);
plot.Refresh();
}
通過設置Color,設置折線顏色
通過設置LineWidth,設置折線寬度
通過設置LineStyle,設置折線樣式。LineStyle為枚舉,支持樣式如下:
9.階梯折線圖
功能演示
實現(xiàn)代碼
// 階梯折線圖
private void InitStepLines()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 20 };
// 添加階梯折線圖
plot.Plot.AddScatterStep(xs, ys);
plot.Refresh();
}
- 通過AddScatterStep方法,添加階梯折線圖
10.可拖動折線圖
功能演示
實現(xiàn)代碼
// 可拖動折線圖
private void InitDragLine()
{
double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 20 };
// 添加可拖動折線
var scatter = new ScottPlot.Plottable.ScatterPlotListDraggable();
scatter.AddRange(xs, ys);
plot.Plot.Add(scatter);
plot.Refresh();
}
11.折線圖動態(tài)數(shù)據(jù)展示
功能演示
實現(xiàn)代碼
// 折線圖動態(tài)數(shù)據(jù)展示
private void InitDynamicDataDisplay()
{
var random = new Random();
var xs = new List<double>();
var ys = new List<double>();
plot.Render();
Task.Factory.StartNew(async () =>
{
var index = 5;
while (true)
{
xs.Add(index++);
ys.Add(random.Next(1, 100));
plot.Plot.Clear();
plot.Plot.AddScatter(xs.ToArray(), ys.ToArray());
Dispatcher.Invoke(() => plot.Render());
await Task.Delay(300);
}
});
}
核心邏輯便是重繪:清理掉之前的繪制,然后重新繪制折線,達到動態(tài)顯示的效果。
需要注意的便是Refresh方法必須在UI線程中調(diào)用。
12.折線圖泛型數(shù)據(jù)源
功能演示
實現(xiàn)代碼
// 折線圖泛型數(shù)據(jù)源
private void InitGenric()
{
float[] xs = { 1, 2, 3, 4, 5 };
float[] ys = { 1, 4, 9, 16, 20 };
// 使用泛型數(shù)據(jù)
var scatterList = plot.Plot.AddScatterList<float>();
scatterList.AddRange(xs, ys);
plot.Refresh();
}
三、環(huán)境
開發(fā)工具:Visual Studio
開發(fā)語言:C#
目標框架:.Net 6.0
Nuget包:DynamicDataDisplayReloaded