圖表控件一直是很難找的,特別是免費又強大的。NPlot是一款非常難得的.Net平台下的圖表控件,能做各種曲線圖,柱狀圖,餅圖,散點圖,股票圖等,而且它免費又開源,使用起來也非常符合程序員的習慣。唯一的缺點就是文檔特別難找,難讀。通過對其文檔的閱讀和對示例程序源代碼的分析,現在將NPlot的基本概念整理如下:
NPlot的命名空間包括NPlot,NPlot.Bitmap,NPlot.Web,NPlot.Web.Design,NPlot.Windows等,其中最核心的,管理各種圖表的類都屬於NPlot命名空間,NPlot.Bitmap針對位圖的管理,NPlot.Web,NPlot.Web.Design和NPlot.Windows則可視為NPlot圖表在Web Form和Windows Form上的容器(PlotSurface2D)。這些容器可以拖到Form上,也可以位於其他容器之中。
要在應用程序中應用NPlot控件,首先要把所下載的NPlot.dll添加到.Net工程中。並將其添加到工具箱托盤中。添加方式為:在工具箱上單擊右鍵,選擇“選擇項”,會出現“選擇工具箱項”對話框,在“.Net Frameworks組件”屬性頁,選擇瀏覽,找到NPlot.dll添加到工具箱項。這時工具箱中會出現NPlot控件。在設計應用程序界面時,可以將其拖入應用程序界面,系統會在代碼中自動創建一個PlotSurface2D對象。
PlotSurface2D對象是NPlot圖表的容器,所有的圖表圖形,坐標,標題(都繼承IDrawable接口)等各種信息都可以被加入PlotSurface2D。PlotSurface2D擁有一個非常重要的方法:Add。各種圖表圖形,坐標,標題都可以通過Add加入PlotSurface2D對象。
我們可以通過下面簡單的代碼示例來了解NPlot的基本用法:
public void plotline() { // --- Plotting --- plot.Clear(); // --- Grid Code --- Grid mygrid = new Grid(); mygrid.HorizontalGridType = Grid.GridType.None; mygrid.VerticalGridType = Grid.GridType.Fine; plot.Add(mygrid); plot.Title = "Test"; StepPlot line = new StepPlot(); line.Pen = new Pen (Color.Red, 1); line.OrdinateData = new int [] {0, 1, 0, 1, 1, 0}; line.HideVerticalSegments = false; plot.Add(line); plot.Refresh(); return; }
Grid對象和StepPlot對象都是NPlot命名空間中的對象,都繼承於NPlot.IDrawable,都可以作為PlotSurface2D.Add函數調用,在NPlot中畫圖,就是把網格,坐標,圖形等各種對象加入PlotSurface2D對象中,一切就那么簡單!
下面給出更多代碼例子
////////對所繪的圖進行打印與保存////////// private void print() { myPlot.Print(true); } private void save() { saveFileDialog1.Filter = "位圖(*.bmp)|*.bmp|JPEG(*.jpg)|*.jpg;*.jpeg;*,jpe|Gif(*.gif)|*.gif|Tiff(*.tiff)|*.tiff|Png(*.png)|*.png|Exif(*.exif)|*.exif|所有文件(*.*)|*.*"; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { try { int h = myPlot.Size.Height; int w = myPlot.Size.Width; Bitmap bm = new Bitmap(w, h); Bitmap bm1 = new Bitmap(w, h); Rectangle rt = new Rectangle(1, 1, w, h); saveFileDialog1.RestoreDirectory = true; saveFileDialog1.CreatePrompt = true; myPlot.DrawToBitmap(bm, rt); if (saveFileDialog1.FilterIndex == 1) { bm.Save(saveFileDialog1.FileName); } if (saveFileDialog1.FilterIndex == 2) { bm.Save(saveFileDialog1.FileName, ImageFormat.Jpeg); } if (saveFileDialog1.FilterIndex == 3) { bm.Save(saveFileDialog1.FileName, ImageFormat.Gif); } if (saveFileDialog1.FilterIndex == 4) { bm.Save(saveFileDialog1.FileName, ImageFormat.Tiff); } if (saveFileDialog1.FilterIndex == 5) { bm.Save(saveFileDialog1.FileName, ImageFormat.Png); } if (saveFileDialog1.FilterIndex == 6) { bm.Save(saveFileDialog1.FileName, ImageFormat.Exif); } } catch (Exception MyEx) { MessageBox.Show(MyEx.ToString(), "錯誤提示", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } ///放大縮小 private void changeSize() { this.myPlot.XAxis1.IncreaseRange(0.1); this.myPlot.YAxis1.IncreaseRange(0.1); //縮小 this.myPlot.XAxis1.IncreaseRange(-0.1); this.myPlot.YAxis1.IncreaseRange(-0.1); //放大 this.myPlot.Refresh(); } /////////各種繪圖////////// private void plot() { this.myPlot.Clear( ////////標簽////////// string[] strLabel = new string[leng]; for (int i = 0; i < leng; i++) strLabel[i] = Convert.ToString(p[i]); LabelPointPlot labp = new LabelPointPlot(); labp.AbscissaData = X; labp.OrdinateData = p; labp.TextData = strLabel; labp.LabelTextPosition = LabelPointPlot.LabelPositions.Above; labp.Marker = new Marker(Marker.MarkerType.Square, 8); labp.Marker.Color = Color.Blue; myPlot.Add(labp); myPlot.Refresh(); ////////網格////////// Grid mygrid = new Grid(); mygrid.HorizontalGridType = Grid.GridType.Fine; mygrid.VerticalGridType = Grid.GridType.Fine; this.myPlot.Add(mygrid); ////////曲線,雙坐標軸////////// ///////水平線////////// HorizontalLine line = new HorizontalLine(1.2); line.LengthScale = 0.89f; this.myPlot.Add(line, -10); ///////垂直線/////////// VerticalLine line2 = new VerticalLine(1.2); line2.LengthScale = 0.89f; this.myPlot.Add(line2); ///////普通的線/////////// LinePlot lp3 = new LinePlot(); lp3.OrdinateData = yPW; lp3.AbscissaData = x; lp3.Pen = new Pen(Color.Orange); lp3.Pen.Width = 2; lp3.Label = " 價格"; this.myPlot.Add(lp3); LinearAxis linx = (LinearAxis)myPlot.XAxis1; this.myPlot.XAxis1 = linx; LinearAxis liny = (LinearAxis)myPlot.YAxis1; liny.Label = "價格"; liny.AxisColor = Color.Orange; liny.LabelColor = Color.Orange; liny.TickTextColor = Color.Orange; this.myPlot.YAxis1 = liny; LinePlot lp4 = new LinePlot(); lp4.OrdinateData = yUw; lp4.AbscissaData = x; lp4.Pen = new Pen(Color.Green); lp4.Pen.Width = 2; lp4.Label = "銷售量"; this.myPlot.Add(lp4, PlotSurface2D.XAxisPosition.Top, PlotSurface2D.YAxisPosition.Right); LinearAxis liny2 = (LinearAxis)myPlot.YAxis2; liny2.WorldMax = 1.2; liny2.WorldMin = 0; liny2.Label = "銷售量"; liny2.AxisColor = Color.Green; liny2.LabelColor = Color.Green; liny2.TickTextColor = Color.Green; this.myPlot.YAxis2 = liny2; ///////圖例////////// this.myPlot.Legend = new Legend(); this.myPlot.Legend.AttachTo(PlotSurface2D.XAxisPosition.Top, PlotSurface2D.YAxisPosition.Right); this.myPlot.Legend.NumberItemsHorizontally = 2; this.myPlot.Legend.HorizontalEdgePlacement = Legend.Placement.Inside; this.myPlot.Legend.VerticalEdgePlacement = Legend.Placement.Inside; this.myPlot.Legend.YOffset = 5; this.myPlot.Legend.XOffset = -5; ///////窗體移動////////// this.myPlot.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.HorizontalDrag()); this.myPlot.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.VerticalDrag()); this.myPlot.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.AxisDrag(true)); //////累加的柱狀圖//////// HistogramPlot hp3 = new HistogramPlot(); hp3.AbscissaData = x; hp3.OrdinateData = yCC1; hp3.BaseWidth = 0.6f; hp3.RectangleBrush = RectangleBrushes.Vertical.FaintBlueFade; hp3.Filled = true; hp3.Label = "一月"; HistogramPlot hp4 = new HistogramPlot(); hp4.AbscissaData = x; hp4.OrdinateData = yCC2; hp4.Label = "二月"; hp4.RectangleBrush = RectangleBrushes.Horizontal.FaintGreenFade; hp4.Filled = true; hp4.StackedTo(hp3); this.myPlot.Add(hp3); this.myPlot.Add(hp4); //////階狀圖//////// StepPlot sp1 = new StepPlot(); sp1.OrdinateData = yCH1; sp1.AbscissaData = x; sp1.Label = "高度"; sp1.Pen.Width = 2; sp1.Pen.Color = Color.Blue; this.myPlot.Add(sp1); /////點狀圖//////// Marker m = new Marker(Marker.MarkerType.Cross1, 6, new Pen(Color.Blue, 2.0F)); PointPlot pp = new PointPlot(m); pp.OrdinateData = a; pp.AbscissaData = new StartStep(-500.0, 10.0); pp.Label = "Random"; this.myPlot.Add(pp); /////Image圖//////// double[,] map = new double[19, 19]; for (int i = 0; i < 19; ++i) { for (int j = 0; j < 19; ++j) { map[i, j] = Convert.ToDouble(tokens[i * 19 + j], new System.Globalization.CultureInfo("en-US")); } } ImagePlot ip = new ImagePlot(map, -9.0f, 1.0f, -9.0f, 1.0f); ip.Gradient = new LinearGradient(Color.Gold, Color.Black); this.myPlot.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; this.myPlot.AddInteraction(new NPlot.Windows.PlotSurface2D.Interactions.RubberBandSelection()); this.myPlot.Add(ip); ///////蠟燭圖/////////// int[] opens = { 1, 2, 1, 2, 1, 3 }; double[] closes = { 2, 2, 2, 1, 2, 1 }; float[] lows = { 0, 1, 1, 1, 0, 0 }; System.Int64[] highs = { 3, 2, 3, 3, 3, 4 }; int[] times = { 0, 1, 2, 3, 4, 5 }; CandlePlot cp = new CandlePlot(); cp.CloseData = closes; cp.OpenData = opens; cp.LowData = lows; cp.HighData = highs; cp.AbscissaData = times; this.myPlot.Add(cp); /////對數坐標軸//////// // x axis LogAxis logax = new LogAxis(plotSurface.XAxis1); logax.WorldMin = xmin; logax.WorldMax = xmax; logax.AxisColor = Color.Red; logax.LabelColor = Color.Red; logax.TickTextColor = Color.Red; logax.LargeTickStep = 1.0f; logax.Label = "x"; this.myPlot.XAxis1 = logax; // y axis LogAxis logay = new LogAxis(plotSurface.YAxis1); logay.WorldMin = ymin; logay.WorldMax = ymax; logay.AxisColor = Color.Red; logay.LabelColor = Color.Red; logay.TickTextColor = Color.Red; logay.LargeTickStep = 1.0f; logay.Label = "x^2"; this.myPlot.YAxis1 = logay; /////字符坐標軸//////// LabelAxis la1 = new LabelAxis(this.myPlot.XAxis1); string[] sX = new string [15]; for (int i = 0; i < 15; i++) { la1.AddLabel(sX[i].ToString(), i); } la1.Label = "時間"; la1.TickTextFont = new Font("Courier New", 10); la1.TicksBetweenText = true; this.myPlot.XAxis1 = la1; /////區域着色//////// FilledRegion fr = new FilledRegion(new VerticalLine(1.2),new VerticalLine(2.4)); //兩條線之間的區域: FilledRegion fr = new FilledRegion(lp1, lp2); fr.Brush = Brushes.BlanchedAlmond; this.myPlot.Add(fr); //////畫箭頭////////// ArrowItem a = new ArrowItem(new PointD(2, 4),360-(30-90), "Arrow"); a.HeadOffset = 5; a.ArrowColor = Color.Red; a.TextColor = Color.Purple; this.myPlot.Add(a); this.myPlot.Refresh(); }