# HG changeset patch # User Sascha Wilde # Date 1568034895 -7200 # Node ID 97312d7954bad82542bb4806a63af4215b1fc795 # Parent 69c54e2def2dc255622518b2fc59deb01738e22c FA diagrams: round to full days in back end. diff -r 69c54e2def2d -r 97312d7954ba pkg/common/round.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/common/round.go Mon Sep 09 15:14:55 2019 +0200 @@ -0,0 +1,71 @@ +// This is Free Software under GNU Affero General Public License v >= 3.0 +// without warranty, see README.md and license for details. +// +// SPDX-License-Identifier: AGPL-3.0-or-later +// License-Filename: LICENSES/AGPL-3.0.txt +// +// Copyright (C) 2018 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha Wilde + +package common + +import ( + "math" + "sort" + "time" +) + +type Rest struct { + Key int + Rest float64 +} + +// Simple sum preserving rounding method: +func SumPreservingRound(arr []float64) []int { + var ( + sum float64 + rests []Rest + ) + result := make([]int, len(arr)) + + // floor all values + for i, v := range arr { + sum += v + result[i] = int(v) + rests = append(rests, Rest{Key: i, Rest: v - float64(result[i])}) + } + + // find the difference in summs + var newSum int + for _, v := range result { + newSum += v + } + delta := int(math.Round(sum)) - newSum + + // spread delta over values with highest rest + sort.Slice(rests, func(i, j int) bool { + return rests[i].Rest > rests[j].Rest + }) + for _, v := range rests { + if delta <= 0 { + break + } + result[v.Key]++ + delta-- + } + + return result +} + +// Round anarray of Duratons to full days +func RoundToFullDays(durations []time.Duration) []int { + days := make([]float64, len(durations)) + for i, v := range durations { + days[i] = v.Hours() / 24 + } + return SumPreservingRound(days) +} diff -r 69c54e2def2d -r 97312d7954ba pkg/controllers/bottlenecks.go --- a/pkg/controllers/bottlenecks.go Fri Sep 06 18:09:48 2019 +0200 +++ b/pkg/controllers/bottlenecks.go Mon Sep 09 15:14:55 2019 +0200 @@ -653,13 +653,13 @@ // label, ldc, classes record := make([]string, 1+2+len(breaks)+1) record[0] = "#time" - record[1] = fmt.Sprintf("# < LDC (%.1f) [h]", ldcRefs[0]) - record[2] = fmt.Sprintf("# >= LDC (%.1f) [h]", ldcRefs[0]) + record[1] = fmt.Sprintf("# < LDC (%.1f) [d]", ldcRefs[0]) + record[2] = fmt.Sprintf("# >= LDC (%.1f) [d]", ldcRefs[0]) for i, v := range breaks { if i == 0 { - record[3] = fmt.Sprintf("# < %.1f [h]", v) + record[3] = fmt.Sprintf("# < %.1f [d]", v) } - record[i+4] = fmt.Sprintf("# >= %.1f [h]", v) + record[i+4] = fmt.Sprintf("# >= %.1f [d]", v) } if err := out.Write(record); err != nil { @@ -701,13 +701,17 @@ access, ) + // Round to full days + ldcRounded := common.RoundToFullDays(ldc) + rangesRounded := common.RoundToFullDays(ranges) + record[0] = label - for i, v := range ldc { - record[i+1] = fmt.Sprintf("%.3f", v.Hours()) + for i, v := range ldcRounded { + record[i+1] = fmt.Sprintf("%d", v) } - for i, d := range ranges { - record[3+i] = fmt.Sprintf("%.3f", d.Hours()) + for i, d := range rangesRounded { + record[3+i] = fmt.Sprintf("%d", d) } if err := out.Write(record); err != nil { diff -r 69c54e2def2d -r 97312d7954ba pkg/controllers/stretches.go --- a/pkg/controllers/stretches.go Fri Sep 06 18:09:48 2019 +0200 +++ b/pkg/controllers/stretches.go Mon Sep 09 15:14:55 2019 +0200 @@ -27,6 +27,7 @@ "github.com/gorilla/mux" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/middleware" ) @@ -379,13 +380,23 @@ } for _, r := range results { - record[0] = r.label + // Round to full days for i, v := range r.ldc { - record[1+i] = fmt.Sprintf("%.3f", v.Hours()*scale) + r.ldc[i] = time.Duration(float64(v) * scale) + } + for i, v := range r.breaks { + r.breaks[i] = time.Duration(float64(v) * scale) + } + ldcRounded := common.RoundToFullDays(r.ldc) + rangesRounded := common.RoundToFullDays(r.breaks) + + record[0] = r.label + for i, v := range ldcRounded { + record[1+i] = fmt.Sprintf("%d", v) } - for i, d := range r.breaks { - record[3+i] = fmt.Sprintf("%.3f", d.Hours()*scale) + for i, d := range rangesRounded { + record[3+i] = fmt.Sprintf("%d", d) } if err := out.Write(record); err != nil {