/// <summary> /// Stack the histogram to another HistogramPlot. /// </summary> public void StackedTo(HistogramPlot hp) { SequenceAdapter data = new SequenceAdapter(DataSource, DataMember, OrdinateData, 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 XwPlotException("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 XwPlotException("Can stack HistogramPlot data only with the same X coordinates"); } if (hpData[i].Y < 0.0) { throw new XwPlotException("Can stack HistogramPlot data only with positive Y coordinates"); } } } stackedTo = hp; }
public HistogramSample() : base() { infoText = ""; infoText += "Gaussian Example. Demonstrates - \n"; infoText += " * HistogramPlot and LinePlot" ; plotCanvas.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) { a[i] = Math.Exp (-(double)(i-len/2)*(double)(i-len/2)/50.0); b[i] = a[i] + (r.Next(10)/50.0f)-0.05f; if (b[i] < 0) { b[i] = 0; } } HistogramPlot sp = new HistogramPlot (); sp.DataSource = b; sp.BorderColor = Colors.DarkBlue; sp.Filled = true; sp.FillColor = Colors.Gold; //Gradient (Colors.Lavender, Color.Gold ); sp.BaseWidth = 0.5; sp.Label = "Random Data"; LinePlot lp = new LinePlot (); lp.DataSource = a; lp.LineColor = Colors.Blue; lp.LineWidth = 3; lp.Label = "Gaussian Function"; plotCanvas.Add (sp); plotCanvas.Add (lp); plotCanvas.Legend = new Legend (); plotCanvas.YAxis1.WorldMin = 0.0; plotCanvas.Title = "Histogram Plot"; PackStart (plotCanvas.Canvas, true); Label la = new Label (infoText); PackStart (la); }
/// <summary> /// Returns a y-axis that is suitable for drawing this plot. /// </summary> /// <returns>A suitable y-axis.</returns> public Axis SuggestYAxis() { if (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.0, tmpMax); // TODO make 0.08 a parameter. a.IncreaseRange(0.08); return(a); } else { SequenceAdapter data = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); return(data.SuggestYAxis()); } }
public StackedHistogram() { infoText = ""; infoText += "Stacked Histogram Sample. Also demonstrates - \n"; infoText += " * Label Axis with angled text. \n"; infoText += " * ColorGradient Bars fill"; plotCanvas.Clear(); Grid myGrid = new Grid(); myGrid.VerticalGridType = Grid.GridType.Coarse; double[] pattern = {1.0, 2.0}; myGrid.MajorGridDash = pattern; myGrid.MajorGridColor = Colors.LightGray; plotCanvas.Add (myGrid); // set up Histogram dataSets manually double[] xs = {20.0, 31.0, 27.0, 38.0, 24.0, 3.0, 2.0}; double[] xs2 = {7.0, 10.0, 42.0, 9.0, 2.0, 79.0, 70.0}; double[] xs3 = {1.0, 20.0, 20.0, 25.0, 10.0, 30.0, 30.0}; HistogramPlot hp1 = new HistogramPlot (); hp1.DataSource = xs; hp1.BaseWidth = 0.6; hp1.FillGradient = new ColorGradient (Colors.LightGreen, Colors.White); hp1.Filled = true; hp1.Label = "Developer Work"; HistogramPlot hp2 = new HistogramPlot (); hp2.DataSource = xs2; hp2.Label = "Web Browsing"; hp2.FillGradient = new ColorGradient (Colors.LightBlue, Colors.White); hp2.Filled = true; hp2.StackedTo (hp1); HistogramPlot hp3 = new HistogramPlot (); hp3.DataSource = xs3; hp3.Label = "P2P Downloads"; hp3.FillGradient = new ColorGradient (Colors.Red, Colors.White); hp3.Filled = true; hp3.StackedTo (hp2); plotCanvas.Add (hp1); plotCanvas.Add (hp2); plotCanvas.Add (hp3); plotCanvas.Legend = new Legend(); LabelAxis la = new LabelAxis (plotCanvas.XAxis1); la.AddLabel ("Monday", 0.0); la.AddLabel ("Tuesday", 1.0); la.AddLabel ("Wednesday", 2.0); la.AddLabel ("Thursday", 3.0); la.AddLabel ("Friday", 4.0); la.AddLabel ("Saturday", 5.0); la.AddLabel ("Sunday", 6.0); la.Label = "Days"; la.TickTextFont = Font.FromName ("Courier New").WithSize (8); la.TicksBetweenText = true; plotCanvas.XAxis1 = la; plotCanvas.YAxis1.WorldMin = 0.0; plotCanvas.YAxis1.Label = "MBytes"; ((LinearAxis)plotCanvas.YAxis1).NumberOfSmallTicks = 1; plotCanvas.Title = "Internet useage for user:\n johnc 09/01/03 - 09/07/03"; plotCanvas.XAxis1.TickTextAngle = 30.0; PackStart (plotCanvas.Canvas, true); Label l = new Label (infoText); PackStart (l); }
/// <summary> /// Stack the histogram to another HistogramPlot. /// </summary> public void StackedTo(HistogramPlot hp) { SequenceAdapter data = new SequenceAdapter (DataSource, DataMember, OrdinateData, 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 XwPlotException ("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 XwPlotException ("Can stack HistogramPlot data only with the same X coordinates"); } if (hpData[i].Y < 0.0) { throw new XwPlotException ("Can stack HistogramPlot data only with positive Y coordinates"); } } } stackedTo = hp; }
/// <summary> /// Draws the histogram. /// </summary> /// <param name="ctx">The Drawing Context with 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(Context ctx, PhysicalAxis xAxis, PhysicalAxis yAxis) { double yoff; SequenceAdapter data = new SequenceAdapter(DataSource, DataMember, OrdinateData, AbscissaData); ctx.Save(); ctx.SetLineWidth(1); for (int i = 0; i < data.Count; ++i) { // (1) determine the top left hand point of the bar (assuming not centered) Point 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) Point p2 = Point.Zero;; 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.0; 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.0; double yval = 0.0; 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.0; 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. Point xPos1 = xAxis.WorldToPhysical(p1.X, false); Point yPos1 = yAxis.WorldToPhysical(p1.Y, false); Point xPos2 = xAxis.WorldToPhysical(p2.X, false); if (IsStacked) { currentPlot = this; while (currentPlot.IsStacked) { currentPlot = currentPlot.stackedTo; } baseWidth = currentPlot.baseWidth; } double width = xPos2.X - xPos1.X; double height; if (IsStacked) { height = -yPos1.Y + yoff; } else { height = -yPos1.Y + yAxis.PhysicalMin.Y; } double xoff = (1.0 - baseWidth) / 2.0 * width; Rectangle bar = new Rectangle(xPos1.X + xoff, yPos1.Y, width - 2 * xoff, height); ctx.Rectangle(bar); if (Filled) { if (bar.Height != 0 && bar.Width != 0) { if (FillGradient != null) { // Scale FillGradient to bar rectangle double sX = bar.X + fillGradient.StartPoint.X * bar.Width; double sY = bar.Y + fillGradient.StartPoint.Y * bar.Height; double eX = bar.X + fillGradient.EndPoint.X * bar.Width; double eY = bar.Y + fillGradient.EndPoint.Y * bar.Height; LinearGradient g = new LinearGradient(sX, sY, eX, eY); g.AddColorStop(0, FillGradient.StartColor); g.AddColorStop(1, FillGradient.EndColor); ctx.Pattern = g; } else { ctx.SetColor(FillColor); } ctx.FillPreserve(); } } ctx.SetColor(BorderColor); ctx.Stroke(); } ctx.Restore(); }