Documentation ¶
Overview ¶
timeseries provides tools for adding and formatting static time series data for reporting purposes.
Index ¶
- func ParseTimeFuncMonthYear(s string) (time.Time, error)
- func ParseTimeFuncRFC3339(s string) (time.Time, error)
- func ParseTimeFuncYearDotMonth(s string) (time.Time, error)
- func ReportAxisX(set TimeSeriesSet, cols int, conv func(time.Time) string) []string
- func TimeFormatNiceMonth(dt time.Time) string
- func TimeFormatNiceQuarter(dt time.Time) string
- func TimeFormatRFC3339(dt time.Time) string
- func TimeSeriesMapMinMaxTimes(tsm map[string]TimeSeries) (time.Time, time.Time, error)
- func TimeSeriesMapMinMaxValues(tsm map[string]TimeSeries) (int64, int64, error)
- func TimeSeriesSliceNames(tsSlice []TimeSeries) []string
- func TimeSeriesSliceTable(tsSlice []TimeSeries) table.Table
- func TimeSeriesSliceTimes(tsSlice []TimeSeries) []string
- func TimeSeriesSliceWriteXLSX(filename string, tsSlice []TimeSeries) error
- type RowFloat64
- type RowInt64
- type TableConfig
- type TableMonthXOXOpts
- type TimeItem
- type TimeSeries
- func (ts *TimeSeries) AddFloat64(dt time.Time, value float64)
- func (ts *TimeSeries) AddInt64(dt time.Time, value int64)
- func (ts *TimeSeries) AddItems(items ...TimeItem)
- func (ts *TimeSeries) ConvertFloat64()
- func (ts *TimeSeries) ConvertInt64()
- func (ts *TimeSeries) DeleteTime(dt time.Time)
- func (ts *TimeSeries) Get(dt time.Time) (TimeItem, error)
- func (ts *TimeSeries) ItemTimes() []time.Time
- func (ts *TimeSeries) ItemsSorted() []TimeItem
- func (ts *TimeSeries) Keys() []string
- func (ts *TimeSeries) Last() (TimeItem, error)
- func (ts *TimeSeries) LastItem(skipIfTimePartialValueLessPrev bool) (TimeItem, error)
- func (ts *TimeSeries) LinearRegressionYear() (alpha, beta float64, err error)
- func (ts *TimeSeries) LinearRegressionYearProjection(years uint, constantYOY bool) error
- func (ts *TimeSeries) MaxValue() int64
- func (ts *TimeSeries) MinMaxTimes() (time.Time, time.Time)
- func (ts *TimeSeries) MinMaxValues() (int64, int64)
- func (ts *TimeSeries) MinMaxValuesFloat64() (float64, float64)
- func (ts *TimeSeries) MinValue() int64
- func (ts *TimeSeries) OneItemMaxValue() (TimeItem, error)
- func (ts *TimeSeries) Pop() (TimeItem, error)
- func (ts *TimeSeries) SetSeriesName(seriesName string)
- func (ts *TimeSeries) Stats() point.PointSet
- func (ts *TimeSeries) Table(tableName, dateColumnName, countColumnName string, ...) table.Table
- func (ts *TimeSeries) TableMonthXOX(timeFmtColName, seriesName, valuesName, yoyName, qoqName, momName string, ...) table.Table
- func (ts *TimeSeries) TableYearYOY(seriesName, valuesName, yoyName string) table.Table
- func (ts *TimeSeries) TimeSeries(interval timeutil.Interval) []time.Time
- func (ts *TimeSeries) TimeSeriesMonthMOM() TimeSeries
- func (ts *TimeSeries) TimeSeriesMonthQOQ() TimeSeries
- func (ts *TimeSeries) TimeSeriesMonthXOX(years, months, days int, suffix string) TimeSeries
- func (ts *TimeSeries) TimeSeriesMonthYOY() TimeSeries
- func (ts *TimeSeries) TimeSeriesYearYOY(suffix string) (TimeSeries, error)
- func (ts *TimeSeries) TimeSlice(sortSlice bool) timeslice.TimeSlice
- func (ts *TimeSeries) ToMonth(inflate bool, monthsFilter ...time.Month) TimeSeries
- func (ts *TimeSeries) ToMonthCumulative(inflate bool, timesInput ...time.Time) (TimeSeries, error)
- func (ts *TimeSeries) ToQuarter() TimeSeries
- func (ts *TimeSeries) ToYear() TimeSeries
- func (ts *TimeSeries) WriteJSON(filename string, perm os.FileMode, prefix, indent string) error
- func (ts *TimeSeries) WriteXLSX(filename string, sheetName, dateColumnName, countColumnName string) error
- type TimeSeriesFunnel
- type TimeSeriesSet
- func NewTimeSeriesSet(name string) TimeSeriesSet
- func ParseTableTimeSeriesSetFlat(tbl table.Table, timeColIdx, seriesNameColIdx, countColIdx uint, isFloat bool, ...) (TimeSeriesSet, error)
- func ParseTableTimeSeriesSetMatrix(tbl table.Table, isFloat bool, timeParseFunc func(s string) (time.Time, error)) (TimeSeriesSet, error)
- func ReadFileTimeSeriesSet(filename string) (TimeSeriesSet, error)
- func (set *TimeSeriesSet) AddFloat64(seriesName string, dt time.Time, value float64)
- func (set *TimeSeriesSet) AddInt64(seriesName string, dt time.Time, value int64)
- func (set *TimeSeriesSet) AddItems(items ...TimeItem)
- func (set *TimeSeriesSet) AddSeries(timeSeries ...TimeSeries) error
- func (set *TimeSeriesSet) DeleteTime(dt time.Time)
- func (set *TimeSeriesSet) GetSeriesByIndex(index int) (TimeSeries, error)
- func (set *TimeSeriesSet) Inflate()
- func (set *TimeSeriesSet) Item(seriesName, rfc3339 string) (TimeItem, error)
- func (set *TimeSeriesSet) LinearRegressionYearProjection(years uint, constantYOY bool) error
- func (set *TimeSeriesSet) MinMaxTimes() (time.Time, time.Time)
- func (set *TimeSeriesSet) MinMaxValues() (int64, int64)
- func (set *TimeSeriesSet) MinMaxValuesFloat64() (float64, float64)
- func (set *TimeSeriesSet) PopLast()
- func (set *TimeSeriesSet) SeriesNames() []string
- func (set *TimeSeriesSet) Table(opts *TimeSeriesSetTableOpts) (table.Table, error)
- func (set *TimeSeriesSet) TableYearYOY(seriesColName, valuesSuffix, yoySuffix string) table.Table
- func (set *TimeSeriesSet) TimeSlice(sortAsc bool) timeslice.TimeSlice
- func (set *TimeSeriesSet) TimeStrings() []string
- func (set *TimeSeriesSet) ToMonth(cumulative, inflate, popLast bool, monthsFilter []time.Month) (TimeSeriesSet, error)
- func (set *TimeSeriesSet) ToNewSeriesNames(seriesNames, seriesSetNames map[string]string) TimeSeriesSet
- func (set *TimeSeriesSet) ToSetTimesRangeUpper(inclusive bool, times ...time.Time) (TimeSeriesSet, error)
- func (set *TimeSeriesSet) ToYear(inflate, popLast bool) (TimeSeriesSet, error)
- func (set *TimeSeriesSet) WriteJSON(filename string, perm os.FileMode, prefix, indent string) error
- func (set *TimeSeriesSet) WriteXLSX(filename string, opts *TimeSeriesSetTableOpts) error
- type TimeSeriesSetTableOpts
- type TimeSeriesSets
- type TimeSeriesSimple
- type TimeStats
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseTimeFuncMonthYear ¶ added in v2.3.0
func ParseTimeFuncYearDotMonth ¶ added in v2.4.2
func ReportAxisX ¶
ReportAxisX generates data for use with `C3Chart.C3Axis.C3AxisX.Categories`.
func TimeFormatNiceMonth ¶
func TimeFormatNiceQuarter ¶
func TimeFormatRFC3339 ¶
func TimeSeriesMapMinMaxValues ¶
func TimeSeriesMapMinMaxValues(tsm map[string]TimeSeries) (int64, int64, error)
func TimeSeriesSliceNames ¶
func TimeSeriesSliceNames(tsSlice []TimeSeries) []string
func TimeSeriesSliceTable ¶
func TimeSeriesSliceTable(tsSlice []TimeSeries) table.Table
func TimeSeriesSliceTimes ¶
func TimeSeriesSliceTimes(tsSlice []TimeSeries) []string
func TimeSeriesSliceWriteXLSX ¶
func TimeSeriesSliceWriteXLSX(filename string, tsSlice []TimeSeries) error
TimeSeries writes a slice of TimeSeries to an Excel XLSX file for easy consumption.
Types ¶
type RowFloat64 ¶
func ReportFunnelPct ¶
func ReportFunnelPct(rows []RowInt64) []RowFloat64
func ReportGrowthPct ¶
func ReportGrowthPct(rows []RowInt64) []RowFloat64
type RowInt64 ¶
type RowInt64 struct { Name string DisplayName string HavePlusOne bool ValuePlusOne int64 Values []int64 }
type TableConfig ¶
type TableConfig struct { CountColIdx uint TimeColIdx uint TimeFormat string SeriesSetNameColIdx int // optional. Set < 0 to discard. SeriesNameColIdx int Interval timeutil.Interval }
func (*TableConfig) GetTimeFormat ¶
func (cfg *TableConfig) GetTimeFormat() string
type TableMonthXOXOpts ¶ added in v2.6.0
type TimeItem ¶
type TimeItem struct { SeriesName string SeriesSetName string Time time.Time IsFloat bool Value int64 ValueFloat float64 }
func ParseRecordsTimeItems ¶
func ParseRecordsTimeItems(records [][]string, cfg TableConfig) ([]TimeItem, error)
type TimeSeries ¶
type TimeSeries struct { SeriesName string SeriesSetName string ItemMap map[string]TimeItem IsFloat bool Interval timeutil.Interval // Informational }
func AggregateSeries ¶
func AggregateSeries(series TimeSeries) TimeSeries
func NewTimeSeries ¶
func NewTimeSeries(name string) TimeSeries
NewTimeSeries instantiates a `TimeSeries` struct.
func ReadFileTimeSeries ¶
func ReadFileTimeSeries(filename string) (TimeSeries, error)
ReadFileTimeSeries reads a time series file in JSON.
func TimeSeriesDivide ¶
func TimeSeriesDivide(numer, denom TimeSeries) (TimeSeries, error)
func (*TimeSeries) AddFloat64 ¶
func (ts *TimeSeries) AddFloat64(dt time.Time, value float64)
AddFloat64 adds a time value, converting it to a int64 on the series type.
func (*TimeSeries) AddInt64 ¶
func (ts *TimeSeries) AddInt64(dt time.Time, value int64)
AddInt64 adds a time value, converting it to a float on the series type.
func (*TimeSeries) AddItems ¶
func (ts *TimeSeries) AddItems(items ...TimeItem)
AddItems adds a `TimeItem`. It will sum values when existing time unit is encountered.
func (*TimeSeries) ConvertFloat64 ¶ added in v2.6.0
func (ts *TimeSeries) ConvertFloat64()
func (*TimeSeries) ConvertInt64 ¶ added in v2.6.0
func (ts *TimeSeries) ConvertInt64()
func (*TimeSeries) DeleteTime ¶
func (ts *TimeSeries) DeleteTime(dt time.Time)
func (*TimeSeries) Get ¶
func (ts *TimeSeries) Get(dt time.Time) (TimeItem, error)
Get returns a `TimeItem` given a `time.Time`.
func (*TimeSeries) ItemTimes ¶
func (ts *TimeSeries) ItemTimes() []time.Time
func (*TimeSeries) ItemsSorted ¶
func (ts *TimeSeries) ItemsSorted() []TimeItem
ItemsSorted returns sorted TimeItems. This currently uses a simple string sort on RFC3339 times.
func (*TimeSeries) Keys ¶
func (ts *TimeSeries) Keys() []string
Keys returns a sorted listed of Item keys.
func (*TimeSeries) Last ¶
func (ts *TimeSeries) Last() (TimeItem, error)
func (*TimeSeries) LastItem ¶
func (ts *TimeSeries) LastItem(skipIfTimePartialValueLessPrev bool) (TimeItem, error)
func (*TimeSeries) LinearRegressionYear ¶ added in v2.6.1
func (ts *TimeSeries) LinearRegressionYear() (alpha, beta float64, err error)
LinearRegressionYear only runs when interval=Year.
func (*TimeSeries) LinearRegressionYearProjection ¶ added in v2.6.1
func (ts *TimeSeries) LinearRegressionYearProjection(years uint, constantYOY bool) error
LinearRegressionYearProjection only runs when interval=Year for now. Use this to build tables.
func (*TimeSeries) MaxValue ¶
func (ts *TimeSeries) MaxValue() int64
func (*TimeSeries) MinMaxTimes ¶
func (ts *TimeSeries) MinMaxTimes() (time.Time, time.Time)
func (*TimeSeries) MinMaxValues ¶
func (ts *TimeSeries) MinMaxValues() (int64, int64)
func (*TimeSeries) MinMaxValuesFloat64 ¶
func (ts *TimeSeries) MinMaxValuesFloat64() (float64, float64)
func (*TimeSeries) MinValue ¶
func (ts *TimeSeries) MinValue() int64
func (*TimeSeries) OneItemMaxValue ¶
func (ts *TimeSeries) OneItemMaxValue() (TimeItem, error)
func (*TimeSeries) Pop ¶
func (ts *TimeSeries) Pop() (TimeItem, error)
Pop removes the item with the chronologically last time. This is useful when generating interval charts and the last period has not concluded, thus providing an inaccurate projection when compared to previous full months of data.
func (*TimeSeries) SetSeriesName ¶
func (ts *TimeSeries) SetSeriesName(seriesName string)
func (*TimeSeries) Stats ¶
func (ts *TimeSeries) Stats() point.PointSet
func (*TimeSeries) Table ¶ added in v2.3.0
func (ts *TimeSeries) Table(tableName, dateColumnName, countColumnName string, dtFmt func(dt time.Time) string) table.Table
Table generates a `table.Table` given a `TimeSeries`.
func (*TimeSeries) TableMonthXOX ¶ added in v2.3.0
func (ts *TimeSeries) TableMonthXOX(timeFmtColName, seriesName, valuesName, yoyName, qoqName, momName string, opts *TableMonthXOXOpts) table.Table
func (*TimeSeries) TableYearYOY ¶ added in v2.6.1
func (ts *TimeSeries) TableYearYOY(seriesName, valuesName, yoyName string) table.Table
func (*TimeSeries) TimeSeries ¶
func (ts *TimeSeries) TimeSeries(interval timeutil.Interval) []time.Time
func (*TimeSeries) TimeSeriesMonthMOM ¶ added in v2.3.0
func (ts *TimeSeries) TimeSeriesMonthMOM() TimeSeries
func (*TimeSeries) TimeSeriesMonthQOQ ¶ added in v2.3.0
func (ts *TimeSeries) TimeSeriesMonthQOQ() TimeSeries
func (*TimeSeries) TimeSeriesMonthXOX ¶ added in v2.3.0
func (ts *TimeSeries) TimeSeriesMonthXOX(years, months, days int, suffix string) TimeSeries
func (*TimeSeries) TimeSeriesMonthYOY ¶ added in v2.3.0
func (ts *TimeSeries) TimeSeriesMonthYOY() TimeSeries
func (*TimeSeries) TimeSeriesYearYOY ¶ added in v2.6.1
func (ts *TimeSeries) TimeSeriesYearYOY(suffix string) (TimeSeries, error)
func (*TimeSeries) ToMonth ¶
func (ts *TimeSeries) ToMonth(inflate bool, monthsFilter ...time.Month) TimeSeries
ToMonth aggregates time values into months. `inflate` is used to add months with `0` values.
func (*TimeSeries) ToMonthCumulative ¶
func (ts *TimeSeries) ToMonthCumulative(inflate bool, timesInput ...time.Time) (TimeSeries, error)
func (*TimeSeries) ToQuarter ¶
func (ts *TimeSeries) ToQuarter() TimeSeries
func (*TimeSeries) ToYear ¶ added in v2.6.1
func (ts *TimeSeries) ToYear() TimeSeries
type TimeSeriesFunnel ¶
type TimeSeriesFunnel struct { Series map[string]TimeSeriesSimple Order []string }
func (*TimeSeriesFunnel) TimeSeriesSetByQuarter ¶
func (tsf *TimeSeriesFunnel) TimeSeriesSetByQuarter() (TimeSeriesSet, error)
func (*TimeSeriesFunnel) Times ¶
func (tsf *TimeSeriesFunnel) Times() []time.Time
func (*TimeSeriesFunnel) TimesSorted ¶
func (tsf *TimeSeriesFunnel) TimesSorted() []time.Time
type TimeSeriesSet ¶
type TimeSeriesSet struct { Name string Series map[string]TimeSeries Times []time.Time Order []string IsFloat bool Interval timeutil.Interval }
TimeSeriesSet is a data structure to manage a set of similar `TimeSeries`. It is necessary for all `TimeSeries` to have the same value of `IsFloat`.
func NewTimeSeriesSet ¶
func NewTimeSeriesSet(name string) TimeSeriesSet
NewTimeSeriesSet returns an initialized `TimeSeriesSet`.
func ParseTableTimeSeriesSetFlat ¶ added in v2.4.2
func ParseTableTimeSeriesSetFlat(tbl table.Table, timeColIdx, seriesNameColIdx, countColIdx uint, isFloat bool, timeParseFunc func(s string) (time.Time, error)) (TimeSeriesSet, error)
ParseTableTimeSeriesSetFlat create a `TimeSeriesSet` from a `table.Table` using the least amount of input to populate the data structure. It does not set the following parameters which must be set manually: `Name`, `Interval`.
func ParseTableTimeSeriesSetMatrix ¶ added in v2.4.2
func ParseTableTimeSeriesSetMatrix(tbl table.Table, isFloat bool, timeParseFunc func(s string) (time.Time, error)) (TimeSeriesSet, error)
ParseTableTimeSeriesSetMatrix create a `TimeSeriesSet` from a `table.Table` using the least amount of input to populate the data structure. The time must be in column 0 and the series names must be in the column headers.
func ReadFileTimeSeriesSet ¶
func ReadFileTimeSeriesSet(filename string) (TimeSeriesSet, error)
ReadFileTimeSeriesSet reads a time series set file in JSON.
func (*TimeSeriesSet) AddFloat64 ¶
func (set *TimeSeriesSet) AddFloat64(seriesName string, dt time.Time, value float64)
AddFloat64 adds an `int64` value, converting it to a `int64` if necssary based on set definition.
func (*TimeSeriesSet) AddInt64 ¶
func (set *TimeSeriesSet) AddInt64(seriesName string, dt time.Time, value int64)
AddInt64 adds an `int64` value, converting it to a `float64` if necssary based on set definition.
func (*TimeSeriesSet) AddItems ¶
func (set *TimeSeriesSet) AddItems(items ...TimeItem)
func (*TimeSeriesSet) AddSeries ¶
func (set *TimeSeriesSet) AddSeries(timeSeries ...TimeSeries) error
func (*TimeSeriesSet) DeleteTime ¶
func (set *TimeSeriesSet) DeleteTime(dt time.Time)
func (*TimeSeriesSet) GetSeriesByIndex ¶
func (set *TimeSeriesSet) GetSeriesByIndex(index int) (TimeSeries, error)
func (*TimeSeriesSet) Inflate ¶
func (set *TimeSeriesSet) Inflate()
func (*TimeSeriesSet) Item ¶
func (set *TimeSeriesSet) Item(seriesName, rfc3339 string) (TimeItem, error)
func (*TimeSeriesSet) LinearRegressionYearProjection ¶ added in v2.6.1
func (set *TimeSeriesSet) LinearRegressionYearProjection(years uint, constantYOY bool) error
LinearRegressionYearProjection only runs when interval=Year.
func (*TimeSeriesSet) MinMaxTimes ¶
func (set *TimeSeriesSet) MinMaxTimes() (time.Time, time.Time)
func (*TimeSeriesSet) MinMaxValues ¶
func (set *TimeSeriesSet) MinMaxValues() (int64, int64)
func (*TimeSeriesSet) MinMaxValuesFloat64 ¶
func (set *TimeSeriesSet) MinMaxValuesFloat64() (float64, float64)
func (*TimeSeriesSet) PopLast ¶
func (set *TimeSeriesSet) PopLast()
func (*TimeSeriesSet) SeriesNames ¶
func (set *TimeSeriesSet) SeriesNames() []string
func (*TimeSeriesSet) Table ¶ added in v2.3.2
func (set *TimeSeriesSet) Table(opts *TimeSeriesSetTableOpts) (table.Table, error)
Table returns a `table.Table`.
func (*TimeSeriesSet) TableYearYOY ¶ added in v2.6.1
func (set *TimeSeriesSet) TableYearYOY(seriesColName, valuesSuffix, yoySuffix string) table.Table
func (*TimeSeriesSet) TimeSlice ¶
func (set *TimeSeriesSet) TimeSlice(sortAsc bool) timeslice.TimeSlice
func (*TimeSeriesSet) TimeStrings ¶
func (set *TimeSeriesSet) TimeStrings() []string
func (*TimeSeriesSet) ToMonth ¶
func (set *TimeSeriesSet) ToMonth(cumulative, inflate, popLast bool, monthsFilter []time.Month) (TimeSeriesSet, error)
ToMonth aggregates time values into months. `inflate` is used to add months with `0` values.
func (*TimeSeriesSet) ToNewSeriesNames ¶
func (set *TimeSeriesSet) ToNewSeriesNames(seriesNames, seriesSetNames map[string]string) TimeSeriesSet
func (*TimeSeriesSet) ToSetTimesRangeUpper ¶
func (set *TimeSeriesSet) ToSetTimesRangeUpper(inclusive bool, times ...time.Time) (TimeSeriesSet, error)
func (*TimeSeriesSet) ToYear ¶ added in v2.6.1
func (set *TimeSeriesSet) ToYear(inflate, popLast bool) (TimeSeriesSet, error)
ToYear aggregates time values into months. `inflate` is used to add months with `0` values.
func (*TimeSeriesSet) WriteJSON ¶
WriteJSON writes the TimeSeriesSet to a JSON file. To write a minimized JSON file use an empty string for `prefix` and `indent`.
func (*TimeSeriesSet) WriteXLSX ¶
func (set *TimeSeriesSet) WriteXLSX(filename string, opts *TimeSeriesSetTableOpts) error
WriteXLSX writes the TimeSeriesSet as a XLSX spreadsheet file.
type TimeSeriesSetTableOpts ¶
type TimeSeriesSetTableOpts struct { TimeColumnTitle string FuncFormatTime func(time.Time) string TotalInclude bool TotalTitle string PercentInclude bool PercentSuffix string }
func (*TimeSeriesSetTableOpts) PercentSuffixOrDefault ¶
func (opts *TimeSeriesSetTableOpts) PercentSuffixOrDefault() string
func (*TimeSeriesSetTableOpts) TotalTitleOrDefault ¶
func (opts *TimeSeriesSetTableOpts) TotalTitleOrDefault() string
type TimeSeriesSets ¶
type TimeSeriesSets struct { Name string SetsMap map[string]TimeSeriesSet Order []string KeyIsTime bool Interval timeutil.Interval }
func NewTimeSeriesSets ¶
func NewTimeSeriesSets(name string) TimeSeriesSets
func (*TimeSeriesSets) AddItems ¶
func (sets *TimeSeriesSets) AddItems(items ...TimeItem)
func (*TimeSeriesSets) SeriesNames ¶
func (sets *TimeSeriesSets) SeriesNames() []string
func (*TimeSeriesSets) SetNames ¶
func (sets *TimeSeriesSets) SetNames() []string
type TimeSeriesSimple ¶
func NewTimeSeriesSimple ¶
func NewTimeSeriesSimple(name, displayName string) TimeSeriesSimple
func (*TimeSeriesSimple) ToTimeSeriesQuarter ¶
func (tss *TimeSeriesSimple) ToTimeSeriesQuarter() TimeSeries
type TimeStats ¶
type TimeStats struct {
Items []TimeItem
}
TimeStats is used to generate unique counts stats for an array of with time ane names.
func (*TimeStats) UniqueCountsByMonth ¶
func (*TimeStats) UniqueCountsByQuarter ¶
Source Files ¶
- read_table.go
- time_item.go
- time_series.go
- time_series_export.go
- time_series_month_xox.go
- time_series_regression.go
- time_series_set.go
- time_series_set_mod.go
- time_series_set_parse.go
- time_series_set_regression.go
- time_series_set_report.go
- time_series_set_xf.go
- time_series_sets.go
- time_series_simple.go
- time_series_slice.go
- time_series_util.go
- time_stats.go