go-chart/min_max_series.go

139 lines
3.0 KiB
Go

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
}