View difference between Paste ID: axUCjdJj and cynh0ZAD
SHOW: | | - or go back to the newest paste.
1
Imports System.Drawing.Drawing2D
2
3
'------------------
4
'Creator: aeonhack
5
'Site: elitevs.net
6
'Created: 08/18/2012
7
'Changed: 01/16/2013
8
'Version: 1.3.0
9
'------------------
10
Public Class Graph
11
    Inherits Control
12
13
    Sub New()
14
        Dim B As New Bitmap(1, 1)
15
        SG = Graphics.FromImage(B)
16
17
        GP = New GraphicsPath()
18
        _Values = New List(Of Single)
19
        _SmoothValues = New List(Of Single)
20
21
        FillColor = Color.White
22
        BorderColor = Color.Gray
23
24
        GraphFillColor = Color.FromArgb(50, Color.LightGreen)
25
        GraphBorderColor = Color.ForestGreen
26
27
        HorizontalLineColor = Color.FromArgb(238, 238, 238)
28
        VerticalLineColor = Color.FromArgb(248, 248, 248)
29
30
        DataColumnForeColor = Color.Gray
31
32
        HoverFillColor = Color.White
33
        HoverBorderColor = Color.ForestGreen
34
        HoverLineColor = Color.FromArgb(35, Color.ForestGreen)
35
36
        HoverLabelForeColor = Color.Gray
37
        HoverLabelFillColor = Color.White
38
        HoverLabelBorderColor = Color.DarkGray
39
        HoverLabelShadowColor = Color.FromArgb(35, Color.Black)
40
41
        LineGraphColor = Color.FromArgb(130, 0, 200, 255)
42
43
        SetStyle(DirectCast(139286, ControlStyles), True)
44
    End Sub
45
46
#Region " Properties "
47
48
    Private _FillColor As SolidBrush
49
    Public Property FillColor() As Color
50
        Get
51
            Return _FillColor.Color
52
        End Get
53
        Set(ByVal value As Color)
54
            _FillColor = New SolidBrush(value)
55
            Invalidate()
56
        End Set
57
    End Property
58
59
    Private _BorderColor As Pen
60
    Public Property BorderColor() As Color
61
        Get
62
            Return _BorderColor.Color
63
        End Get
64
        Set(ByVal value As Color)
65
            _BorderColor = New Pen(value)
66
            Invalidate()
67
        End Set
68
    End Property
69
70
    Private _GraphFillColor As SolidBrush
71
    Public Property GraphFillColor() As Color
72
        Get
73
            Return _GraphFillColor.Color
74
        End Get
75
        Set(ByVal value As Color)
76
            _GraphFillColor = New SolidBrush(value)
77
            Invalidate()
78
        End Set
79
    End Property
80
81
    Private _GraphBorderColor As Pen
82
    Public Property GraphBorderColor() As Color
83
        Get
84
            Return _GraphBorderColor.Color
85
        End Get
86
        Set(ByVal value As Color)
87
            _GraphBorderColor = New Pen(value)
88
            Invalidate()
89
        End Set
90
    End Property
91
92
    Private _HorizontalLineColor As Pen
93
    Public Property HorizontalLineColor() As Color
94
        Get
95
            Return _HorizontalLineColor.Color
96
        End Get
97
        Set(ByVal value As Color)
98
            _HorizontalLineColor = New Pen(value)
99
            Invalidate()
100
        End Set
101
    End Property
102
103
    Private _VerticalLineColor As Pen
104
    Public Property VerticalLineColor() As Color
105
        Get
106
            Return _VerticalLineColor.Color
107
        End Get
108
        Set(ByVal value As Color)
109
            _VerticalLineColor = New Pen(value)
110
            Invalidate()
111
        End Set
112
    End Property
113
114
    Private _DataColumnForeColor As SolidBrush
115
    Public Property DataColumnForeColor() As Color
116
        Get
117
            Return _DataColumnForeColor.Color
118
        End Get
119
        Set(ByVal value As Color)
120
            _DataColumnForeColor = New SolidBrush(value)
121
            Invalidate()
122
        End Set
123
    End Property
124
125
    Private _HoverFillColor As SolidBrush
126
    Public Property HoverFillColor() As Color
127
        Get
128
            Return _HoverFillColor.Color
129
        End Get
130
        Set(ByVal value As Color)
131
            _HoverFillColor = New SolidBrush(value)
132
            Invalidate()
133
        End Set
134
    End Property
135
136
    Private _HoverBorderColor As Pen
137
    Public Property HoverBorderColor() As Color
138
        Get
139
            Return _HoverBorderColor.Color
140
        End Get
141
        Set(ByVal value As Color)
142
            _HoverBorderColor = New Pen(value)
143
            Invalidate()
144
        End Set
145
    End Property
146
147
    Private _HoverLineColor As Pen
148
    Public Property HoverLineColor() As Color
149
        Get
150
            Return _HoverLineColor.Color
151
        End Get
152
        Set(ByVal value As Color)
153
            _HoverLineColor = New Pen(value)
154
            Invalidate()
155
        End Set
156
    End Property
157
158
    Private _HoverLabelForeColor As SolidBrush
159
    Public Property HoverLabelForeColor() As Color
160
        Get
161
            Return _HoverLabelForeColor.Color
162
        End Get
163
        Set(ByVal value As Color)
164
            _HoverLabelForeColor = New SolidBrush(value)
165
            Invalidate()
166
        End Set
167
    End Property
168
169
    Private _HoverLabelFillColor As SolidBrush
170
    Public Property HoverLabelFillColor() As Color
171
        Get
172
            Return _HoverLabelFillColor.Color
173
        End Get
174
        Set(ByVal value As Color)
175
            _HoverLabelFillColor = New SolidBrush(value)
176
            Invalidate()
177
        End Set
178
    End Property
179
180
    Private _HoverLabelBorderColor As Pen
181
    Public Property HoverLabelBorderColor() As Color
182
        Get
183
            Return _HoverLabelBorderColor.Color
184
        End Get
185
        Set(ByVal value As Color)
186
            _HoverLabelBorderColor = New Pen(value)
187
            Invalidate()
188
        End Set
189
    End Property
190
191
    Private _HoverLabelShadowColor As Pen
192
    Public Property HoverLabelShadowColor() As Color
193
        Get
194
            Return _HoverLabelShadowColor.Color
195
        End Get
196
        Set(ByVal value As Color)
197
            _HoverLabelShadowColor = New Pen(value, 2)
198
            Invalidate()
199
        End Set
200
    End Property
201
202
    Private _LineGraphColor As Pen
203
    Public Property LineGraphColor() As Color
204
        Get
205
            Return _LineGraphColor.Color
206
        End Get
207
        Set(ByVal value As Color)
208
            _LineGraphColor = New Pen(value, 6)
209
            _LineGraphColor.MiterLimit = 0.0F
210
            Invalidate()
211
        End Set
212
    End Property
213
214
    Private _DrawLineGraph As Boolean
215
    Public Property DrawLineGraph() As Boolean
216
        Get
217
            Return _DrawLineGraph
218
        End Get
219
        Set(ByVal value As Boolean)
220
            _DrawLineGraph = value
221
            Invalidate()
222
        End Set
223
    End Property
224
225
    Private _SidePadding As Boolean = True
226
    Public Property SidePadding() As Boolean
227
        Get
228
            Return _SidePadding
229
        End Get
230
        Set(ByVal value As Boolean)
231
            _SidePadding = value
232
            Invalidate()
233
        End Set
234
    End Property
235
236
    Private _DrawHoverData As Boolean = True
237
    Public Property DrawHoverData() As Boolean
238
        Get
239
            Return _DrawHoverData
240
        End Get
241
        Set(ByVal value As Boolean)
242
            Index = -1
243
            _DrawHoverData = value
244
            Invalidate()
245
        End Set
246
    End Property
247
248
    Private _DrawHoverLine As Boolean = True
249
    Public Property DrawHoverLine() As Boolean
250
        Get
251
            Return _DrawHoverLine
252
        End Get
253
        Set(ByVal value As Boolean)
254
            _DrawHoverLine = value
255
            Invalidate()
256
        End Set
257
    End Property
258
259
    Private _DrawDataColumn As Boolean = True
260
    Public Property DrawDataColumn() As Boolean
261
        Get
262
            Return _DrawDataColumn
263
        End Get
264
        Set(ByVal value As Boolean)
265
            _DrawDataColumn = value
266
            Invalidate()
267
        End Set
268
    End Property
269
270
    Private _DrawHorizontalLines As Boolean = True
271
    Public Property DrawHorizontalLines() As Boolean
272
        Get
273
            Return _DrawHorizontalLines
274
        End Get
275
        Set(ByVal value As Boolean)
276
            _DrawHorizontalLines = value
277
            Invalidate()
278
        End Set
279
    End Property
280
281
    Private _DrawVerticalLines As Boolean
282
    Public Property DrawVerticalLines() As Boolean
283
        Get
284
            Return _DrawVerticalLines
285
        End Get
286
        Set(ByVal value As Boolean)
287
            _DrawVerticalLines = value
288
            Invalidate()
289
        End Set
290
    End Property
291
292
    Private _DataSmoothing As Boolean
293
    Public Property DataSmoothing() As Boolean
294
        Get
295
            Return _DataSmoothing
296
        End Get
297
        Set(ByVal value As Boolean)
298
            _DataSmoothing = value
299
300
            InvalidateSmoothValues()
301
            FindMinMax()
302
303
            Invalidate()
304
        End Set
305
    End Property
306
307
    Private _DataSmoothingLevel As Byte = 2
308
    Public Property DataSmoothingLevel() As Byte
309
        Get
310
            Return _DataSmoothingLevel
311
        End Get
312
        Set(ByVal value As Byte)
313
            If value < 1 Then value = 1
314
315
            _DataSmoothingLevel = value
316
317
            InvalidateSmoothValues()
318
            FindMinMax()
319
320
            Invalidate()
321
        End Set
322
    End Property
323
324
    Public ReadOnly Property MaximumValue() As Single
325
        Get
326
            Return _MaximumValue
327
        End Get
328
    End Property
329
330
    Public ReadOnly Property MinimumValue() As Single
331
        Get
332
            Return _MinimumValue
333
        End Get
334
    End Property
335
336
    Private _OverrideMin As Boolean = False
337
    Public Property OverrideMin() As Boolean
338
        Get
339
            Return _OverrideMin
340
        End Get
341
        Set(ByVal value As Boolean)
342
            _OverrideMin = value
343
            If value Then InvalidateMinMax() Else FindMinMax()
344
            Invalidate()
345
        End Set
346
    End Property
347
348
    Private _OverrideMinValue As Single = 0.0F
349
    Public Property OverrideMinValue() As Single
350
        Get
351
            Return _OverrideMinValue
352
        End Get
353
        Set(ByVal value As Single)
354
            _OverrideMinValue = value
355
            InvalidateMinMax()
356
            Invalidate()
357
        End Set
358
    End Property
359
360
    Private _OverrideMax As Boolean = False
361
    Public Property OverrideMax() As Boolean
362
        Get
363
            Return _OverrideMax
364
        End Get
365
        Set(ByVal value As Boolean)
366
            _OverrideMax = value
367
            If value Then InvalidateMinMax() Else FindMinMax()
368
            Invalidate()
369
        End Set
370
    End Property
371
372
    Private _OverrideMaxValue As Single = 100.0F
373
    Public Property OverrideMaxValue() As Single
374
        Get
375
            Return _OverrideMaxValue
376
        End Get
377
        Set(ByVal value As Single)
378
            _OverrideMaxValue = value
379
            InvalidateMinMax()
380
            Invalidate()
381
        End Set
382
    End Property
383
384
    Private Sub InvalidateMinMax()
385
        If _OverrideMin Then _MinimumValue = _OverrideMinValue
386
        If _OverrideMax Then _MaximumValue = _OverrideMaxValue
387
    End Sub
388
389
    Private SS As Size
390
    Private SW, SH, SHH As Integer
391
392
    Private SG As Graphics
393
394
    Public Overrides Property Font As Font
395
        Get
396
            Return MyBase.Font
397
        End Get
398
        Set(value As Font)
399
            MyBase.Font = value
400
401
            SS = SG.MeasureString("999K", Font).ToSize()
402
            SW = SS.Width + 5
403
            SH = SS.Height + 5
404
            SHH = CInt(Math.Ceiling((SS.Height / 2) / 2) * 2)
405
406
            Invalidate()
407
        End Set
408
    End Property
409
410
#End Region
411
412
#Region " Graph Values "
413
414
    Private _MaximumValue As Single = Single.MinValue
415
    Private _MinimumValue As Single = Single.MaxValue
416
    Private CurrentValue As Single
417
418
    Private _Values As List(Of Single)
419
    Private _SmoothValues As List(Of Single)
420
421
    Public Property Values() As Single()
422
        Get
423
            Return _Values.ToArray()
424
        End Get
425
        Set(ByVal value As Single())
426
            Clear()
427
428
            AddValues(value)
429
430
            InvalidateSmoothValues()
431
            FindMinMax()
432
        End Set
433
    End Property
434
435
    Public Sub AddValue(ByVal value As Single)
436
        Index = -1
437
        _Values.Add(value)
438
439
        CleanValues()
440
441
        InvalidateSmoothValues()
442
        FindMinMax()
443
444
        Invalidate()
445
    End Sub
446
447
    Public Sub AddValues(ByVal values As Single())
448
        Index = -1
449
        _Values.AddRange(values)
450
451
        CleanValues()
452
453
        InvalidateSmoothValues()
454
        FindMinMax()
455
456
        Invalidate()
457
    End Sub
458
459
    Private Sub InvalidateSmoothValues()
460
        If Not _DataSmoothing Then Return
461
462
        _SmoothValues.Clear()
463
464
        Dim Mean As Single
465
        Dim Min, Max As Integer
466
467
        For I As Integer = 0 To _Values.Count - 1
468
            Mean = 0.0F
469
470
            Min = Math.Max(I - _DataSmoothingLevel, 0)
471
            Max = Math.Min(I + _DataSmoothingLevel, _Values.Count - 1)
472
473
            For X As Integer = Min To Max
474
                Mean += _Values(X)
475
            Next
476
477
            Mean = Mean / ((Max - Min) + 1)
478
            _SmoothValues.Add(Mean)
479
        Next
480
    End Sub
481
482
    Private Sub FindMinMax()
483
        _MaximumValue = Single.MinValue
484
        _MinimumValue = Single.MaxValue
485
486
        For I As Integer = 0 To _Values.Count - 1
487
488
            If _DataSmoothing Then
489
                CurrentValue = _SmoothValues(I)
490
            Else
491
                CurrentValue = _Values(I)
492
            End If
493
494
            If (CurrentValue > _MaximumValue) Then _MaximumValue = CurrentValue
495
            If (CurrentValue < _MinimumValue) Then _MinimumValue = CurrentValue
496
        Next
497
498
        InvalidateMinMax()
499
    End Sub
500
501
    Private Sub CleanValues()
502
        If _Values.Count > Width Then
503
            _Values.RemoveRange(0, _Values.Count - Width)
504
        End If
505
    End Sub
506
507
    Public Sub Clear()
508
        _Values.Clear()
509
        _SmoothValues.Clear()
510
511
        _MaximumValue = Single.MinValue
512
        _MinimumValue = Single.MaxValue
513
514
        InvalidateMinMax()
515
    End Sub
516
517
#End Region
518
519
    Private SB As String
520
    Private FB1, FB2 As Single
521
522
    Private G As Graphics
523
    Private GP As GraphicsPath
524
525
    Private P As Point
526
    Private PS As PointF()
527
    Private R1, R2, R3 As Rectangle
528
529
    Protected Overrides Sub OnPaint(e As PaintEventArgs)
530
        G = e.Graphics
531
        G.Clear(BackColor)
532
533
        R1 = New Rectangle(SW, 0, Width - SW, Height) 'Height - SH
534
535
        If Not _DrawDataColumn Then
536
            R1.X = 0
537
            R1.Width = Width
538
        End If
539
540
        R2 = New Rectangle(R1.X + 10, R1.Y + 10, R1.Width - 20, R1.Height - 20)
541
542
        If Not _SidePadding Then
543
            R2.X = R1.X
544
            R2.Width = R1.Width
545
        End If
546
547
        G.FillRectangle(_FillColor, R1)
548
549
        For I As Integer = 0 To 10
550
            FB1 = R2.Y + CSng((R2.Height - 1) * (I * 0.1))
551
552
            If _DrawHorizontalLines Then
553
                G.DrawLine(_HorizontalLineColor, R1.X, FB1, R1.Right - 1, FB1)
554
            End If
555
556
            If _DrawDataColumn AndAlso (_Values.Count > 1) Then
557
                If (I Mod 2 = 0) Then
558
                    G.DrawLine(_BorderColor, R1.X - 4, FB1, R1.X, FB1)
559
560
                    CurrentValue = CInt(((_MaximumValue - _MinimumValue) * (1 - (I * 0.1))) + _MinimumValue)
561
                    SB = SmallValue(CurrentValue)
562
563
                    SS = G.MeasureString(SB, Font).ToSize()
564
                    G.DrawString(SB, Font, _DataColumnForeColor, R1.X - 5 - SS.Width, FB1 - SHH)
565
                End If
566
            End If
567
        Next
568
569
        If _Values.Count > 1 Then
570
            PS = New PointF(_Values.Count + 1) {}
571
            FB1 = CSng((R2.Width - 1) / (_Values.Count - 1))
572
573
            For I As Integer = 0 To _Values.Count - 1
574
                FB2 = R2.X + (I * FB1)
575
576
                If _DataSmoothing Then
577
                    CurrentValue = (_SmoothValues(I) - _MinimumValue) / Math.Max(_MaximumValue - _MinimumValue, 1)
578
                Else
579
                    CurrentValue = (_Values(I) - _MinimumValue) / Math.Max(_MaximumValue - _MinimumValue, 1)
580
                End If
581
582
                If CurrentValue > 1 Then
583
                    CurrentValue = 1
584
                ElseIf CurrentValue < 0 Then
585
                    CurrentValue = 0
586
                End If
587
588
                PS(I) = New PointF(FB2, CInt(R2.Bottom - ((R2.Height - 1) * CurrentValue) - 1))
589
590
                If _DrawVerticalLines Then
591
                    G.DrawLine(_VerticalLineColor, FB2, R1.Y, FB2, R1.Bottom)
592
                End If
593
            Next
594
595
            PS(PS.Length - 2) = New PointF(R2.Right - 1, R1.Bottom - 1)
596
            PS(PS.Length - 1) = New PointF(R2.X, R1.Bottom - 1)
597
598
            G.SmoothingMode = SmoothingMode.HighQuality
599
600
            If _DrawLineGraph Then
601
                Array.Resize(PS, PS.Length - 2)
602
                G.DrawLines(_LineGraphColor, PS)
603
            Else
604
                GP.AddPolygon(PS)
605
                GP.CloseFigure()
606
607
                G.FillPath(_GraphFillColor, GP)
608
                G.DrawPath(_GraphBorderColor, GP)
609
                GP.Reset()
610
            End If
611
612
            If _DrawHoverData AndAlso Not (Index < 0) Then
613
                G.SetClip(R1)
614
615
                P = New Point(CInt(PS(Index).X), CInt(PS(Index).Y))
616
                R3 = New Rectangle(P.X - 4, P.Y - 4, 8, 8)
617
618
                If _DrawHoverLine Then
619
                    G.DrawLine(_HoverLineColor, P.X, R1.Y, P.X, R1.Bottom - 1)
620
                End If
621
622
                G.FillEllipse(_HoverFillColor, R3)
623
                G.DrawEllipse(_HoverBorderColor, R3)
624
625
                If _DataSmoothing Then
626
                    SB = _SmoothValues(Index).ToString("N0")
627
                Else
628
                    SB = _Values(Index).ToString("N0")
629
                End If
630
631
                SS = G.MeasureString(SB, Font).ToSize()
632
633
                P = PointToClient(MousePosition)
634
635
                R3 = New Rectangle(P.X + 24, P.Y, SS.Width + 20, SS.Height + 10)
636
                If (R3.X + R3.Width) > (R1.Right - 1) Then R3.X = P.X - R3.Width - 16
637
                If (R3.Y + R3.Height) > (R1.Bottom - 1) Then R3.Y = R1.Bottom - R3.Height - 1
638
639
                G.DrawRectangle(_HoverLabelShadowColor, R3)
640
                G.FillRectangle(_HoverLabelFillColor, R3)
641
                G.DrawRectangle(_HoverLabelBorderColor, R3)
642
643
                G.DrawString(SB, Font, _HoverLabelForeColor, New Point(R3.X + 10, R3.Y + 5))
644
            End If
645
646
            G.ResetClip()
647
            G.SmoothingMode = SmoothingMode.None
648
        End If
649
650
        G.DrawRectangle(_BorderColor, R1.X, R1.Y, R1.Width - 1, R1.Height - 1)
651
    End Sub
652
653
    Private Function SmallValue(value As Single) As String
654
        Dim R As Integer = CInt(value)
655
656
        Select Case R
657
            Case Is >= 1000000000
658
                Return (R \ 1000000000) & "B"
659
            Case Is >= 1000000
660
                Return (R \ 1000000) & "M"
661
            Case Is >= 1000
662
                Return (R \ 1000) & "K"
663
            Case Else
664
                Return CStr(R)
665
        End Select
666
    End Function
667
668
#Region " Hover Handler "
669
670
    Private Index As Integer = -1
671
    Private LastMove As Date
672
673
    Protected Overrides Sub OnMouseMove(e As MouseEventArgs)
674
        If Not _DrawHoverData Then Return
675
676
        R1 = New Rectangle(SW, 0, Width - SW, Height - SH)
677
        R2 = New Rectangle(R1.X + 8, R1.Y + 8, R1.Width - 16, R1.Height - 16)
678
679
        FB1 = CSng((R2.Width - 1) / (_Values.Count - 1))
680
681
        If R1.Contains(e.Location) Then
682
            Index = CInt((e.X - R2.X) / FB1)
683
            If Not Index < _Values.Count Then Index = -1
684
        Else
685
            Index = -1
686
        End If
687
688
        If Date.Now > LastMove.AddMilliseconds(33) Then
689
            LastMove = Date.Now
690
            Invalidate()
691
        End If
692
    End Sub
693
694
    Protected Overrides Sub OnMouseLeave(e As EventArgs)
695
        If Not _DrawHoverData Then Return
696
697
        Index = -1
698
        Invalidate()
699
    End Sub
700
701
#End Region
702
703
End Class