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】,这里面有关于对图像 放大 缩小 移动 ,点击 的基本操作方法。 我们自己还可以注册这些事件写额外的代码 也不会影响。