98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
package chart
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
)
|
|
|
|
// Range is a type that translates values from a range to a domain.
|
|
type Range interface {
|
|
GetMin() interface{}
|
|
GetMax() interface{}
|
|
Translate(value interface{}) int
|
|
}
|
|
|
|
// NewRangeOfFloat64 returns a new Range
|
|
func NewRangeOfFloat64(domain int, values ...float64) Range {
|
|
min, max := MinAndMax(values...)
|
|
return &RangeOfFloat64{
|
|
MinValue: min,
|
|
MaxValue: max,
|
|
MinMaxDelta: max - min,
|
|
Domain: domain,
|
|
}
|
|
}
|
|
|
|
// RangeOfFloat64 represents a continuous range
|
|
// of float64 values mapped to a [0...WindowMaxValue]
|
|
// interval.
|
|
type RangeOfFloat64 struct {
|
|
MinValue float64
|
|
MaxValue float64
|
|
MinMaxDelta float64
|
|
Domain int
|
|
}
|
|
|
|
// GetMin implements the interface method.
|
|
func (r RangeOfFloat64) GetMin() interface{} {
|
|
return r.MinValue
|
|
}
|
|
|
|
// GetMax implements the interface method.
|
|
func (r RangeOfFloat64) GetMax() interface{} {
|
|
return r.MaxValue
|
|
}
|
|
|
|
// Translate maps a given value into the range space.
|
|
// An example would be a 600 px image, with a min of 10 and a max of 100.
|
|
// Translate(50) would yield (50.0/90.0)*600 ~= 333.33
|
|
func (r RangeOfFloat64) Translate(value interface{}) int {
|
|
if typedValue, isTyped := value.(float64); isTyped {
|
|
finalValue := ((r.MaxValue - typedValue) / r.MinMaxDelta) * float64(r.Domain)
|
|
return int(math.Floor(finalValue))
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// NewRangeOfTime makes a new range of time with the given time values.
|
|
func NewRangeOfTime(domain int, values ...time.Time) Range {
|
|
min, max := MinAndMaxOfTime(values...)
|
|
r := &RangeOfTime{
|
|
MinValue: min,
|
|
MaxValue: max,
|
|
MinMaxDelta: max.Unix() - min.Unix(),
|
|
Domain: domain,
|
|
}
|
|
return r
|
|
}
|
|
|
|
// RangeOfTime represents a timeseries.
|
|
type RangeOfTime struct {
|
|
MinValue time.Time
|
|
MaxValue time.Time
|
|
MinMaxDelta int64 //unix time difference
|
|
Domain int
|
|
}
|
|
|
|
// GetMin implements the interface method.
|
|
func (r RangeOfTime) GetMin() interface{} {
|
|
return r.MinValue
|
|
}
|
|
|
|
// GetMax implements the interface method.
|
|
func (r RangeOfTime) GetMax() interface{} {
|
|
return r.MaxValue
|
|
}
|
|
|
|
// Translate maps a given value into the range space (of time).
|
|
// An example would be a 600 px image, with a min of jan-01-2016 and a max of jun-01-2016.
|
|
// Translate(may-01-2016) would yield ... something.
|
|
func (r RangeOfTime) Translate(value interface{}) int {
|
|
if typed, isTyped := value.(time.Time); isTyped {
|
|
valueDelta := r.MaxValue.Unix() - typed.Unix()
|
|
finalValue := (float64(valueDelta) / float64(r.MinMaxDelta)) * float64(r.Domain)
|
|
return int(math.Floor(finalValue))
|
|
}
|
|
return 0
|
|
}
|