79 lines
1.6 KiB
Go
79 lines
1.6 KiB
Go
package chartjs
|
|
|
|
import (
|
|
"slices"
|
|
"sync"
|
|
)
|
|
|
|
// DataCounter 计数统计, 实现类似Pie 和 Doughnut 之类的图形
|
|
type DataCounter struct {
|
|
mutex sync.Mutex
|
|
legends map[string]*counterValue
|
|
}
|
|
|
|
func (c *DataCounter) Inc(leg string, label string, value float64) {
|
|
c.mutex.Lock()
|
|
defer c.mutex.Unlock()
|
|
v, ok := c.legends[leg]
|
|
if !ok {
|
|
v = &counterValue{
|
|
Label: leg,
|
|
Values: make(map[string]float64),
|
|
}
|
|
c.legends[leg] = v
|
|
}
|
|
v.Values[label] += value
|
|
}
|
|
|
|
func (c *DataCounter) Dec(legend string, label string, value float64) {
|
|
c.mutex.Lock()
|
|
defer c.mutex.Unlock()
|
|
v, ok := c.legends[legend]
|
|
if !ok {
|
|
return
|
|
}
|
|
if _, ok := v.Values[label]; ok {
|
|
v.Values[label] -= value
|
|
}
|
|
}
|
|
|
|
func (c *DataCounter) Data() *CounterData {
|
|
c.mutex.Lock()
|
|
defer c.mutex.Unlock()
|
|
data := &CounterData{
|
|
Lables: make([]string, 0, 5),
|
|
Datasets: make([]*CounterValue, 0, len(c.legends)),
|
|
}
|
|
for _, row := range c.legends {
|
|
for k, _ := range row.Values {
|
|
if !slices.Contains(data.Lables, k) {
|
|
data.Lables = append(data.Lables, k)
|
|
}
|
|
}
|
|
}
|
|
for _, row := range c.legends {
|
|
set := &CounterValue{
|
|
Label: row.Label,
|
|
Data: make([]float64, 0, len(data.Lables)),
|
|
}
|
|
for _, label := range data.Lables {
|
|
set.Data = append(set.Data, row.Values[label])
|
|
}
|
|
data.Datasets = append(data.Datasets, set)
|
|
}
|
|
return data
|
|
}
|
|
|
|
func NewDataCounter(legends ...string) *DataCounter {
|
|
c := &DataCounter{
|
|
legends: make(map[string]*counterValue),
|
|
}
|
|
for _, legend := range legends {
|
|
c.legends[legend] = &counterValue{
|
|
Label: legend,
|
|
Values: make(map[string]float64),
|
|
}
|
|
}
|
|
return c
|
|
}
|