go-chart/range.go
2016-07-06 18:54:00 -07:00

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
}