第01章:ScottPlot.NET 折線圖

一、概述

本文介紹使用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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容