/// <summary> /// Stack the histogram to another HistogramPlot. /// </summary> public void StackedTo(HistogramPlot hp) { SequenceAdapter data = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData); SequenceAdapter hpData = new SequenceAdapter(hp.DataSource, hp.DataMember, hp.OrdinateData, hp.AbscissaData); if (hp != null) { isStacked_ = true; if (hpData.Count != data.Count) { throw new NPlotException("Can stack HistogramPlot data only with the same number of datapoints."); } for (int i = 0; i < data.Count; ++i) { if (data[i].X != hpData[i].X) { throw new NPlotException("Can stack HistogramPlot data only with the same X coordinates."); } if (hpData[i].Y < 0.0f) { throw new NPlotException("Can stack HistogramPlot data only with positive Y coordinates."); } } } stackedTo_ = hp; }
/// <summary> /// Returns a y-axis that is suitable for drawing this plot. /// </summary> /// <returns>A suitable y-axis.</returns> public Axis SuggestYAxis() { if (this.isStacked_) { double tmpMax = 0.0f; ArrayList adapterList = new ArrayList(); HistogramPlot currentPlot = this; do { adapterList.Add(new SequenceAdapter( currentPlot.DataSource, currentPlot.DataMember, currentPlot.OrdinateData, currentPlot.AbscissaData) ); } while ((currentPlot = currentPlot.stackedTo_) != null); SequenceAdapter[] adapters = (SequenceAdapter[])adapterList.ToArray(typeof(SequenceAdapter)); for (int i = 0; i < adapters[0].Count; ++i) { double tmpHeight = 0.0f; for (int j = 0; j < adapters.Length; ++j) { tmpHeight += adapters[j][i].Y; } tmpMax = Math.Max(tmpMax, tmpHeight); } Axis a = new LinearAxis(0.0f, tmpMax); // TODO make 0.08 a parameter. a.IncreaseRange(0.08); return(a); } else { SequenceAdapter data = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData); return(data.SuggestYAxis()); } }
/// <summary> /// Renders the histogram. /// </summary> /// <param name="g">The Graphics surface on which to draw</param> /// <param name="xAxis">The X-Axis to draw against.</param> /// <param name="yAxis">The Y-Axis to draw against.</param> public void Draw(Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis) { SequenceAdapter data = new SequenceAdapter(this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData); float yoff; for (int i = 0; i < data.Count; ++i) { // (1) determine the top left hand point of the bar (assuming not centered) PointD p1 = data[i]; if (double.IsNaN(p1.X) || double.IsNaN(p1.Y)) { continue; } // (2) determine the top right hand point of the bar (assuming not centered) PointD p2; if (i + 1 != data.Count) { p2 = data[i + 1]; if (double.IsNaN(p2.X) || double.IsNaN(p2.Y)) { continue; } p2.Y = p1.Y; } else if (i != 0) { p2 = data[i - 1]; if (double.IsNaN(p2.X) || double.IsNaN(p2.Y)) { continue; } double offset = p1.X - p2.X; p2.X = p1.X + offset; p2.Y = p1.Y; } else { double offset = 1.0f; p2.X = p1.X + offset; p2.Y = p1.Y; } // (3) now account for plots this may be stacked on top of. HistogramPlot currentPlot = this; yoff = 0.0f; double yval = 0.0f; while (currentPlot.isStacked_) { SequenceAdapter stackedToData = new SequenceAdapter( currentPlot.stackedTo_.DataSource, currentPlot.stackedTo_.DataMember, currentPlot.stackedTo_.OrdinateData, currentPlot.stackedTo_.AbscissaData); yval += stackedToData[i].Y; yoff = yAxis.WorldToPhysical(yval, false).Y; p1.Y += stackedToData[i].Y; p2.Y += stackedToData[i].Y; currentPlot = currentPlot.stackedTo_; } // (4) now account for centering if (center_) { double offset = (p2.X - p1.X) / 2.0f; p1.X -= offset; p2.X -= offset; } // (5) now account for BaseOffset (shift of bar sideways). p1.X += baseOffset_; p2.X += baseOffset_; // (6) now get physical coordinates of top two points. PointF xPos1 = xAxis.WorldToPhysical(p1.X, false); PointF yPos1 = yAxis.WorldToPhysical(p1.Y, false); PointF xPos2 = xAxis.WorldToPhysical(p2.X, false); PointF yPos2 = yAxis.WorldToPhysical(p2.Y, false); if (isStacked_) { currentPlot = this; while (currentPlot.isStacked_) { currentPlot = currentPlot.stackedTo_; } this.baseWidth_ = currentPlot.baseWidth_; } float width = xPos2.X - xPos1.X; float height; if (isStacked_) { height = -yPos1.Y + yoff; } else { height = -yPos1.Y + yAxis.PhysicalMin.Y; } float xoff = (1.0f - baseWidth_) / 2.0f * width; Rectangle r = new Rectangle((int)(xPos1.X + xoff), (int)yPos1.Y, (int)(width - 2 * xoff), (int)height); if (this.Filled) { if (r.Height != 0 && r.Width != 0) { // room for optimization maybe. g.FillRectangle(rectangleBrush_.Get(r), r); } } g.DrawRectangle(Pen, r.X, r.Y, r.Width, r.Height); } }
public void PlotProfitLoss() { // this example will in the future demonstrate histogram plots with +- values. // currently not used - histograms don't support this. plotSurface.Clear(); int[] values = {-10,2,-3, 4, 6, -1, 10, 4, -4, -3 }; HistogramPlot hp = new HistogramPlot(); hp.OrdinateData = values; plotSurface.Add(hp); plotSurface.XAxis1.LabelOffset = 0; plotSurface.YAxis1.LabelOffset = 0; plotSurface.Refresh(); }
public void PlotMultiHistogram() { double[] data = new double[] { 0, 4, 3, 2, 5, 4, 2, 3 }; double[] data2 = new double[] { 5, 2, 4, 1, 2, 1, 5, 3 }; HistogramPlot hp = new HistogramPlot(); hp.OrdinateData = data; hp.RectangleBrush = RectangleBrushes.Horizontal.FaintRedFade; hp.Filled = true; hp.BaseOffset = -0.15; hp.BaseWidth = 0.25f; HistogramPlot hp2 = new HistogramPlot(); hp2.OrdinateData = data2; hp2.RectangleBrush = RectangleBrushes.Horizontal.FaintGreenFade; hp2.Filled = true; hp2.BaseOffset = 0.15; hp2.BaseWidth = 0.25f; plotSurface.Clear(); plotSurface.Add(hp); plotSurface.Add(hp2); plotSurface.PlotBackBrush = RectangleBrushes.Vertical.FaintBlueFade; plotSurface.XAxis1.LabelOffset = 0; plotSurface.YAxis1.LabelOffset = 0; plotSurface.Refresh(); }
public void PlotLabelAxis() { string lines = "Internet Usage Example. Demonstrates - * Label Axis with angular text. * RectangleBrushes."; infoBox.Text = lines; plotSurface.Clear(); Grid mygrid = new Grid(); mygrid.VerticalGridType = Grid.GridType.Coarse; Pen majorGridPen = new Pen( Color.LightGray ); float[] pattern = { 1.0f, 2.0f }; mygrid.MajorGridPen = majorGridPen; plotSurface.Add( mygrid ); float[] xs = {20.0f, 31.0f, 27.0f, 38.0f, 24.0f, 3.0f, 2.0f }; float[] xs2 = {7.0f, 10.0f, 42.0f, 9.0f, 2.0f, 79.0f, 70.0f }; float[] xs3 = {1.0f, 20.0f, 20.0f, 25.0f, 10.0f, 30.0f, 30.0f }; HistogramPlot hp = new HistogramPlot(); hp.DataSource = xs; hp.BaseWidth = 0.6f; hp.RectangleBrush = new RectangleBrushes.HorizontalCenterFade( Color.FromArgb(255,255,200), Color.White ); hp.Filled = true; hp.Label = "Developer Work"; HistogramPlot hp2 = new HistogramPlot(); hp2.DataSource = xs2; hp2.Label = "Web Browsing"; hp2.RectangleBrush = RectangleBrushes.Horizontal.FaintGreenFade; hp2.Filled = true; hp2.StackedTo( hp ); HistogramPlot hp3 = new HistogramPlot(); hp3.DataSource = xs3; hp3.Label = "P2P Downloads"; hp3.RectangleBrush = RectangleBrushes.Vertical.FaintBlueFade; hp3.Filled = true; hp3.StackedTo( hp2 ); plotSurface.Add( hp ); plotSurface.Add( hp2 ); plotSurface.Add( hp3 ); plotSurface.Legend = new Legend(); LabelAxis la = new LabelAxis( plotSurface.XAxis1 ); la.AddLabel( "Monday", 0.0f ); la.AddLabel( "Tuesday", 1.0f ); la.AddLabel( "Wednesday", 2.0f ); la.AddLabel( "Thursday", 3.0f ); la.AddLabel( "Friday", 4.0f ); la.AddLabel( "Saturday", 5.0f ); la.AddLabel( "Sunday", 6.0f ); la.Label = "Days"; la.TickTextFont = new Font( "Courier New", 8 ,FontStyle.Regular); la.TicksBetweenText = true; plotSurface.XAxis1 = la; plotSurface.YAxis1.WorldMin = 0.0; plotSurface.YAxis1.Label = "MBytes"; ((LinearAxis)plotSurface.YAxis1).NumberOfSmallTicks = 1; plotSurface.Title = "Internet useage for user:\n johnc 09/01/03 - 09/07/03"; plotSurface.XAxis1.TicksLabelAngle = 30.0f; plotSurface.XAxis1.LabelOffset = 0; plotSurface.YAxis1.LabelOffset = 0; plotSurface.PlotBackBrush = RectangleBrushes.Vertical.FaintRedFade; plotSurface.Refresh(); }
public void PlotGaussian() { string lines = "Gaussian Example. Demonstrates - * HistogramPlot and LinePlot."; infoBox.Text = lines; plotSurface.Clear(); System.Random r = new Random(); int len = 35; double[] a = new double[len]; double[] b = new double[len]; for (int i=0; i<len; ++i) { int j = len-1-i; a[i] = (double)Math.Exp(-(double)(i-len/2)*(double)(i-len/2)/50.0f); b[i] = a[i] + (r.Next(10)/50.0f)-0.05f; if (b[i] < 0.0f) { b[i] = 0; } } HistogramPlot sp = new HistogramPlot(); sp.DataSource = b; sp.Pen = new Pen(Color.DarkBlue); sp.Filled = true; sp.RectangleBrush = new RectangleBrushes.HorizontalCenterFade( Color.Lavender, Color.Gold ); sp.BaseWidth = 0.5f; sp.Label = "Random Data"; LinePlot lp = new LinePlot(); lp.DataSource = a; lp.Pen = new Pen( Color.Blue, 3.0f ); lp.Label = "Gaussian Function"; plotSurface.Add( sp ); plotSurface.Add( lp ); plotSurface.Legend = new Legend(); plotSurface.YAxis1.WorldMin = 0.0f; plotSurface.Title = "Histogram Plot"; plotSurface.XAxis1.LabelOffset = 0; plotSurface.YAxis1.LabelOffset = 0; plotSurface.Refresh(); }
/// <summary> /// Stack the histogram to another HistogramPlot. /// </summary> public void StackedTo(HistogramPlot hp) { SequenceAdapter data = new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData ); SequenceAdapter hpData = new SequenceAdapter( hp.DataSource, hp.DataMember, hp.OrdinateData, hp.AbscissaData ); if ( hp != null ) { isStacked_ = true; if ( hpData.Count != data.Count ) { throw new NPlotException("Can stack HistogramPlot data only with the same number of datapoints."); } for ( int i=0; i < data.Count; ++i ) { if ( data[i].X != hpData[i].X ) { throw new NPlotException("Can stack HistogramPlot data only with the same X coordinates."); } if ( hpData[i].Y < 0.0f) { throw new NPlotException("Can stack HistogramPlot data only with positive Y coordinates."); } } } stackedTo_ = hp; }
public void InitDataToChart() { float min = (float)dataList[0];//最小值 float max = (float)dataList[0];//最大值 for (int i = 1; i < dataList.Count; i++) { if ((float)dataList[i] < min) min = (float)dataList[i]; if ((float)dataList[i] > max) max = (float)dataList[i]; } int start = (int)(min / 10) * 10;//x轴的起始值 int end = (int)Math.Ceiling(max / 10) * 10;//x轴的末尾值 int offset = 10;//x轴的偏移量 int size = (int)Math.Ceiling((float)(end - start) / offset);//计算柱状图中柱体的个数 double[] xValues = new double[size]; double[] yValues = new double[size]; for (int i = 0; i < size; i++) { xValues[i] = start + offset * i; } for (int i = 0; i < dataList.Count; i++) { int index = (int)(((float)dataList[i] - start) / offset); yValues[index]++; } for (int i = 0; i < size; i++) { yValues[i] = yValues[i] / dataList.Count * 100; } /*//图例 legend = new Legend(); legend.AttachTo(PlotSurface2D.XAxisPosition.Top, PlotSurface2D.YAxisPosition.Left); legend.VerticalEdgePlacement = Legend.Placement.Inside; legend.HorizontalEdgePlacement = Legend.Placement.Outside; legend.YOffset = -5; legend.BorderStyle = LegendBase.BorderType.Line; legend.NumberItemsHorizontally = 2; legend.Font = new Font(FontFamily.GenericSerif, 8, FontStyle.Regular); legend.AutoScaleText = false;*/ //网格 grid = new Grid(); grid.HorizontalGridType = Grid.GridType.Fine; grid.VerticalGridType = Grid.GridType.Fine; grid.MajorGridPen.Color = Color.Silver; grid.MinorGridPen.Color = Color.Silver; ///////////////////////////////////////////// //柱状图 histogramPlot = new HistogramPlot(); histogramPlot.AbscissaData = xValues; histogramPlot.OrdinateData = yValues; histogramPlot.RectangleBrush = new RectangleBrushes.Solid(Color.Orange); histogramPlot.Filled = true; histogramPlot.BaseWidth = 0.25f; //添加 chart.Add(grid); chart.Add(histogramPlot); // chart.XAxis1.Label = xLabel; chart.XAxis1.TicksCrossAxis = true; chart.YAxis1.Label = "%"; chart.YAxis1.WorldMin = 0; chart.YAxis1.LabelOffsetAbsolute = true; chart.Padding = 5; chart.AddInteraction(new xuzhenzhen.com.chart.Windows.PlotSurface2D.Interactions.VerticalGuideline()); chart.AddAxesConstraint(new AxesConstraint.AxisPosition(PlotSurface2D.YAxisPosition.Left, 60)); // chart.PlotBackColor = Color.White; chart.BackColor = System.Drawing.SystemColors.Control; chart.XAxis1.Color = Color.Black; chart.YAxis1.Color = Color.Black; //chart.Legend = legend; chart.LegendZOrder = 1; chart.Refresh(); }