/// <summary> /// Create a TextLabel for each bar in the GraphPane. /// Call this method only after calling AxisChange() /// </summary> /// <remarks> /// This method will go through the bars, create a label that corresponds to the bar value, /// and place it on the graph depending on user preferences. This works for horizontal or /// vertical bars in clusters or stacks.</remarks> /// <param name="pane">The GraphPane in which to place the text labels.</param> /// <param name="isBarCenter">true to center the labels inside the bars, false to /// place the labels just above the top of the bar.</param> /// <param name="valueFormat">The double.ToString string format to use for creating /// the labels /// </param> private void CreateBarLabels(GraphPane pane, bool isBarCenter, string valueFormat) { bool isVertical = pane.BarSettings.Base == BarBase.X; // Make the gap between the bars and the labels = 2% of the axis range float labelOffset; if (isVertical) { labelOffset = (float)(pane.YAxis.Scale.Max - pane.YAxis.Scale.Min) * 0.02f; } else { labelOffset = (float)(pane.XAxis.Scale.Max - pane.XAxis.Scale.Min) * 0.02f; } // keep a count of the number of BarItems int curveIndex = 0; // Get a valuehandler to do some calculations for us ValueHandler valueHandler = new ValueHandler(pane, true); // Loop through each curve in the list foreach (CurveItem curve in pane.CurveList) { // work with BarItems only BarItem bar = curve as BarItem; if (bar != null) { IPointList points = curve.Points; // Loop through each point in the BarItem for (int i = 0; i < points.Count; i++) { // Get the high, low and base values for the current bar // note that this method will automatically calculate the "effective" // values if the bar is stacked double baseVal, lowVal, hiVal; valueHandler.GetValues(curve, i, out baseVal, out lowVal, out hiVal); // Get the value that corresponds to the center of the bar base // This method figures out how the bars are positioned within a cluster float centerVal = (float)valueHandler.BarCenterValue(bar, bar.GetBarWidth(pane), i, baseVal, curveIndex); // Create a text label -- note that we have to go back to the original point // data for this, since hiVal and lowVal could be "effective" values from a bar stack string barLabelText = (isVertical ? points[i].Y : points[i].X).ToString(valueFormat); // Calculate the position of the label -- this is either the X or the Y coordinate // depending on whether they are horizontal or vertical bars, respectively float position; if (isBarCenter) { position = (float)(hiVal + lowVal) / 2.0f; } else { position = (float)hiVal + labelOffset; } // Create the new TextObj TextObj label; if (isVertical) { label = new TextObj(barLabelText, centerVal, position); } else { label = new TextObj(barLabelText, position, centerVal); } // Configure the TextObj label.Location.CoordinateFrame = CoordType.AxisXYScale; label.FontSpec.Size = 12; label.FontSpec.FontColor = Color.Black; label.FontSpec.Angle = isVertical ? 90 : 0; label.Location.AlignH = isBarCenter ? AlignH.Center : AlignH.Left; label.Location.AlignV = AlignV.Center; label.FontSpec.Border.IsVisible = false; label.FontSpec.Fill.IsVisible = false; // Add the TextObj to the GraphPane pane.GraphObjList.Add(label); } } curveIndex++; } }
public HorizontalBarDemo() : base("A sideways bar demo.\n" + "This demo also shows how to add labels to the bars, in this " + "case showing the value of each bar", "HorizontalBar Demo", DemoType.Bar) { GraphPane myPane = base.GraphPane; // Set the title and axis labels myPane.Title.Text = "Horizontal Bar Graph"; myPane.XAxis.Title.Text = "Performance Factor"; myPane.YAxis.Title.Text = "Grouping"; // Enter some random data values double[] y = { 100, 115, 75, -22, 98, 40, -10 }; double[] y2 = { 90, 100, 95, -35, 80, 35, 35 }; double[] y3 = { 80, 110, 65, -15, 54, 67, 18 }; // Generate a bar with "Curve 1" in the legend BarItem myCurve = myPane.AddBar("Curve 1", y, null, Color.Red); // Fill the bar with a red-white-red gradient myCurve.Bar.Fill = new Fill(Color.Red, Color.White, Color.Red, 90F); // Generate a bar with "Curve 2" in the legend myCurve = myPane.AddBar("Curve 2", y2, null, Color.Blue); // Fill the bar with a blue-white-blue gradient for a 3d look myCurve.Bar.Fill = new Fill(Color.Blue, Color.White, Color.Blue, 90F); // Generate a bar with "Curve 3" in the legend myCurve = myPane.AddBar("Curve 3", y3, null, Color.Green); // Fill the bar with a Green-white-Green gradient for a 3d look myCurve.Bar.Fill = new Fill(Color.White, Color.Green, 90F); // Draw the X tics between the labels instead of at the labels myPane.YAxis.MajorTic.IsBetweenLabels = true; // Set the XAxis to an ordinal type myPane.YAxis.Type = AxisType.Ordinal; // draw the X axis zero line myPane.XAxis.MajorGrid.IsZeroLine = true; //This is the part that makes the bars horizontal myPane.BarSettings.Base = BarBase.Y; // Fill the axis background with a color gradient myPane.Chart.Fill = new Fill(Color.White, Color.FromArgb(255, 255, 166), 45.0F); base.ZedGraphControl.AxisChange(); // The ValueHandler is a helper that does some position calculations for us. ValueHandler valueHandler = new ValueHandler(myPane, true); // Display a value for the maximum of each bar cluster // Shift the text items by 5 user scale units above the bars const float shift = 3; int ord = 0; foreach (CurveItem curve in myPane.CurveList) { BarItem bar = curve as BarItem; if (bar != null) { IPointList points = curve.Points; for (int i = 0; i < points.Count; i++) { double xVal = points[i].X; // Calculate the Y value at the center of each bar double yVal = valueHandler.BarCenterValue(curve, curve.GetBarWidth(myPane), i, points[i].Y, ord); // format the label string to have 1 decimal place string lab = xVal.ToString("F0"); // create the text item (assumes the x axis is ordinal or text) // for negative bars, the label appears just above the zero value TextObj text = new TextObj(lab, (float)xVal + (xVal > 0 ? shift : -shift), (float)yVal); // tell Zedgraph to use user scale units for locating the TextObj text.Location.CoordinateFrame = CoordType.AxisXYScale; text.FontSpec.Size = 10; // AlignH the left-center of the text to the specified point text.Location.AlignH = xVal > 0 ? AlignH.Left : AlignH.Right; text.Location.AlignV = AlignV.Center; text.FontSpec.Border.IsVisible = false; // rotate the text 90 degrees text.FontSpec.Angle = 0; text.FontSpec.Fill.IsVisible = false; // add the TextObj to the list myPane.GraphObjList.Add(text); } } ord++; } }