FastReport

Форк
0
442 строки · 17.1 Кб
1
using System;
2
using System.ComponentModel;
3
using System.Drawing;
4
using System.Drawing.Design;
5
using System.Drawing.Drawing2D;
6
using FastReport.Utils;
7

8
namespace FastReport.Gauge.Radial
9
{
10
    #region Enums
11

12
    /// <summary>
13
    /// Radial Gauge types
14
    /// </summary>
15
    [Flags]
16
    public enum RadialGaugeType
17
    {
18
        /// <summary>
19
        /// Full sized gauge
20
        /// </summary>
21
        Circle = 1,
22

23
        /// <summary>
24
        /// Half of the radial gauge
25
        /// </summary>
26
        Semicircle = 2,
27

28
        /// <summary>
29
        /// Quarter of the radial gauge
30
        /// </summary>
31
        Quadrant = 4
32
    }
33

34
    /// <summary>
35
    /// Radial Gauge position types
36
    /// </summary>
37
    [Flags]
38
    [TypeConverter(typeof(FastReport.TypeConverters.FlagConverter))]
39
    public enum RadialGaugePosition
40
    {
41
        /// <summary>
42
        /// None
43
        /// </summary>
44
        None = 0,
45

46
        /// <summary>
47
        /// Top
48
        /// </summary>
49
        Top = 1,
50

51
        /// <summary>
52
        /// Bottom
53
        /// </summary>
54
        Bottom = 2,
55

56
        /// <summary>
57
        /// Left
58
        /// </summary>
59
        Left = 4,
60

61
        /// <summary>
62
        /// Right
63
        /// </summary>
64
        Right = 8
65
    }
66

67
    #endregion // Enums
68

69
    /// <summary>
70
    /// Represents a linear gauge.
71
    /// </summary>
72
    public partial class RadialGauge : GaugeObject
73
    {
74
        private const double RAD = Math.PI / 180.0;
75
        private PointF center;
76
        private RadialGaugeType type;
77
        private RadialGaugePosition position;
78
        private float semicircleOffsetRatio;
79

80
        #region Properties
81
        /// <inheritdoc/>
82
        public override float Width
83
        {
84
            get { return base.Width; }
85
            set
86
            {
87
                base.Width = value;
88
                if (base.Height != base.Width)
89
                {
90
                    base.Height = Width;
91
                }
92
            }
93
        }
94

95
        /// <inheritdoc/>
96
        public override float Height
97
        {
98
            get { return base.Height; }
99
            set
100
            {
101
                base.Height = value;
102
                if (base.Width != base.Height)
103
                {
104
                    base.Width = Height;
105
                }
106
            }
107
        }
108

109
        /// <summary>
110
        /// Returns centr of the gauge
111
        /// </summary>
112
        [Browsable(false)]
113
        public PointF Center
114
        {
115
            get { return center; }
116
            set { center = value; }
117
        }
118

119
        /// <summary>
120
        /// The number of radians in one degree
121
        /// </summary>
122
        public static double Radians
123
        {
124
            get { return RAD; }
125
        }
126

127
        /// <summary>
128
        /// Gets or sets the Radial Gauge type
129
        /// </summary>
130
        [Browsable(true)]
131
        [Category("Appearance")]
132
        public RadialGaugeType Type
133
        {
134
            get { return type; }
135
            set
136
            {
137
                if (value == RadialGaugeType.Circle)
138
                {
139
                    position = RadialGaugePosition.None;
140
                    type = value;
141
                }
142
                if (value == RadialGaugeType.Semicircle &&
143
                    !(Position == RadialGaugePosition.Bottom ||
144
                    Position == RadialGaugePosition.Left ||
145
                    Position == RadialGaugePosition.Right ||
146
                    Position == RadialGaugePosition.Top))
147
                {
148
                    position = RadialGaugePosition.Top;
149
                    type = value;
150
                }
151
                else if (value == RadialGaugeType.Quadrant &&
152
                    !(
153
                    ((Position & RadialGaugePosition.Left) != 0 && (Position & RadialGaugePosition.Top) != 0 &&
154
                    (Position & RadialGaugePosition.Right) == 0 && (Position & RadialGaugePosition.Bottom) == 0) ||
155

156
                    ((Position & RadialGaugePosition.Right) != 0 && (Position & RadialGaugePosition.Top) != 0 &&
157
                    (Position & RadialGaugePosition.Left) == 0 && (Position & RadialGaugePosition.Bottom) == 0) ||
158

159
                    ((Position & RadialGaugePosition.Left) != 0 && (Position & RadialGaugePosition.Bottom) != 0 &&
160
                    (Position & RadialGaugePosition.Right) == 0 && (Position & RadialGaugePosition.Top) == 0) ||
161

162
                    ((Position & RadialGaugePosition.Right) != 0 && (Position & RadialGaugePosition.Bottom) != 0 &&
163
                    (Position & RadialGaugePosition.Left) == 0 && (Position & RadialGaugePosition.Top) == 0)
164
                    ))
165
                {
166
                    position = RadialGaugePosition.Top | RadialGaugePosition.Left;
167
                    type = value;
168
                }
169

170
            }
171
        }
172

173
        /// <summary>
174
        /// Gats or sets the Radial Gauge position. Doesn't work for Full Radial Gauge.
175
        /// </summary>
176
        [Category("Appearance")]
177
        [Editor("FastReport.TypeEditors.FlagsEditor, FastReport", typeof(UITypeEditor))]
178
        public RadialGaugePosition Position
179
        {
180
            get { return position; }
181
            set
182
            {
183
                if (Type == RadialGaugeType.Semicircle &&
184
                    (value == RadialGaugePosition.Bottom ||
185
                    value == RadialGaugePosition.Left ||
186
                    value == RadialGaugePosition.Right ||
187
                    value == RadialGaugePosition.Top))
188
                    position = value;
189
                else if (Type == RadialGaugeType.Quadrant &&
190
                    (
191
                    ((value & RadialGaugePosition.Left) != 0 && (value & RadialGaugePosition.Top) != 0 &&
192
                    (value & RadialGaugePosition.Right) == 0 && (value & RadialGaugePosition.Bottom) == 0) ||
193

194
                    ((value & RadialGaugePosition.Right) != 0 && (value & RadialGaugePosition.Top) != 0 &&
195
                    (value & RadialGaugePosition.Left) == 0 && (value & RadialGaugePosition.Bottom) == 0) ||
196

197
                    ((value & RadialGaugePosition.Left) != 0 && (value & RadialGaugePosition.Bottom) != 0 &&
198
                    (value & RadialGaugePosition.Right) == 0 && (value & RadialGaugePosition.Top) == 0) ||
199

200
                    ((value & RadialGaugePosition.Right) != 0 && (value & RadialGaugePosition.Bottom) != 0 &&
201
                    (value & RadialGaugePosition.Left) == 0 && (value & RadialGaugePosition.Top) == 0)
202
                    ))
203
                    position = value;
204
                else if (Type == RadialGaugeType.Circle)
205
                    position = 0;
206

207
            }
208
        }
209

210
        /// <summary>
211
        /// Gets or sets the semicircles offset
212
        /// </summary>
213
        [Category("Appearance")]
214
        public float SemicircleOffsetRatio
215
        {
216
            get { return semicircleOffsetRatio; }
217
            set { semicircleOffsetRatio = value; }
218
        }
219
        #endregion // Properties
220

221
        #region Constructors
222

223
        /// <summary>
224
        /// Initializes a new instance of the <see cref="RadialGauge"/> class.
225
        /// </summary>
226
        public RadialGauge() : base()
227
        {
228
            InitializeComponent();
229
            Scale = new RadialScale(this);
230
            Pointer = new RadialPointer(this, Scale as RadialScale);
231
            Label = new RadialLabel(this);
232
            Height = 4.0f * Units.Centimeters;
233
            Width = 4.0f * Units.Centimeters;
234
            semicircleOffsetRatio = type == RadialGaugeType.Semicircle &&
235
                (position == RadialGaugePosition.Left || position == RadialGaugePosition.Right) ? 1.5f : 1;
236
            Type = RadialGaugeType.Circle;
237
            Border.Lines = BorderLines.None;
238
        }
239

240
        #endregion // Constructor
241

242
        #region Public Methods
243

244
        /// <inheritdoc/>
245
        public override void Assign(Base source)
246
        {
247
            base.Assign(source);
248
            RadialGauge src = source as RadialGauge;
249
            Type = src.Type;
250
            Position = src.Position;
251
        }
252

253
        /// <inheritdoc/>
254
        public override void Draw(FRPaintEventArgs e)
255
        {
256
            IGraphics g = e.Graphics;
257

258
            float x = (AbsLeft + Border.Width / 2) * e.ScaleX;
259
            float y = (AbsTop + Border.Width / 2) * e.ScaleY;
260
            float dx = (Width - Border.Width) * e.ScaleX - 1;
261
            float dy = (Height - Border.Width) * e.ScaleY - 1;
262
            float x1 = x + dx;
263
            float y1 = y + dy;
264

265
            Pen pen = e.Cache.GetPen(Border.Color, Border.Width * e.ScaleX, Border.DashStyle);
266
            Brush brush;
267
            if (Fill is SolidFill)
268
                brush = e.Cache.GetBrush((Fill as SolidFill).Color);
269
            else
270
                brush = Fill.CreateBrush(new RectangleF(x, y, dx, dy), e.ScaleX, e.ScaleY);
271

272
            center = new PointF(x + dx / 2, y + dy / 2);
273

274
            if (type == RadialGaugeType.Circle)
275
            {
276
                g.FillAndDrawEllipse(pen, brush, x, y, dx, dy);
277
            }
278
            else if (type == RadialGaugeType.Semicircle)
279
            {
280
                float semiOffset = (Width / 16f / 2f + 2f) * semicircleOffsetRatio * e.ScaleY;
281
                PointF[] points = new PointF[4];
282
                if (position == RadialGaugePosition.Top)
283
                {
284
                    g.FillPie(brush, x, y, dx, dy, -180, 180);
285
                    g.DrawArc(pen, x, y, dx, dy, -180, 180);
286

287
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -90 * RAD, center)[0];
288

289
                    points[0] = new PointF(startPoint.X, startPoint.Y - 1 * e.ScaleY);
290
                    points[1] = new PointF(startPoint.X, startPoint.Y + semiOffset);
291
                    points[2] = new PointF(startPoint.X + dx, startPoint.Y + semiOffset);
292
                    points[3] = new PointF(startPoint.X + dx, startPoint.Y - 1 * e.ScaleY);
293
                }
294
                else if (position == RadialGaugePosition.Bottom)
295
                {
296
                    g.FillPie(brush, x, y, dx, dy, 0, 180);
297
                    g.DrawArc(pen, x, y, dx, dy, 0, 180);
298

299
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 90 * RAD, center)[0];
300

301
                    points[0] = new PointF(startPoint.X, startPoint.Y + 1 * e.ScaleY);
302
                    points[1] = new PointF(startPoint.X, startPoint.Y - semiOffset);
303
                    points[2] = new PointF(startPoint.X - dx, startPoint.Y - semiOffset);
304
                    points[3] = new PointF(startPoint.X - dx, startPoint.Y + 1 * e.ScaleY);
305
                }
306
                else if (position == RadialGaugePosition.Left)
307
                {
308
                    g.FillPie(brush, x, y, dx, dy, 90, 180);
309
                    g.DrawArc(pen, x, y, dx, dy, 90, 180);
310

311
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 180 * RAD, center)[0];
312

313
                    points[0] = new PointF(startPoint.X - 1 * e.ScaleX, startPoint.Y);
314
                    points[1] = new PointF(startPoint.X + semiOffset, startPoint.Y);
315
                    points[2] = new PointF(startPoint.X + semiOffset, startPoint.Y - dy);
316
                    points[3] = new PointF(startPoint.X - 1 * e.ScaleX, startPoint.Y - dy);
317
                }
318
                else if (position == RadialGaugePosition.Right)
319
                {
320
                    g.FillPie(brush, x, y, dx, dy, -90, 180);
321
                    g.DrawArc(pen, x, y, dx, dy, -90, 180);
322

323
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -180 * RAD, center)[0];
324

325
                    points[0] = new PointF(startPoint.X + 1 * e.ScaleX, startPoint.Y);
326
                    points[1] = new PointF(startPoint.X - semiOffset, startPoint.Y);
327
                    points[2] = new PointF(startPoint.X - semiOffset, startPoint.Y - dy);
328
                    points[3] = new PointF(startPoint.X + 1 * e.ScaleX, startPoint.Y - dy);
329
                }
330

331
                if (position != RadialGaugePosition.None)
332
                {
333
                    GraphicsPath path = new GraphicsPath();
334
                    path.AddLines(points);
335
                    g.FillAndDrawPath(pen, brush, path);
336
                }
337
            }
338
            else if (type == RadialGaugeType.Quadrant)
339
            {
340
                float semiOffset = (Width / 16f / 2f + 2f) * semicircleOffsetRatio * e.ScaleY;
341
                if (RadialUtils.IsTop(this) && RadialUtils.IsLeft(this))
342
                {
343
                    g.FillPie(brush, x, y, dx, dy, -180, 90);
344
                    g.DrawArc(pen, x, y, dx, dy, -180, 90);
345

346
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -90 * RAD, center)[0];
347

348
                    PointF[] points = new PointF[5];
349
                    points[0] = new PointF(startPoint.X, startPoint.Y - 1 * e.ScaleY);
350
                    points[1] = new PointF(startPoint.X, startPoint.Y + semiOffset);
351
                    points[2] = new PointF(startPoint.X + dx / 2 + semiOffset, startPoint.Y + semiOffset);
352
                    points[3] = new PointF(startPoint.X + dx / 2 + semiOffset, y);
353
                    points[4] = new PointF(startPoint.X + dx / 2 - 1 * e.ScaleX, y);
354
                    GraphicsPath path = new GraphicsPath();
355
                    path.AddLines(points);
356
                    g.FillAndDrawPath(pen, brush, path);
357

358
                }
359
                else if (RadialUtils.IsBottom(this) && RadialUtils.IsLeft(this))
360
                {
361

362
                    g.FillPie(brush, x, y, dx, dy, -270, 90);
363
                    g.DrawArc(pen, x, y, dx, dy, -270, 90);
364

365
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, -90 * RAD, center)[0];
366
                    PointF[] points = new PointF[5];
367
                    points[0] = new PointF(startPoint.X, startPoint.Y + 1 * e.ScaleY);
368
                    points[1] = new PointF(startPoint.X, startPoint.Y - semiOffset);
369
                    points[2] = new PointF(startPoint.X + dx / 2 + semiOffset, startPoint.Y - semiOffset);
370
                    points[3] = new PointF(startPoint.X + dx / 2 + semiOffset, y + dy);
371
                    points[4] = new PointF(x + dx / 2 - 1 * e.ScaleX, y + dy);
372
                    GraphicsPath path = new GraphicsPath();
373
                    path.AddLines(points);
374
                    g.FillAndDrawPath(pen, brush, path);
375
                }
376
                else if (RadialUtils.IsTop(this) && RadialUtils.IsRight(this))
377
                {
378
                    g.FillPie(brush, x, y, dx, dy, -90, 90);
379
                    g.DrawArc(pen, x, y, dx, dy, -90, 90);
380

381
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 90 * RAD, center)[0];
382

383
                    PointF[] points = new PointF[5];
384
                    points[0] = new PointF(startPoint.X, startPoint.Y - 1 * e.ScaleY);
385
                    points[1] = new PointF(startPoint.X, startPoint.Y + semiOffset);
386
                    points[2] = new PointF(startPoint.X - dx / 2 - semiOffset, startPoint.Y + semiOffset);
387
                    points[3] = new PointF(x + dx / 2 - semiOffset, y);
388
                    points[4] = new PointF(x + dx / 2 + 1 * e.ScaleX, y);
389
                    GraphicsPath path = new GraphicsPath();
390
                    path.AddLines(points);
391
                    g.FillAndDrawPath(pen, brush, path);
392
                }
393
                else if (RadialUtils.IsBottom(this) && RadialUtils.IsRight(this))
394
                {
395
                    g.FillPie(brush, x, y, dx, dy, 0, 90);
396
                    g.DrawArc(pen, x, y, dx, dy, 0, 90);
397

398
                    PointF startPoint = RadialUtils.RotateVector(new PointF[] { new PointF(x + dx / 2, y), center }, 90 * RAD, center)[0];
399

400
                    PointF[] points = new PointF[5];
401
                    points[0] = new PointF(startPoint.X, startPoint.Y + 1 * e.ScaleY);
402
                    points[1] = new PointF(startPoint.X, startPoint.Y - semiOffset);
403
                    points[2] = new PointF(x + dx / 2 - semiOffset, startPoint.Y - semiOffset);
404
                    points[3] = new PointF(x + dx / 2 - semiOffset, y + dy);
405
                    points[4] = new PointF(x + dx / 2 + 1 * e.ScaleX, y + dy);
406
                    GraphicsPath path = new GraphicsPath();
407
                    path.AddLines(points);
408
                    g.FillAndDrawPath(pen, brush, path);
409
                }
410
            }
411

412
            Scale.Draw(e);
413
            Pointer.Draw(e);
414
            Label.Draw(e);
415
            DrawMarkers(e);
416
            if (!(Fill is SolidFill))
417
                brush.Dispose();
418
            if (Report != null && Report.SmoothGraphics)
419
            {
420
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
421
                g.SmoothingMode = SmoothingMode.AntiAlias;
422
            }
423
        }
424

425
        /// <inheritdoc/>
426
        public override void Serialize(FRWriter writer)
427
        {
428
            RadialGauge c = writer.DiffObject as RadialGauge;
429
            base.Serialize(writer);
430
            if (Type != c.Type)
431
            {
432
                writer.WriteValue("Type", Type);
433
            }
434
            if (Position != c.Position)
435
            {
436
                writer.WriteValue("Position", Position);
437
            }
438
        }
439

440
        #endregion // Public Methods
441
    }
442
}
443

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.