123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- using System;
- using System.ComponentModel;
- using System.Drawing;
- using System.Drawing.Design;
- using System.Drawing.Drawing2D;
- using FastReport.Utils;
- namespace FastReport.Gauge.Radial
- {
- #region Enums
- /// <summary>
- /// Radial Gauge types
- /// </summary>
- [Flags]
- public enum RadialGaugeType
- {
- /// <summary>
- /// Full sized gauge
- /// </summary>
- Circle = 1,
- /// <summary>
- /// Half of the radial gauge
- /// </summary>
- Semicircle = 2,
- /// <summary>
- /// Quarter of the radial gauge
- /// </summary>
- Quadrant = 4
- }
- /// <summary>
- /// Radial Gauge position types
- /// </summary>
- [Flags]
- public enum RadialGaugePosition
- {
- /// <summary>
- /// None
- /// </summary>
- None = 0,
- /// <summary>
- /// Top
- /// </summary>
- Top = 1,
- /// <summary>
- /// Bottom
- /// </summary>
- Bottom = 2,
- /// <summary>
- /// Left
- /// </summary>
- Left = 4,
- /// <summary>
- /// Right
- /// </summary>
- Right = 8
- }
- #endregion // Enums
-
- /// <summary>
- /// Represents a linear gauge.
- /// </summary>
- public partial class RadialGauge : GaugeObject
- {
- private const double RAD = Math.PI / 180.0;
- private PointF center;
- private RadialGaugeType type;
- private RadialGaugePosition position;
- private float semicircleOffsetRatio;
- #region Properties
- /// <inheritdoc/>
- public override float Width
- {
- get { return base.Width; }
- set
- {
- base.Width = value;
- if (base.Height != base.Width)
- {
- base.Height = Width;
- }
- }
- }
- /// <inheritdoc/>
- public override float Height
- {
- get { return base.Height; }
- set
- {
- base.Height = value;
- if (base.Width != base.Height)
- {
- base.Width = Height;
- }
- }
- }
- /// <summary>
- /// Returns centr of the gauge
- /// </summary>
- [Browsable(false)]
- public PointF Center
- {
- get { return center; }
- set { center = value; }
- }
- /// <summary>
- /// The number of radians in one degree
- /// </summary>
- public static double Radians
- {
- get { return RAD; }
- }
- /// <summary>
- /// Gets or sets the Radial Gauge type
- /// </summary>
- [Browsable(true)]
- [Category("Appearance")]
- public RadialGaugeType Type
- {
- get { return type; }
- set
- {
- if (value == RadialGaugeType.Circle)
- {
- position = RadialGaugePosition.None;
- type = value;
- }
- if (value == RadialGaugeType.Semicircle &&
- !(Position == RadialGaugePosition.Bottom ||
- Position == RadialGaugePosition.Left ||
- Position == RadialGaugePosition.Right ||
- Position == RadialGaugePosition.Top))
- {
- position = RadialGaugePosition.Top;
- type = value;
- }
- else if (value == RadialGaugeType.Quadrant &&
- !(
- ((Position & RadialGaugePosition.Left) != 0 && (Position & RadialGaugePosition.Top) != 0 &&
- (Position & RadialGaugePosition.Right) == 0 && (Position & RadialGaugePosition.Bottom) == 0) ||
- ((Position & RadialGaugePosition.Right) != 0 && (Position & RadialGaugePosition.Top) != 0 &&
- (Position & RadialGaugePosition.Left) == 0 && (Position & RadialGaugePosition.Bottom) == 0) ||
-
- ((Position & RadialGaugePosition.Left) != 0 && (Position & RadialGaugePosition.Bottom) != 0 &&
- (Position & RadialGaugePosition.Right) == 0 && (Position & RadialGaugePosition.Top) == 0) ||
-
- ((Position & RadialGaugePosition.Right) != 0 && (Position & RadialGaugePosition.Bottom) != 0 &&
- (Position & RadialGaugePosition.Left) == 0 && (Position & RadialGaugePosition.Top) == 0)
- ))
- {
- position = RadialGaugePosition.Top | RadialGaugePosition.Left;
- type = value;
- }
-
- }
- }
- /// <summary>
- /// Gats or sets the Radial Gauge position. Doesn't work for Full Radial Gauge.
- /// </summary>
- [Category("Appearance")]
- [Editor("FastReport.TypeEditors.FlagsEditor, FastReport", typeof(UITypeEditor))]
- public RadialGaugePosition Position
- {
- get { return position; }
- set
- {
- if(Type == RadialGaugeType.Semicircle &&
- (value == RadialGaugePosition.Bottom ||
- value == RadialGaugePosition.Left ||
- value == RadialGaugePosition.Right ||
- value == RadialGaugePosition.Top))
- position = value;
- else if (Type == RadialGaugeType.Quadrant &&
- (
- ((value & RadialGaugePosition.Left) != 0 && (value & RadialGaugePosition.Top) != 0 &&
- (value & RadialGaugePosition.Right) == 0 && (value & RadialGaugePosition.Bottom) == 0) ||
- ((value & RadialGaugePosition.Right) != 0 && (value & RadialGaugePosition.Top) != 0 &&
- (value & RadialGaugePosition.Left) == 0 && (value & RadialGaugePosition.Bottom) == 0) ||
- ((value & RadialGaugePosition.Left) != 0 && (value & RadialGaugePosition.Bottom) != 0 &&
- (value & RadialGaugePosition.Right) == 0 && (value & RadialGaugePosition.Top) == 0) ||
- ((value & RadialGaugePosition.Right) != 0 && (value & RadialGaugePosition.Bottom) != 0 &&
- (value & RadialGaugePosition.Left) == 0 && (value & RadialGaugePosition.Top) == 0)
- ))
- position = value;
- else if (Type == RadialGaugeType.Circle)
- position = 0;
- }
- }
- /// <summary>
- /// Gets or sets the semicircles offset
- /// </summary>
- [Category("Appearance")]
- public float SemicircleOffsetRatio
- {
- get { return semicircleOffsetRatio; }
- set { semicircleOffsetRatio = value; }
- }
- #endregion // Properties
- #region Constructors
- /// <summary>
- /// Initializes a new instance of the <see cref="RadialGauge"/> class.
- /// </summary>
- public RadialGauge() : base()
- {
- InitializeComponent();
- Scale = new RadialScale(this);
- Pointer = new RadialPointer(this, Scale as RadialScale);
- Label = new RadialLabel(this);
- Height = 4.0f * Units.Centimeters;
- Width = 4.0f * Units.Centimeters;
- semicircleOffsetRatio = type == RadialGaugeType.Semicircle &&
- (position == RadialGaugePosition.Left || position == RadialGaugePosition.Right) ? 1.5f : 1;
- Type = RadialGaugeType.Circle;
- Border.Lines = BorderLines.None;
- }
- #endregion // Constructor
- #region Public Methods
- /// <inheritdoc/>
- public override void Assign(Base source)
- {
- base.Assign(source);
- RadialGauge src = source as RadialGauge;
- Type = src.Type;
- Position = src.Position;
- }
- /// <inheritdoc/>
- public override void Draw(FRPaintEventArgs e)
- {
- IGraphics g = e.Graphics;
- float x = (AbsLeft + Border.Width / 2) * e.ScaleX;
- float y = (AbsTop + Border.Width / 2) * e.ScaleY;
- float dx = (Width - Border.Width) * e.ScaleX - 1;
- float dy = (Height - Border.Width) * e.ScaleY - 1;
- float x1 = x + dx;
- float y1 = y + dy;
- Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle);
- Brush brush;
- if (Fill is SolidFill)
- brush = e.Cache.GetBrush((Fill as SolidFill).Color);
- else
- brush = Fill.CreateBrush(new RectangleF(x, y, dx, dy), e.ScaleX, e.ScaleY);
- center = new PointF(x + dx / 2, y + dy / 2);
- if (type == RadialGaugeType.Circle)
- {
- g.FillAndDrawEllipse(pen, brush, x, y, dx, dy);
- }
- else if (type == RadialGaugeType.Semicircle)
- {
- float semiOffset = (Width / 16f /2f + 2f) * semicircleOffsetRatio * e.ScaleY;
- PointF[] points = new PointF[4];
- if (position == RadialGaugePosition.Top)
- {
- g.FillPie(brush, x, y, dx, dy, -180, 180);
- g.DrawArc(pen, x, y, dx, dy, -180, 180);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -90 * RAD, center)[0];
-
- points[0] = new PointF(startPoint.X, startPoint.Y - 1 * e.ScaleY);
- points[1] = new PointF(startPoint.X, startPoint.Y + semiOffset);
- points[2] = new PointF(startPoint.X + dx, startPoint.Y + semiOffset);
- points[3] = new PointF(startPoint.X + dx, startPoint.Y - 1 * e.ScaleY);
- }
- else if(position == RadialGaugePosition.Bottom)
- {
- g.FillPie(brush, x, y, dx, dy, 0, 180);
- g.DrawArc(pen, x, y, dx, dy, 0, 180);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 90 * RAD, center)[0];
- points[0] = new PointF(startPoint.X, startPoint.Y + 1 * e.ScaleY);
- points[1] = new PointF(startPoint.X, startPoint.Y - semiOffset);
- points[2] = new PointF(startPoint.X - dx, startPoint.Y - semiOffset);
- points[3] = new PointF(startPoint.X - dx, startPoint.Y + 1 * e.ScaleY);
- }
- else if (position == RadialGaugePosition.Left)
- {
- g.FillPie(brush, x, y, dx, dy, 90, 180);
- g.DrawArc(pen, x, y, dx, dy, 90, 180);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 180 * RAD, center)[0];
- points[0] = new PointF(startPoint.X - 1 * e.ScaleX, startPoint.Y);
- points[1] = new PointF(startPoint.X + semiOffset, startPoint.Y);
- points[2] = new PointF(startPoint.X + semiOffset, startPoint.Y - dy);
- points[3] = new PointF(startPoint.X - 1 * e.ScaleX, startPoint.Y - dy);
- }
- else if (position == RadialGaugePosition.Right)
- {
- g.FillPie(brush, x, y, dx, dy, -90, 180);
- g.DrawArc(pen, x, y, dx, dy, -90, 180);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -180 * RAD, center)[0];
-
- points[0] = new PointF(startPoint.X + 1 * e.ScaleX, startPoint.Y);
- points[1] = new PointF(startPoint.X - semiOffset, startPoint.Y);
- points[2] = new PointF(startPoint.X - semiOffset, startPoint.Y - dy);
- points[3] = new PointF(startPoint.X + 1 * e.ScaleX, startPoint.Y - dy);
- }
- if(position != RadialGaugePosition.None)
- {
- GraphicsPath path = new GraphicsPath();
- path.AddLines(points);
- g.FillAndDrawPath(pen, brush, path);
- }
- }
- else if (type == RadialGaugeType.Quadrant)
- {
- float semiOffset = (Width / 16f / 2f + 2f) * semicircleOffsetRatio * e.ScaleY;
- if (RadialUtils.IsTop(this) && RadialUtils.IsLeft(this))
- {
- g.FillPie(brush, x, y, dx, dy, -180, 90);
- g.DrawArc(pen, x, y, dx, dy, -180, 90);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -90 * RAD, center)[0];
- PointF[] points = new PointF[5];
- points[0] = new PointF(startPoint.X, startPoint.Y - 1 * e.ScaleY);
- points[1] = new PointF(startPoint.X, startPoint.Y + semiOffset);
- points[2] = new PointF(startPoint.X + dx / 2 + semiOffset, startPoint.Y + semiOffset);
- points[3] = new PointF(startPoint.X + dx / 2 + semiOffset, y);
- points[4] = new PointF(startPoint.X + dx / 2 - 1 * e.ScaleX, y);
- GraphicsPath path = new GraphicsPath();
- path.AddLines(points);
- g.FillAndDrawPath(pen, brush, path);
- }
- else if (RadialUtils.IsBottom(this) && RadialUtils.IsLeft(this))
- {
- g.FillPie(brush, x, y, dx, dy, -270, 90);
- g.DrawArc(pen, x, y, dx, dy, -270, 90);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -90 * RAD, center)[0];
- PointF[] points = new PointF[5];
- points[0] = new PointF(startPoint.X, startPoint.Y + 1 * e.ScaleY);
- points[1] = new PointF(startPoint.X, startPoint.Y - semiOffset);
- points[2] = new PointF(startPoint.X + dx / 2 + semiOffset, startPoint.Y - semiOffset);
- points[3] = new PointF(startPoint.X + dx / 2 + semiOffset, y + dy);
- points[4] = new PointF(x + dx / 2 - 1 * e.ScaleX, y + dy);
- GraphicsPath path = new GraphicsPath();
- path.AddLines(points);
- g.FillAndDrawPath(pen, brush, path);
- }
- else if (RadialUtils.IsTop(this) && RadialUtils.IsRight(this))
- {
- g.FillPie(brush, x, y, dx, dy, -90, 90);
- g.DrawArc(pen, x, y, dx, dy, -90, 90);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 90 * RAD, center)[0];
- PointF[] points = new PointF[5];
- points[0] = new PointF(startPoint.X, startPoint.Y - 1 * e.ScaleY);
- points[1] = new PointF(startPoint.X, startPoint.Y + semiOffset);
- points[2] = new PointF(startPoint.X - dx / 2 - semiOffset, startPoint.Y + semiOffset);
- points[3] = new PointF(x + dx / 2 - semiOffset , y);
- points[4] = new PointF(x + dx / 2 + 1 * e.ScaleX, y);
- GraphicsPath path = new GraphicsPath();
- path.AddLines(points);
- g.FillAndDrawPath(pen, brush, path);
- }
- else if (RadialUtils.IsBottom(this) && RadialUtils.IsRight(this))
- {
- g.FillPie(brush, x, y, dx, dy, 0, 90);
- g.DrawArc(pen, x, y, dx, dy, 0, 90);
- PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 90 * RAD, center)[0];
- PointF[] points = new PointF[5];
- points[0] = new PointF(startPoint.X, startPoint.Y + 1 * e.ScaleY);
- points[1] = new PointF(startPoint.X, startPoint.Y - semiOffset);
- points[2] = new PointF(x + dx / 2 - semiOffset, startPoint.Y - semiOffset);
- points[3] = new PointF(x + dx / 2 - semiOffset, y + dy);
- points[4] = new PointF(x + dx / 2 + 1 * e.ScaleX, y + dy);
- GraphicsPath path = new GraphicsPath();
- path.AddLines(points);
- g.FillAndDrawPath(pen, brush, path);
- }
- }
- Scale.Draw(e);
- Pointer.Draw(e);
- Label.Draw(e);
- DrawMarkers(e);
- if (!(Fill is SolidFill))
- brush.Dispose();
- if (Report != null && Report.SmoothGraphics)
- {
- g.InterpolationMode = InterpolationMode.HighQualityBicubic;
- g.SmoothingMode = SmoothingMode.AntiAlias;
- }
- }
- /// <inheritdoc/>
- public override void Serialize(FRWriter writer)
- {
- RadialGauge c = writer.DiffObject as RadialGauge;
- base.Serialize(writer);
- if (Type != c.Type)
- {
- writer.WriteValue("Type", Type);
- }
- if (Position != c.Position)
- {
- writer.WriteValue("Position", Position);
- }
- }
- #endregion // Public Methods
- }
- }
|