summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/chart.go77
1 files changed, 59 insertions, 18 deletions
diff --git a/server/chart.go b/server/chart.go
index 1f20d3c..b6c0471 100644
--- a/server/chart.go
+++ b/server/chart.go
@@ -5,6 +5,9 @@ import (
"net/http"
"fmt"
"time"
+ "sync"
+ "slices"
+ "strings"
"github.com/wcharczuk/go-chart/v2"
)
@@ -21,28 +24,11 @@ func (h ChartHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
- var series []chart.Series
- for room, record := range h.building {
- var x []time.Time
- var y []float64
- c := make(chan Entry[Humidity])
- record.get <- c
- for e := range c {
- x = append(x, e.t)
- y = append(y, float64(e.v))
- }
- series = append(series, chart.TimeSeries{
- Name: string(room),
- XValues: x,
- YValues: y,
- })
- }
-
graph := chart.Chart{
Background: chart.Style{
Padding: chart.Box{Top: 20, Left: 20},
},
- Series: series,
+ Series: buildSortedSeries(h.building),
}
graph.Elements = []chart.Renderable{
chart.Legend(&graph),
@@ -53,3 +39,58 @@ func (h ChartHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Println(err)
}
}
+
+// Build a time series for each humidity record in the building.
+// The returned series' are sorted by room name.
+func buildSortedSeries(building Building) []chart.Series {
+ seriesChan := make(chan chart.TimeSeries)
+ sortedSeriesChan := make(chan []chart.Series)
+ go sortSeriesByName(seriesChan, sortedSeriesChan)
+
+ var wg sync.WaitGroup
+ for room, record := range building {
+ entries := make(chan Entry[Humidity])
+ record.get <- entries
+ wg.Add(1)
+ go func() {
+ buildSeries(room, entries, seriesChan)
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+ close(seriesChan)
+ return <-sortedSeriesChan
+}
+
+// Sort a sequence of series' by name.
+func sortSeriesByName(in <-chan chart.TimeSeries, out chan<- []chart.Series) {
+ series := make([]chart.Series, 0)
+ cmp := func(a chart.Series, b chart.TimeSeries) int {
+ return strings.Compare(a.GetName(), b.GetName())
+ }
+
+ // Insertion sort.
+ for s := range in {
+ i, _ := slices.BinarySearchFunc(series, s, cmp)
+ series = slices.Insert(series, i, chart.Series(s))
+ }
+
+ out <- series
+ close(out)
+}
+
+// Build a time series from a sequence of record entries.
+func buildSeries(room RoomID, in <-chan Entry[Humidity], out chan<- chart.TimeSeries) {
+ var x []time.Time
+ var y []float64
+
+ for e := range in {
+ x = append(x, e.t)
+ y = append(y, float64(e.v))
+ }
+ out <- chart.TimeSeries{
+ Name: string(room),
+ XValues: x,
+ YValues: y,
+ }
+}