use javascript chart instead of svg
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2026-02-06 16:42:48 +11:00
parent 9677d083a8
commit a993aedf79
13 changed files with 1152 additions and 1290 deletions

View File

@@ -141,91 +141,54 @@ func buildVcenterChart(entries []views.VcenterTotalsEntry) views.VcenterChartDat
plot = append(plot, entries[i])
}
width := 1200.0
height := 260.0
plotWidth := width - 60.0
startX := 40.0
maxVal := float64(0)
labels := make([]string, 0, len(plot))
tickLabels := make([]string, 0, len(plot))
vmValues := make([]float64, 0, len(plot))
vcpuValues := make([]float64, 0, len(plot))
ramValues := make([]float64, 0, len(plot))
for _, e := range plot {
if float64(e.VmCount) > maxVal {
maxVal = float64(e.VmCount)
}
if float64(e.VcpuTotal) > maxVal {
maxVal = float64(e.VcpuTotal)
}
if float64(e.RamTotalGB) > maxVal {
maxVal = float64(e.RamTotalGB)
}
t := time.Unix(e.RawTime, 0).Local()
labels = append(labels, t.Format("2006-01-02 15:04:05"))
tickLabels = append(tickLabels, t.Format("01-02 15:04"))
vmValues = append(vmValues, float64(e.VmCount))
vcpuValues = append(vcpuValues, float64(e.VcpuTotal))
ramValues = append(ramValues, float64(e.RamTotalGB))
}
if maxVal == 0 {
maxVal = 1
}
stepX := plotWidth
if len(plot) > 1 {
stepX = plotWidth / float64(len(plot)-1)
}
pointsVm := ""
pointsVcpu := ""
pointsRam := ""
for i, e := range plot {
x := startX + float64(i)*stepX
yVm := 10 + (1-(float64(e.VmCount)/maxVal))*height
yVcpu := 10 + (1-(float64(e.VcpuTotal)/maxVal))*height
yRam := 10 + (1-(float64(e.RamTotalGB)/maxVal))*height
if i == 0 {
pointsVm = fmt.Sprintf("%.1f,%.1f", x, yVm)
pointsVcpu = fmt.Sprintf("%.1f,%.1f", x, yVcpu)
pointsRam = fmt.Sprintf("%.1f,%.1f", x, yRam)
} else {
pointsVm = pointsVm + " " + fmt.Sprintf("%.1f,%.1f", x, yVm)
pointsVcpu = pointsVcpu + " " + fmt.Sprintf("%.1f,%.1f", x, yVcpu)
pointsRam = pointsRam + " " + fmt.Sprintf("%.1f,%.1f", x, yRam)
}
}
gridX := []float64{}
if len(plot) > 1 {
for i := 0; i < len(plot); i++ {
gridX = append(gridX, startX+float64(i)*stepX)
}
}
gridY := []float64{}
for i := 0; i <= 4; i++ {
gridY = append(gridY, 10+float64(i)*(height/4))
}
yTicks := []views.ChartTick{}
for i := 0; i <= 4; i++ {
val := maxVal * float64(4-i) / 4
pos := 10 + float64(i)*(height/4)
yTicks = append(yTicks, views.ChartTick{Pos: pos, Label: fmt.Sprintf("%.0f", val)})
}
xTicks := []views.ChartTick{}
maxTicks := 6
stepIdx := 1
if len(plot) > 1 {
stepIdx = (len(plot)-1)/maxTicks + 1
}
for idx := 0; idx < len(plot); idx += stepIdx {
x := startX + float64(idx)*stepX
label := time.Unix(plot[idx].RawTime, 0).Local().Format("01-02 15:04")
xTicks = append(xTicks, views.ChartTick{Pos: x, Label: label})
}
if len(plot) > 1 {
lastIdx := len(plot) - 1
xLast := startX + float64(lastIdx)*stepX
labelLast := time.Unix(plot[lastIdx].RawTime, 0).Local().Format("01-02 15:04")
if len(xTicks) == 0 || xTicks[len(xTicks)-1].Pos != xLast {
xTicks = append(xTicks, views.ChartTick{Pos: xLast, Label: labelLast})
}
cfg := lineChartConfig{
Height: 360,
XTicks: 6,
YTicks: 5,
YLabel: "Totals",
XLabel: "Snapshots (oldest left, newest right)",
Labels: labels,
TickLabels: tickLabels,
Series: []lineChartSeries{
{
Name: "VMs",
Color: "#2563eb",
Values: vmValues,
TooltipFormat: "int",
LineWidth: 2.5,
},
{
Name: "vCPU",
Color: "#16a34a",
Values: vcpuValues,
TooltipFormat: "int",
LineWidth: 2.5,
},
{
Name: "RAM (GB)",
Color: "#ea580c",
Values: ramValues,
TooltipFormat: "int",
LineWidth: 2.5,
},
},
}
return views.VcenterChartData{
PointsVm: pointsVm,
PointsVcpu: pointsVcpu,
PointsRam: pointsRam,
Width: int(width),
Height: int(height),
GridX: gridX,
GridY: gridY,
YTicks: yTicks,
XTicks: xTicks,
ConfigJSON: encodeLineChartConfig(cfg),
}
}