52 lines
1.1 KiB
Go
52 lines
1.1 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"strings"
|
|
|
|
pb "git.ipng.ch/ipng/nginx-logtail/proto/logtailpb"
|
|
)
|
|
|
|
const (
|
|
svgW = 300.0
|
|
svgH = 60.0
|
|
svgPad = 4.0
|
|
)
|
|
|
|
// renderSparkline converts trend points into an inline SVG polyline.
|
|
// Returns "" if there are fewer than 2 points or all counts are zero.
|
|
func renderSparkline(points []*pb.TrendPoint) template.HTML {
|
|
if len(points) < 2 {
|
|
return ""
|
|
}
|
|
|
|
var maxCount int64
|
|
for _, p := range points {
|
|
if p.Count > maxCount {
|
|
maxCount = p.Count
|
|
}
|
|
}
|
|
if maxCount == 0 {
|
|
return ""
|
|
}
|
|
|
|
n := len(points)
|
|
var pts strings.Builder
|
|
for i, p := range points {
|
|
x := svgPad + float64(i)*(svgW-2*svgPad)/float64(n-1)
|
|
y := svgPad + (svgH-2*svgPad)*(1.0-float64(p.Count)/float64(maxCount))
|
|
if i > 0 {
|
|
pts.WriteByte(' ')
|
|
}
|
|
fmt.Fprintf(&pts, "%.1f,%.1f", x, y)
|
|
}
|
|
|
|
return template.HTML(fmt.Sprintf(
|
|
`<svg viewBox="0 0 %d %d" width="%d" height="%d" xmlns="http://www.w3.org/2000/svg">`+
|
|
`<polyline points="%s" fill="none" stroke="#4a90d9" stroke-width="1.5" stroke-linejoin="round"/>`+
|
|
`</svg>`,
|
|
int(svgW), int(svgH), int(svgW), int(svgH), pts.String(),
|
|
))
|
|
}
|