C# ScottPlot 繪圖控件 源碼閱讀心得體會


ScottPlot的介紹可以看這篇博客: https://www.cnblogs.com/myshowtime/p/15606399.html
我對代碼的理解是這樣的:
圖像的呈現是靠bitmap,每進行拖動圖像,放大縮小,等等操作,都會新創建一張圖片,並把這張圖片作為最新的展示在界面上。
為了保證圖片內存的回收效率,還專門創建了一個隊列,這個隊列會把舊圖片在新圖片創建時入隊,當對當前圖形有改變時並且當隊列里的圖片個數大於3時,才會出隊釋放圖片內存。
在【Settings】這個類里,主要是存儲圖像的配置和數據的,比如x y軸, 長寬 ,軸的長度限制,以及一個非常核心的觀察模式的集合對象:
ObservableCollection<IPlottable> Plottables
圖片所包括的所有顯示需要渲染到圖片上的對象都實現了IPlottable接口,比如坐標 刻度 插圖 x軸y軸線,里面的代碼如下:
public interface IPlottable
    {
        bool IsVisible { get; set; }
        void Render(PlotDimensions dims, System.Drawing.Bitmap bmp, bool lowQuality = false);

        int XAxisIndex { get; set; }
        int YAxisIndex { get; set; }

        /// <summary>
        /// Returns items to show in the legend. Most plottables return a single item. in this array will appear in the legend.
        /// Plottables which never appear in the legend can return null.
        /// </summary>
        LegendItem[] GetLegendItems();

        /// <summary>
        /// Return min and max of the horizontal and vertical data contained in this plottable.
        /// Double.NaN is used for axes not containing data.
        /// </summary>
        /// <returns></returns>
        AxisLimits GetAxisLimits();

        /// <summary>
        /// Throw InvalidOperationException if ciritical variables are null or have incorrect sizes. 
        /// Deep validation is slower but also checks every value for NaN and Infinity.
        /// </summary>
        void ValidateData(bool deep = false);
    }
其中核心的就是Render方法了,這個在底層調用 bmp參數的gdi,這個bmp參數就是最終顯示給用戶的圖像。所有在 Plottables 里的對象都會渲染到這張圖片上面去。【PlotDimensions】 這個對象表示該元素的長寬 位置等信息。
暴露給用戶使用的類是【Plot】類,里面有不同樣式的 x y 數據類型,有單一的接受y軸數據,而x軸就平均分取。比如:
public SignalPlot AddSignal(double[] ys, double sampleRate = 1, Color? color = null, string label = null)
        {
            SignalPlot signal = new SignalPlot()
            {
                Ys = ys,
                SampleRate = sampleRate,
                Color = color ?? settings.GetNextColor(),
                Label = label,

                // TODO: FIX THIS!!!
                MinRenderIndex = 0,
                MaxRenderIndex = ys.Length - 1,
            };
            Add(signal);
            return signal;
        }

 最后在返回之前 ,這個Add(signal)會把這個對象加入到Plottables 集合中去 我們還可以添加很多元素,比如:

// plot the data
formsPlot1.Plot.AddScatter(xs, sin);
formsPlot1.Plot.AddScatter(xs, cos);

// customize the axis labels
formsPlot1.Plot.Title("ScottPlot Quickstart");
formsPlot1.Plot.XLabel("Horizontal Axis");
formsPlot1.Plot.YLabel("Vertical Axis");

 最后渲染的時候就用這個:formsPlot1.Refresh(); 它會調用Plot的 Render方法,這個方法會去遍歷Plottables 這個集合,然后挨個用gdi畫到bitmap上面去。 在formsPlot1控件里,有一個非常重要的類:【ControlBackEnd】,這里面有關於對圖像 放大 縮小 移動 ,點擊 的基本操作方法。 我們自己還可以注冊這些事件寫額外的代碼 也不會影響。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM