From 0579c9720c40f31306d5764a2025db34f569a28d Mon Sep 17 00:00:00 2001 From: mgiannopoulos24 Date: Fri, 5 Jul 2024 03:09:50 +0300 Subject: [PATCH 1/4] Aded float64 value support. --- progress.go | 10 +++++----- progress.html | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/progress.go b/progress.go index b20081e..1e817f5 100644 --- a/progress.go +++ b/progress.go @@ -16,8 +16,8 @@ import ( // Data ... is the collection of inputs we need to fill our template type Data struct { BackgroundColor string - Percentage int - Progress int + Percentage float64 + Progress float64 PickedColor string } @@ -35,7 +35,7 @@ func fixDir() { } } -func pickColor(percentage int, successColor string, warningColor string, dangerColor string) string { +func pickColor(percentage float64, successColor string, warningColor string, dangerColor string) string { pickedColor := green if successColor != "" { pickedColor = "#" + successColor @@ -67,7 +67,7 @@ func init() { func Progress(w http.ResponseWriter, r *http.Request) { var id = fmt.Sprintf(path.Base(r.URL.Path)) - if percentage, err := strconv.Atoi(id); err == nil { + if percentage, err := strconv.ParseFloat(id, 64); err == nil { // Read (with the intention to overwrite) success, warning, and danger colors if provided successColor := r.URL.Query().Get("successColor") @@ -94,7 +94,7 @@ func Progress(w http.ResponseWriter, r *http.Request) { log.Fatalln(err) } - fmt.Printf("The percentage is: %d\n", percentage) + fmt.Printf("The percentage is: %.3f\n", percentage) w.Header().Add("Content-Type", "image/svg+xml") fmt.Fprintf(w, buf.String()) } diff --git a/progress.html b/progress.html index b4b927b..9699d42 100644 --- a/progress.html +++ b/progress.html @@ -1,14 +1,14 @@ - + - + - {{.Percentage}}%% + {{printf "%.3f" .Percentage}}% From dddc60150c4531a320a0b0148cc9175d3b819c26 Mon Sep 17 00:00:00 2001 From: mgiannopoulos24 Date: Thu, 23 Jan 2025 13:16:12 +0000 Subject: [PATCH 2/4] Added float64 value support --- progress.go | 64 +++++++++++++++++++++++++-------------------------- progress.html | 6 ++--- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/progress.go b/progress.go index 1e817f5..aeec2c3 100644 --- a/progress.go +++ b/progress.go @@ -13,7 +13,7 @@ import ( "github.com/GoogleCloudPlatform/functions-framework-go/functions" ) -// Data ... is the collection of inputs we need to fill our template +// Data ... is the collection of inputs to fill our template type Data struct { BackgroundColor string Percentage float64 @@ -35,19 +35,20 @@ func fixDir() { } } -func pickColor(percentage float64, successColor string, warningColor string, dangerColor string) string { +func pickColor(percentage float64, successColor, warningColor, dangerColor string) string { pickedColor := green if successColor != "" { pickedColor = "#" + successColor } - if percentage >= 0 && percentage < 33 { + switch { + case percentage >= 0 && percentage < 33: if dangerColor != "" { pickedColor = "#" + dangerColor } else { pickedColor = red } - } else if percentage >= 33 && percentage < 70 { + case percentage >= 33 && percentage < 70: if warningColor != "" { pickedColor = "#" + warningColor } else { @@ -65,37 +66,36 @@ func init() { // Progress ... Entrypoint of our Cloud Function func Progress(w http.ResponseWriter, r *http.Request) { - var id = fmt.Sprintf(path.Base(r.URL.Path)) + id := path.Base(r.URL.Path) - if percentage, err := strconv.ParseFloat(id, 64); err == nil { - - // Read (with the intention to overwrite) success, warning, and danger colors if provided - successColor := r.URL.Query().Get("successColor") - warningColor := r.URL.Query().Get("warningColor") - dangerColor := r.URL.Query().Get("dangerColor") - - data := Data{ - BackgroundColor: grey, - Percentage: percentage, - Progress: percentage - (percentage / 10), - PickedColor: pickColor(percentage, successColor, warningColor, dangerColor), - } - - tpl, err := template.ParseFiles("progress.html") + percentage, err := strconv.ParseFloat(id, 64) + if err != nil { + http.Error(w, "Invalid percentage value", http.StatusBadRequest) + return + } - if err != nil { - log.Fatalln(err) - } + successColor := r.URL.Query().Get("successColor") + warningColor := r.URL.Query().Get("warningColor") + dangerColor := r.URL.Query().Get("dangerColor") - buf := new(bytes.Buffer) + data := Data{ + BackgroundColor: grey, + Percentage: percentage, + Progress: percentage - (percentage / 10), + PickedColor: pickColor(percentage, successColor, warningColor, dangerColor), + } - err = tpl.Execute(buf, data) - if err != nil { - log.Fatalln(err) - } + tpl, err := template.ParseFiles("progress.html") + if err != nil { + log.Fatalln("Error parsing template:", err) + } - fmt.Printf("The percentage is: %.3f\n", percentage) - w.Header().Add("Content-Type", "image/svg+xml") - fmt.Fprintf(w, buf.String()) + buf := new(bytes.Buffer) + if err := tpl.Execute(buf, data); err != nil { + log.Fatalln("Error executing template:", err) } -} + + fmt.Printf("The percentage is: %.2f\n", percentage) + w.Header().Set("Content-Type", "image/svg+xml") + _, _ = w.Write(buf.Bytes()) +} \ No newline at end of file diff --git a/progress.html b/progress.html index 9699d42..e558e3f 100644 --- a/progress.html +++ b/progress.html @@ -4,11 +4,11 @@ - + - {{printf "%.3f" .Percentage}}% + {{printf "%.2f%%" .Percentage}} - + \ No newline at end of file From 5a2e6fb56db3d46fbdc52f4d9a192c38e68f5217 Mon Sep 17 00:00:00 2001 From: mgiannopoulos24 Date: Thu, 23 Jan 2025 13:35:58 +0000 Subject: [PATCH 3/4] Simple if else case --- progress.go | 15 +++++++++++---- progress.html | 6 +++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/progress.go b/progress.go index aeec2c3..320a662 100644 --- a/progress.go +++ b/progress.go @@ -13,7 +13,6 @@ import ( "github.com/GoogleCloudPlatform/functions-framework-go/functions" ) -// Data ... is the collection of inputs to fill our template type Data struct { BackgroundColor string Percentage float64 @@ -64,7 +63,11 @@ func init() { functions.HTTP("Progress", Progress) } -// Progress ... Entrypoint of our Cloud Function +// Template helper to check if a float is an integer +func isInt(f float64) bool { + return f == float64(int(f)) +} + func Progress(w http.ResponseWriter, r *http.Request) { id := path.Base(r.URL.Path) @@ -85,7 +88,11 @@ func Progress(w http.ResponseWriter, r *http.Request) { PickedColor: pickColor(percentage, successColor, warningColor, dangerColor), } - tpl, err := template.ParseFiles("progress.html") + // Parse template with custom "isInt" function + tpl := template.New("progress.html").Funcs(template.FuncMap{ + "isInt": isInt, + }) + tpl, err = tpl.ParseFiles("progress.html") if err != nil { log.Fatalln("Error parsing template:", err) } @@ -95,7 +102,7 @@ func Progress(w http.ResponseWriter, r *http.Request) { log.Fatalln("Error executing template:", err) } - fmt.Printf("The percentage is: %.2f\n", percentage) + fmt.Printf("The percentage is: %v\n", percentage) w.Header().Set("Content-Type", "image/svg+xml") _, _ = w.Write(buf.Bytes()) } \ No newline at end of file diff --git a/progress.html b/progress.html index e558e3f..f48cb04 100644 --- a/progress.html +++ b/progress.html @@ -8,7 +8,11 @@ - {{printf "%.2f%%" .Percentage}} + {{if isInt .Percentage}} + {{printf "%.0f%%" .Percentage}} + {{else}} + {{printf "%.2f%%" .Percentage}} + {{end}} \ No newline at end of file From e0483adbcf25f77adc7e3a6172a30f4824a3f672 Mon Sep 17 00:00:00 2001 From: mgiannopoulos24 <79588074+mgiannopoulos24@users.noreply.github.com> Date: Sun, 21 Dec 2025 19:54:23 +0200 Subject: [PATCH 4/4] feat: Add custom label overlay and data bar support with min/max scaling --- cmd/main.go | 5 ++++ progress.go | 79 +++++++++++++++++++++++++++++++++++++++++++++++---- progress.html | 18 +++++++----- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index e862a88..cee0eac 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -10,6 +10,11 @@ import ( ) func main() { + // Set FUNCTION_TARGET if not already set + if os.Getenv("FUNCTION_TARGET") == "" { + os.Setenv("FUNCTION_TARGET", "Progress") + } + // Use PORT environment variable, or default to 8080. port := "8080" if envPort := os.Getenv("PORT"); envPort != "" { diff --git a/progress.go b/progress.go index 320a662..660e929 100644 --- a/progress.go +++ b/progress.go @@ -18,6 +18,9 @@ type Data struct { Percentage float64 Progress float64 PickedColor string + Label string + ShowLabel bool + BarWidth float64 } var grey = "#555" @@ -68,29 +71,95 @@ func isInt(f float64) bool { return f == float64(int(f)) } +// Template helper for division +func div(a, b float64) float64 { + if b == 0 { + return 0 + } + return a / b +} + func Progress(w http.ResponseWriter, r *http.Request) { id := path.Base(r.URL.Path) - percentage, err := strconv.ParseFloat(id, 64) + value, err := strconv.ParseFloat(id, 64) if err != nil { - http.Error(w, "Invalid percentage value", http.StatusBadRequest) + http.Error(w, "Invalid value", http.StatusBadRequest) return } successColor := r.URL.Query().Get("successColor") warningColor := r.URL.Query().Get("warningColor") dangerColor := r.URL.Query().Get("dangerColor") + barColor := r.URL.Query().Get("barColor") + customLabel := r.URL.Query().Get("label") + minStr := r.URL.Query().Get("min") + maxStr := r.URL.Query().Get("max") + + // Determine if we're using custom label mode (data bar mode) + showLabel := customLabel != "" + + // Calculate percentage and bar width + var percentage float64 + var barWidth float64 + const defaultWidth = 90.0 + + if showLabel && minStr != "" && maxStr != "" { + // Data bar mode: scale proportionally based on min/max + min, errMin := strconv.ParseFloat(minStr, 64) + max, errMax := strconv.ParseFloat(maxStr, 64) + + if errMin != nil || errMax != nil || min >= max { + http.Error(w, "Invalid min/max values", http.StatusBadRequest) + return + } + + // Calculate percentage for color picking (0-100) + if max > min { + percentage = ((value - min) / (max - min)) * 100 + } else { + percentage = 0 + } + + // Calculate bar width proportionally (leave some padding) + if max > min { + barWidth = ((value - min) / (max - min)) * (defaultWidth * 0.95) + } else { + barWidth = 0 + } + } else { + // Original percentage mode + percentage = value + if percentage > 100 { + percentage = 100 + } + barWidth = percentage - (percentage / 10) + } + + // Determine bar color + var pickedColor string + if barColor != "" { + // Use custom bar color if provided (for data bars) + pickedColor = "#" + barColor + } else { + // Use percentage-based color logic + pickedColor = pickColor(percentage, successColor, warningColor, dangerColor) + } data := Data{ BackgroundColor: grey, Percentage: percentage, - Progress: percentage - (percentage / 10), - PickedColor: pickColor(percentage, successColor, warningColor, dangerColor), + Progress: barWidth, + BarWidth: defaultWidth, + PickedColor: pickedColor, + Label: customLabel, + ShowLabel: showLabel, } - // Parse template with custom "isInt" function + // Parse template with custom functions tpl := template.New("progress.html").Funcs(template.FuncMap{ "isInt": isInt, + "div": div, }) tpl, err = tpl.ParseFiles("progress.html") if err != nil { diff --git a/progress.html b/progress.html index f48cb04..0c31912 100644 --- a/progress.html +++ b/progress.html @@ -1,17 +1,21 @@ - + - + - + - - {{if isInt .Percentage}} - {{printf "%.0f%%" .Percentage}} + + {{if .ShowLabel}} + {{.Label}} {{else}} - {{printf "%.2f%%" .Percentage}} + {{if isInt .Percentage}} + {{printf "%.0f%%" .Percentage}} + {{else}} + {{printf "%.2f%%" .Percentage}} + {{end}} {{end}}