public void fillRoundRect(int x, int y, int width, int height, int d1, int d2) { int r1 = d1 / 2; int r2 = d2 / 2; System.Drawing.SolidBrush brush = new System.Drawing.SolidBrush(col); graph.FillRectangle(brush, x + r1, y, width - d1, r2); graph.FillRectangle(brush, x + r1, y + height - r2, width - d1, r2); graph.FillRectangle(brush, x, y + r2, r1, height - d2); graph.FillRectangle(brush, x + width - r1, y + r2, r1, height - d2); graph.FillRectangle(brush, x + r1, y + r2, width - d1, height - d2); graph.FillPie(brush, x, y, d1, d2, 180, 90); graph.FillPie(brush, x + width - d1, y, d1, d2, 270, 90); graph.FillPie(brush, x, y + height - d2, d1, d2, 90, 90); graph.FillPie(brush, x + width - d1, y + height - d2, d1, d2, 0, 90); }
void RenderPie(bool left, System.Drawing.Graphics g) { Pie pie = left ? _leftPie : _rightPie; Label firstLabel = null; Label lastLabel = null; float startAngle = 0F; for (int i = 0; i < pie.Blocks.Count; i++) { PieBlock block = pie.Blocks[i]; Label label = _labels.Find(p => p.Index == block.Index); if (label == null) { continue; } if (i == 0) { firstLabel = label; } lastLabel = label; g.FillPie(label.Brush, pie.X, pie.Y, pie.Width, pie.Height, startAngle, block.Percent); startAngle += block.Percent; } if (firstLabel == null) { firstLabel = new Label() { Index = 0, Color = System.Drawing.Color.Gray, Name = "" }; g.FillPie(firstLabel.Brush, pie.X, pie.Y, pie.Width, pie.Height, 0F, 1F); } g.DrawPie(new System.Drawing.Pen(firstLabel.Brush), pie.X, pie.Y, pie.Width, pie.Height, 0F, 360F); //bottom labels float bottomY = pie.Y + pie.Height + 15F; if (left) { float bottomX = pie.X + 4F; for (int i = 0; i < pie.Labels.Count; i++) { Label label = pie.Labels[i]; g.FillRectangle(label.Brush, bottomX, bottomY, Font.Height, Font.Height); bottomX += Font.Height + 3F; string text = label.Name; System.Drawing.SizeF textSize = g.MeasureString(text, _font); g.DrawString(text, _font, label.Brush, bottomX, bottomY + (_font.Height - textSize.Height) / 2F); bottomX += textSize.Width + 10F; if (!string.IsNullOrEmpty(label.Value)) { text = label.Value; bottomX -= 8F; textSize = g.MeasureString(text, _font); g.DrawString(text, _font, label.Brush, bottomX, bottomY + (_font.Height - textSize.Height) / 2F); bottomX += textSize.Width + 10F; } } } else { float bottomX = pie.X + pie.Width - 4F; for (int i = pie.Labels.Count - 1; i >= 0; i--) { Label label = pie.Labels[i]; string text = null; System.Drawing.SizeF textSize; if (!string.IsNullOrEmpty(label.Value)) { text = label.Value; textSize = g.MeasureString(text, _font); bottomX -= textSize.Width; g.DrawString(text, _font, label.Brush, bottomX, bottomY + (_font.Height - textSize.Height) / 2F); bottomX -= 3F; } text = label.Name; textSize = g.MeasureString(text, _font); bottomX -= textSize.Width; g.DrawString(text, _font, label.Brush, bottomX, bottomY + (_font.Height - textSize.Height) / 2F); bottomX -= 3F; bottomX -= Font.Height; g.FillRectangle(label.Brush, bottomX, bottomY, Font.Height, Font.Height); bottomX -= 10F; } } }
protected override void RenderChart(System.Drawing.Graphics graphics, Palette palette, Bamboo.Css.StyleStack styleStack, System.Drawing.RectangleF rectangle, string title, Bamboo.DataStructures.Table table) { styleStack.PushTag("PieChart"); string backColor = (string)styleStack["BackColor"]; Bamboo.Css.Font font = (Bamboo.Css.Font)styleStack["Font"]; string foreColor = (string)styleStack["ForeColor"]; int padding = (int)styleStack["Padding"]; string[] colors = (string[])styleStack["Colors"]; //TODO put in stylesheet. System.Drawing.Font titleFont = palette.Font(font.Name, font.Size * 1.2f, System.Drawing.FontStyle.Bold); //TODO put in stylesheet. System.Drawing.Font labelFont = palette.Font(font.Name, font.Size, System.Drawing.FontStyle.Bold); System.Drawing.Pen backColorPen = palette.Pen(backColor); System.Drawing.Brush backColorBrush = palette.Brush(backColor); System.Drawing.Brush foreColorBrush = palette.Brush(foreColor); // Background graphics.DrawRectangle(backColorPen, rectangle.Left, rectangle.Top, rectangle.Width, rectangle.Height); graphics.FillRectangle(backColorBrush, rectangle); rectangle = new System.Drawing.RectangleF(rectangle.Left + padding, rectangle.Top + padding, rectangle.Width - padding - padding, rectangle.Height - padding - padding); // Title if (title != null) { rectangle = DrawTitle(title, titleFont, foreColorBrush, graphics, rectangle); } //TODO // Legend // rectangle = new System.Drawing.RectangleF(rectangle.Left, rectangle.Top, rectangle.Width - padding - padding, rectangle.Height); Slice[] slices = new Slice[table.Rows.Count]; float sum = 0; for (int i = 0; i < table.Rows.Count; i++) { Bamboo.DataStructures.Tuple row = table.Rows[i]; slices[i].Label = row[0].ToString(); float value = System.Convert.ToSingle(row[1]); slices[i].Value = value; sum += value; } sum /= 360; float startAngle = -90; for (int i = 0; i < slices.Length; i++) { slices[i].StartAngle = startAngle; float sweepAngle = slices[i].Value / sum; slices[i].SweepAngle = sweepAngle; double startPlusHalfSweepRadian = DegreeToRadian(startAngle + (sweepAngle / 2)); slices[i].LabelCos = (float)Math.Cos(startPlusHalfSweepRadian); slices[i].LabelSin = (float)Math.Sin(startPlusHalfSweepRadian); System.Drawing.SizeF sizef = MeasureString(graphics, slices[i].Label, labelFont); slices[i].LabelWidth = sizef.Width; slices[i].LabelHeight = sizef.Height; slices[i].Adjacent = slices[i].LabelCos * slices[i].LabelWidth; slices[i].Opposite = slices[i].LabelSin * slices[i].LabelHeight; slices[i].Hypotenuse = (float)Math.Sqrt((slices[i].Adjacent * slices[i].Adjacent) + (slices[i].Opposite * slices[i].Opposite)); slices[i].Brush = palette.Brush(colors[i % colors.Length]); startAngle += sweepAngle; } float x_min = 0; float x_max = 0; float y_min = 0; float y_max = 0; for (int i = 0; i < slices.Length; i++) { x_min = Math.Min(x_min, slices[i].Adjacent); x_max = Math.Max(x_max, slices[i].Adjacent); y_min = Math.Min(y_min, slices[i].Opposite); y_max = Math.Max(y_max, slices[i].Opposite); } float x_offset = Math.Max(Math.Abs(x_min), x_max); float y_offset = Math.Max(Math.Abs(y_min), y_max); rectangle = new System.Drawing.RectangleF(rectangle.Left + x_offset, rectangle.Top + y_offset, rectangle.Width - (x_offset * 2), rectangle.Height - (y_offset * 2)); float halfInnerWidth = rectangle.Width / 2; float halfInnerHeight = rectangle.Height / 2; float radius = Math.Min(halfInnerWidth, halfInnerHeight); float diameter = radius + radius; float x = rectangle.Left + halfInnerWidth - radius; float y = rectangle.Top + halfInnerHeight - radius; if (radius > 0) { graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; for (int i = 0; i < slices.Length; i++) { graphics.FillPie(slices[i].Brush, x, y, diameter, diameter, slices[i].StartAngle, slices[i].SweepAngle); float radiusPlusHalfHypotenuse = radius + slices[i].Hypotenuse / 2; float labelLeft = x + radius - (slices[i].LabelWidth / 2) + (slices[i].LabelCos * radiusPlusHalfHypotenuse); float labelTop = y + radius - (slices[i].LabelHeight / 2) + (slices[i].LabelSin * radiusPlusHalfHypotenuse); //TODO use a style for Brush DrawString(graphics, slices[i].Label, labelFont, foreColorBrush, labelLeft, labelTop); } graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default; } styleStack.PopTag(); }