forked from beevee/go-chart
-
Notifications
You must be signed in to change notification settings - Fork 1
/
min_max_series.go
138 lines (117 loc) · 3.03 KB
/
min_max_series.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package chart
import (
"fmt"
"math"
)
// MinSeries draws a horizontal line at the minimum value of the inner series.
type MinSeries struct {
Name string
Style Style
YAxis YAxisType
InnerSeries ValuesProvider
minValue *float64
}
// GetName returns the name of the time series.
func (ms MinSeries) GetName() string {
return ms.Name
}
// GetStyle returns the line style.
func (ms MinSeries) GetStyle() Style {
return ms.Style
}
// GetYAxis returns which YAxis the series draws on.
func (ms MinSeries) GetYAxis() YAxisType {
return ms.YAxis
}
// Len returns the number of elements in the series.
func (ms MinSeries) Len() int {
return ms.InnerSeries.Len()
}
// GetValues gets a value at a given index.
func (ms *MinSeries) GetValues(index int) (x, y float64) {
ms.ensureMinValue()
x, _ = ms.InnerSeries.GetValues(index)
y = *ms.minValue
return
}
// Render renders the series.
func (ms *MinSeries) Render(r Renderer, canvasBox Box, xrange, yrange Range, defaults Style) {
style := ms.Style.InheritFrom(defaults)
Draw.LineSeries(r, canvasBox, xrange, yrange, style, ms)
}
func (ms *MinSeries) ensureMinValue() {
if ms.minValue == nil {
minValue := math.MaxFloat64
var y float64
for x := 0; x < ms.InnerSeries.Len(); x++ {
_, y = ms.InnerSeries.GetValues(x)
if y < minValue {
minValue = y
}
}
ms.minValue = &minValue
}
}
// Validate validates the series.
func (ms *MinSeries) Validate() error {
if ms.InnerSeries == nil {
return fmt.Errorf("min series requires InnerSeries to be set")
}
return nil
}
// MaxSeries draws a horizontal line at the maximum value of the inner series.
type MaxSeries struct {
Name string
Style Style
YAxis YAxisType
InnerSeries ValuesProvider
maxValue *float64
}
// GetName returns the name of the time series.
func (ms MaxSeries) GetName() string {
return ms.Name
}
// GetStyle returns the line style.
func (ms MaxSeries) GetStyle() Style {
return ms.Style
}
// GetYAxis returns which YAxis the series draws on.
func (ms MaxSeries) GetYAxis() YAxisType {
return ms.YAxis
}
// Len returns the number of elements in the series.
func (ms MaxSeries) Len() int {
return ms.InnerSeries.Len()
}
// GetValues gets a value at a given index.
func (ms *MaxSeries) GetValues(index int) (x, y float64) {
ms.ensureMaxValue()
x, _ = ms.InnerSeries.GetValues(index)
y = *ms.maxValue
return
}
// Render renders the series.
func (ms *MaxSeries) Render(r Renderer, canvasBox Box, xrange, yrange Range, defaults Style) {
style := ms.Style.InheritFrom(defaults)
Draw.LineSeries(r, canvasBox, xrange, yrange, style, ms)
}
func (ms *MaxSeries) ensureMaxValue() {
if ms.maxValue == nil {
maxValue := -math.MaxFloat64
var y float64
for x := 0; x < ms.InnerSeries.Len(); x++ {
_, y = ms.InnerSeries.GetValues(x)
if y > maxValue {
maxValue = y
}
}
ms.maxValue = &maxValue
}
}
// Validate validates the series.
func (ms *MaxSeries) Validate() error {
if ms.InnerSeries == nil {
return fmt.Errorf("max series requires InnerSeries to be set")
}
return nil
}