use javascript chart instead of svg
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -72,3 +72,5 @@ Network Trash Folder
|
|||||||
Temporary Items
|
Temporary Items
|
||||||
.apdisk
|
.apdisk
|
||||||
#/db/queries/*.go
|
#/db/queries/*.go
|
||||||
|
|
||||||
|
.gocache/
|
||||||
@@ -12,6 +12,7 @@ templ Header() {
|
|||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
|
||||||
<script src="/assets/js/htmx@v2.0.2.min.js"></script>
|
<script src="/assets/js/htmx@v2.0.2.min.js"></script>
|
||||||
|
<script src={ "/assets/js/web3-charts.js?v=" + version.Value }></script>
|
||||||
<link href={ "/assets/css/output@" + version.Value + ".css" } rel="stylesheet"/>
|
<link href={ "/assets/css/output@" + version.Value + ".css" } rel="stylesheet"/>
|
||||||
<link href="/assets/css/web3.css" rel="stylesheet"/>
|
<link href="/assets/css/web3.css" rel="stylesheet"/>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -31,20 +31,33 @@ func Header() templ.Component {
|
|||||||
templ_7745c5c3_Var1 = templ.NopComponent
|
templ_7745c5c3_Var1 = templ.NopComponent
|
||||||
}
|
}
|
||||||
ctx = templ.ClearChildren(ctx)
|
ctx = templ.ClearChildren(ctx)
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta name=\"description\" content=\"vCTP API endpoint\"><title>vCTP API</title><link rel=\"icon\" href=\"/favicon.ico\"><link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\"><link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\"><script src=\"/assets/js/htmx@v2.0.2.min.js\"></script><link href=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><meta name=\"description\" content=\"vCTP API endpoint\"><title>vCTP API</title><link rel=\"icon\" href=\"/favicon.ico\"><link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\"><link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\"><script src=\"/assets/js/htmx@v2.0.2.min.js\"></script><script src=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var2 templ.SafeURL
|
var templ_7745c5c3_Var2 string
|
||||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinURLErrs("/assets/css/output@" + version.Value + ".css")
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs("/assets/js/web3-charts.js?v=" + version.Value)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/header.templ`, Line: 15, Col: 61}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/header.templ`, Line: 15, Col: 62}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\" rel=\"stylesheet\"><link href=\"/assets/css/web3.css\" rel=\"stylesheet\"></head>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"></script><link href=\"")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var3 templ.SafeURL
|
||||||
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinURLErrs("/assets/css/output@" + version.Value + ".css")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/header.templ`, Line: 16, Col: 61}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" rel=\"stylesheet\"><link href=\"/assets/css/web3.css\" rel=\"stylesheet\"></head>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package views
|
package views
|
||||||
|
|
||||||
import (
|
import "vctp/components/core"
|
||||||
"fmt"
|
|
||||||
"vctp/components/core"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SnapshotEntry struct {
|
type SnapshotEntry struct {
|
||||||
Label string
|
Label string
|
||||||
@@ -18,10 +15,10 @@ type VcenterLink struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VcenterTotalsEntry struct {
|
type VcenterTotalsEntry struct {
|
||||||
Snapshot string
|
Snapshot string
|
||||||
RawTime int64
|
RawTime int64
|
||||||
VmCount int64
|
VmCount int64
|
||||||
VcpuTotal int64
|
VcpuTotal int64
|
||||||
RamTotalGB int64
|
RamTotalGB int64
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,20 +34,7 @@ type VcenterTotalsMeta struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VcenterChartData struct {
|
type VcenterChartData struct {
|
||||||
PointsVm string
|
ConfigJSON string
|
||||||
PointsVcpu string
|
|
||||||
PointsRam string
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
GridX []float64
|
|
||||||
GridY []float64
|
|
||||||
YTicks []ChartTick
|
|
||||||
XTicks []ChartTick
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChartTick struct {
|
|
||||||
Pos float64
|
|
||||||
Label string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templ SnapshotHourlyList(entries []SnapshotEntry) {
|
templ SnapshotHourlyList(entries []SnapshotEntry) {
|
||||||
@@ -75,17 +59,16 @@ templ SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) {
|
|||||||
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<div class="web2-pill">Snapshot Library</div>
|
<div class="web2-pill">Snapshot Library</div>
|
||||||
<h1 class="mt-3 text-4xl font-bold">{title}</h1>
|
<h1 class="mt-3 text-4xl font-bold">{ title }</h1>
|
||||||
<p class="mt-2 text-sm text-slate-600">{subtitle}</p>
|
<p class="mt-2 text-sm text-slate-600">{ subtitle }</p>
|
||||||
</div>
|
</div>
|
||||||
<a class="web2-button" href="/">Back to Dashboard</a>
|
<a class="web2-button" href="/">Back to Dashboard</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="web2-card">
|
<section class="web2-card">
|
||||||
<div class="flex items-center justify-between gap-3 mb-4 flex-wrap">
|
<div class="flex items-center justify-between gap-3 mb-4 flex-wrap">
|
||||||
<h2 class="text-lg font-semibold">Available Exports</h2>
|
<h2 class="text-lg font-semibold">Available Exports</h2>
|
||||||
<span class="web2-badge">{len(entries)} files</span>
|
<span class="web2-badge">{ len(entries) } files</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-hidden border border-slate-200 rounded">
|
<div class="overflow-hidden border border-slate-200 rounded">
|
||||||
<table class="web2-table">
|
<table class="web2-table">
|
||||||
@@ -100,20 +83,20 @@ templ SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) {
|
|||||||
for i, entry := range entries {
|
for i, entry := range entries {
|
||||||
if entry.Group != "" && (i == 0 || entries[i-1].Group != entry.Group) {
|
if entry.Group != "" && (i == 0 || entries[i-1].Group != entry.Group) {
|
||||||
<tr class="web2-group-row">
|
<tr class="web2-group-row">
|
||||||
<td colspan="3" class="font-semibold text-slate-700">{entry.Group}</td>
|
<td colspan="3" class="font-semibold text-slate-700">{ entry.Group }</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<span class="text-sm font-semibold text-slate-700">{entry.Label}</span>
|
<span class="text-sm font-semibold text-slate-700">{ entry.Label }</span>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="web2-badge">{entry.Count} records</span>
|
<span class="web2-badge">{ entry.Count } records</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<a class="web2-link" href={entry.Link}>Download XLSX</a>
|
<a class="web2-link" href={ entry.Link }>Download XLSX</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@@ -143,11 +126,10 @@ templ VcenterList(links []VcenterLink) {
|
|||||||
<a class="web2-button" href="/">Back to Dashboard</a>
|
<a class="web2-button" href="/">Back to Dashboard</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="web2-card">
|
<section class="web2-card">
|
||||||
<div class="flex items-center justify-between gap-3 mb-4 flex-wrap">
|
<div class="flex items-center justify-between gap-3 mb-4 flex-wrap">
|
||||||
<h2 class="text-lg font-semibold">vCenters</h2>
|
<h2 class="text-lg font-semibold">vCenters</h2>
|
||||||
<span class="web2-badge">{len(links)} total</span>
|
<span class="web2-badge">{ len(links) } total</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-hidden border border-slate-200 rounded">
|
<div class="overflow-hidden border border-slate-200 rounded">
|
||||||
<table class="web2-table">
|
<table class="web2-table">
|
||||||
@@ -160,9 +142,9 @@ templ VcenterList(links []VcenterLink) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
for _, link := range links {
|
for _, link := range links {
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font-semibold text-slate-700">{link.Name}</td>
|
<td class="font-semibold text-slate-700">{ link.Name }</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<a class="web2-link" href={link.Link}>View Totals</a>
|
<a class="web2-link" href={ link.Link }>View Totals</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
@@ -177,84 +159,48 @@ templ VcenterList(links []VcenterLink) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
templ VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart VcenterChartData, meta VcenterTotalsMeta) {
|
templ VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart VcenterChartData, meta VcenterTotalsMeta) {
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
@core.Header()
|
@core.Header()
|
||||||
<body class="flex flex-col min-h-screen web2-bg">
|
<body class="flex flex-col min-h-screen web2-bg">
|
||||||
<main class="flex-grow web2-shell space-y-8 max-w-screen-2xl mx-auto" style="max-width: 1400px;">
|
<main class="flex-grow web2-shell web2-shell-wide space-y-8 max-w-screen-2xl mx-auto" style="max-width: 1400px; width: 100%;">
|
||||||
<section class="web2-header">
|
<section class="web2-header">
|
||||||
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||||
<div>
|
<div>
|
||||||
<div class="web2-pill">vCenter Totals</div>
|
<div class="web2-pill">vCenter Totals</div>
|
||||||
<h1 class="mt-3 text-4xl font-bold">Totals for {vcenter}</h1>
|
<h1 class="mt-3 text-4xl font-bold">Totals for { vcenter }</h1>
|
||||||
<p class="mt-2 text-sm text-slate-600">{meta.TypeLabel} snapshots of VM count, vCPU, and RAM over time.</p>
|
<p class="mt-2 text-sm text-slate-600">{ meta.TypeLabel } snapshots of VM count, vCPU, and RAM over time.</p>
|
||||||
</div>
|
|
||||||
<div class="flex gap-3">
|
|
||||||
<a class="web2-button secondary" href="/vcenters">All vCenters</a>
|
|
||||||
<a class="web2-button" href="/">Dashboard</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="web3-button-group mt-8 mb-3">
|
<div class="flex gap-3">
|
||||||
<a class={meta.HourlyClass} href={meta.HourlyLink}>Hourly</a>
|
<a class="web2-button secondary" href="/vcenters">All vCenters</a>
|
||||||
<a class={meta.DailyClass} href={meta.DailyLink}>Daily</a>
|
<a class="web2-button" href="/">Dashboard</a>
|
||||||
<a class={meta.MonthlyClass} href={meta.MonthlyLink}>Monthly</a>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
|
<div class="web3-button-group mt-8 mb-3">
|
||||||
<section class="web2-card">
|
<a class={ meta.HourlyClass } href={ meta.HourlyLink }>Hourly</a>
|
||||||
<div class="flex items-center justify-between gap-3 mb-4 flex-wrap">
|
<a class={ meta.DailyClass } href={ meta.DailyLink }>Daily</a>
|
||||||
<h2 class="text-lg font-semibold">{meta.TypeLabel} Snapshots</h2>
|
<a class={ meta.MonthlyClass } href={ meta.MonthlyLink }>Monthly</a>
|
||||||
<span class="web2-badge">{len(entries)} records</span>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
if chart.PointsVm != "" {
|
<section class="web2-card">
|
||||||
|
<div class="flex items-center justify-between gap-3 mb-4 flex-wrap">
|
||||||
|
<h2 class="text-lg font-semibold">{ meta.TypeLabel } Snapshots</h2>
|
||||||
|
<span class="web2-badge">{ len(entries) } records</span>
|
||||||
|
</div>
|
||||||
|
if chart.ConfigJSON != "" {
|
||||||
<div class="mb-6 overflow-auto">
|
<div class="mb-6 overflow-auto">
|
||||||
<svg width="100%" height={fmt.Sprintf("%d", chart.Height+80)} viewBox={"0 0 " + fmt.Sprintf("%d", chart.Width) + " " + fmt.Sprintf("%d", chart.Height+70)} role="img" aria-label="Totals over time">
|
<div class="web3-chart-frame">
|
||||||
<defs>
|
<canvas id="vcenter-totals-chart" class="web3-chart-canvas" role="img" aria-label="Totals over time" data-chart-config={ chart.ConfigJSON }></canvas>
|
||||||
<linearGradient id="grid" x1="0" y1="0" x2="0" y2="1">
|
<div id="vcenter-totals-tooltip" class="web3-chart-tooltip" aria-hidden="true"></div>
|
||||||
<stop offset="0%" stop-color="#e2e8f0" stop-opacity="0.6"></stop>
|
</div>
|
||||||
</linearGradient>
|
<script>
|
||||||
</defs>
|
window.Web3Charts.renderFromDataset({
|
||||||
<rect x="40" y="10" width={fmt.Sprintf("%d", chart.Width-60)} height={fmt.Sprintf("%d", chart.Height)} fill="white" stroke="#e2e8f0"></rect>
|
canvasId: "vcenter-totals-chart",
|
||||||
<!-- grid lines -->
|
tooltipId: "vcenter-totals-tooltip",
|
||||||
<g stroke="#e2e8f0" stroke-width="1" stroke-dasharray="2,4">
|
})
|
||||||
for _, y := range chart.GridY {
|
</script>
|
||||||
<line x1="40" y1={fmt.Sprintf("%.1f", y)} x2={fmt.Sprintf("%d", chart.Width-20)} y2={fmt.Sprintf("%.1f", y)} />
|
|
||||||
}
|
|
||||||
for _, x := range chart.GridX {
|
|
||||||
<line x1={fmt.Sprintf("%.1f", x)} y1="10" x2={fmt.Sprintf("%.1f", x)} y2={fmt.Sprintf("%d", chart.Height+10)} />
|
|
||||||
}
|
|
||||||
</g>
|
|
||||||
<!-- axes -->
|
|
||||||
<line x1="40" y1={fmt.Sprintf("%d", chart.Height+10)} x2={fmt.Sprintf("%d", chart.Width-20)} y2={fmt.Sprintf("%d", chart.Height+10)} stroke="#94a3b8" stroke-width="1.5"></line>
|
|
||||||
<line x1="40" y1="10" x2="40" y2={fmt.Sprintf("%d", chart.Height+10)} stroke="#94a3b8" stroke-width="1.5"></line>
|
|
||||||
<!-- data -->
|
|
||||||
<polyline points={chart.PointsVm} fill="none" stroke="#2563eb" stroke-width="2.5"></polyline>
|
|
||||||
<polyline points={chart.PointsVcpu} fill="none" stroke="#16a34a" stroke-width="2.5"></polyline>
|
|
||||||
<polyline points={chart.PointsRam} fill="none" stroke="#ea580c" stroke-width="2.5"></polyline>
|
|
||||||
<!-- tick labels -->
|
|
||||||
<g font-size="10" fill="#475569" text-anchor="end">
|
|
||||||
for _, tick := range chart.YTicks {
|
|
||||||
<text x="36" y={fmt.Sprintf("%.1f", tick.Pos+3)}>{tick.Label}</text>
|
|
||||||
}
|
|
||||||
</g>
|
|
||||||
<g font-size="10" fill="#475569" text-anchor="middle">
|
|
||||||
for _, tick := range chart.XTicks {
|
|
||||||
<text x={fmt.Sprintf("%.1f", tick.Pos)} y={fmt.Sprintf("%d", chart.Height+24)}>{tick.Label}</text>
|
|
||||||
}
|
|
||||||
</g>
|
|
||||||
<!-- legend -->
|
|
||||||
<g font-size="12" fill="#475569" transform={"translate(40 " + fmt.Sprintf("%d", chart.Height+54) + ")"}>
|
|
||||||
<rect x="0" y="0" width="14" height="8" fill="#2563eb"></rect><text x="22" y="12">VMs</text>
|
|
||||||
<rect x="90" y="0" width="14" height="8" fill="#16a34a"></rect><text x="112" y="12">vCPU</text>
|
|
||||||
<rect x="180" y="0" width="14" height="8" fill="#ea580c"></rect><text x="202" y="12">RAM (GB)</text>
|
|
||||||
</g>
|
|
||||||
<!-- axis labels -->
|
|
||||||
<text x="15" y="20" transform={"rotate(-90 15 20)"} font-size="12" fill="#475569">Totals</text>
|
|
||||||
<text x={fmt.Sprintf("%d", chart.Width/2)} y={fmt.Sprintf("%d", chart.Height+70)} font-size="12" fill="#475569">Snapshot sequence (newest right)</text>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="overflow-hidden border border-slate-200 rounded">
|
<div class="overflow-hidden border border-slate-200 rounded">
|
||||||
<table class="web2-table">
|
<table class="web2-table">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -268,10 +214,10 @@ templ VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcen
|
|||||||
<tbody>
|
<tbody>
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
<tr>
|
<tr>
|
||||||
<td>{entry.Snapshot}</td>
|
<td>{ entry.Snapshot }</td>
|
||||||
<td class="text-right">{entry.VmCount}</td>
|
<td class="text-right">{ entry.VmCount }</td>
|
||||||
<td class="text-right">{entry.VcpuTotal}</td>
|
<td class="text-right">{ entry.VcpuTotal }</td>
|
||||||
<td class="text-right">{entry.RamTotalGB}</td>
|
<td class="text-right">{ entry.RamTotalGB }</td>
|
||||||
</tr>
|
</tr>
|
||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ package views
|
|||||||
import "github.com/a-h/templ"
|
import "github.com/a-h/templ"
|
||||||
import templruntime "github.com/a-h/templ/runtime"
|
import templruntime "github.com/a-h/templ/runtime"
|
||||||
|
|
||||||
import (
|
import "vctp/components/core"
|
||||||
"fmt"
|
|
||||||
"vctp/components/core"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SnapshotEntry struct {
|
type SnapshotEntry struct {
|
||||||
Label string
|
Label string
|
||||||
@@ -45,20 +42,7 @@ type VcenterTotalsMeta struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VcenterChartData struct {
|
type VcenterChartData struct {
|
||||||
PointsVm string
|
ConfigJSON string
|
||||||
PointsVcpu string
|
|
||||||
PointsRam string
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
GridX []float64
|
|
||||||
GridY []float64
|
|
||||||
YTicks []ChartTick
|
|
||||||
XTicks []ChartTick
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChartTick struct {
|
|
||||||
Pos float64
|
|
||||||
Label string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SnapshotHourlyList(entries []SnapshotEntry) templ.Component {
|
func SnapshotHourlyList(entries []SnapshotEntry) templ.Component {
|
||||||
@@ -184,7 +168,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var5 string
|
var templ_7745c5c3_Var5 string
|
||||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(title)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 78, Col: 49}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 62, Col: 50}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -197,7 +181,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var6 string
|
var templ_7745c5c3_Var6 string
|
||||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(subtitle)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 79, Col: 55}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 63, Col: 56}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -210,7 +194,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var7 string
|
var templ_7745c5c3_Var7 string
|
||||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(len(entries))
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(len(entries))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 88, Col: 44}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 71, Col: 45}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -229,7 +213,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var8 string
|
var templ_7745c5c3_Var8 string
|
||||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Group)
|
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Group)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 103, Col: 76}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 86, Col: 77}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -247,7 +231,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var9 string
|
var templ_7745c5c3_Var9 string
|
||||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Label)
|
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Label)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 109, Col: 75}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 92, Col: 76}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -260,7 +244,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var10 string
|
var templ_7745c5c3_Var10 string
|
||||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Count)
|
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Count)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 113, Col: 48}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 96, Col: 49}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -273,7 +257,7 @@ func SnapshotListPage(title string, subtitle string, entries []SnapshotEntry) te
|
|||||||
var templ_7745c5c3_Var11 templ.SafeURL
|
var templ_7745c5c3_Var11 templ.SafeURL
|
||||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinURLErrs(entry.Link)
|
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinURLErrs(entry.Link)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 116, Col: 48}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 99, Col: 49}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -336,7 +320,7 @@ func VcenterList(links []VcenterLink) templ.Component {
|
|||||||
var templ_7745c5c3_Var13 string
|
var templ_7745c5c3_Var13 string
|
||||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(len(links))
|
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(len(links))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 150, Col: 42}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 132, Col: 43}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -354,7 +338,7 @@ func VcenterList(links []VcenterLink) templ.Component {
|
|||||||
var templ_7745c5c3_Var14 string
|
var templ_7745c5c3_Var14 string
|
||||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(link.Name)
|
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(link.Name)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 163, Col: 61}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 145, Col: 62}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -367,7 +351,7 @@ func VcenterList(links []VcenterLink) templ.Component {
|
|||||||
var templ_7745c5c3_Var15 templ.SafeURL
|
var templ_7745c5c3_Var15 templ.SafeURL
|
||||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinURLErrs(link.Link)
|
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinURLErrs(link.Link)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 165, Col: 47}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 147, Col: 48}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -423,14 +407,14 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<body class=\"flex flex-col min-h-screen web2-bg\"><main class=\"flex-grow web2-shell space-y-8 max-w-screen-2xl mx-auto\" style=\"max-width: 1400px;\"><section class=\"web2-header\"><div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\"><div><div class=\"web2-pill\">vCenter Totals</div><h1 class=\"mt-3 text-4xl font-bold\">Totals for ")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "<body class=\"flex flex-col min-h-screen web2-bg\"><main class=\"flex-grow web2-shell web2-shell-wide space-y-8 max-w-screen-2xl mx-auto\" style=\"max-width: 1400px; width: 100%;\"><section class=\"web2-header\"><div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\"><div><div class=\"web2-pill\">vCenter Totals</div><h1 class=\"mt-3 text-4xl font-bold\">Totals for ")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var17 string
|
var templ_7745c5c3_Var17 string
|
||||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(vcenter)
|
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(vcenter)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 189, Col: 63}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 171, Col: 63}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -443,7 +427,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
var templ_7745c5c3_Var18 string
|
var templ_7745c5c3_Var18 string
|
||||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(meta.TypeLabel)
|
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(meta.TypeLabel)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 190, Col: 62}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 172, Col: 62}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -478,7 +462,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
var templ_7745c5c3_Var21 templ.SafeURL
|
var templ_7745c5c3_Var21 templ.SafeURL
|
||||||
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinURLErrs(meta.HourlyLink)
|
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinURLErrs(meta.HourlyLink)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 198, Col: 56}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 180, Col: 58}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -513,7 +497,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
var templ_7745c5c3_Var24 templ.SafeURL
|
var templ_7745c5c3_Var24 templ.SafeURL
|
||||||
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinURLErrs(meta.DailyLink)
|
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinURLErrs(meta.DailyLink)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 199, Col: 54}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 181, Col: 56}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -548,7 +532,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
var templ_7745c5c3_Var27 templ.SafeURL
|
var templ_7745c5c3_Var27 templ.SafeURL
|
||||||
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(meta.MonthlyLink)
|
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinURLErrs(meta.MonthlyLink)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 200, Col: 58}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 182, Col: 60}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -561,7 +545,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
var templ_7745c5c3_Var28 string
|
var templ_7745c5c3_Var28 string
|
||||||
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(meta.TypeLabel)
|
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(meta.TypeLabel)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 206, Col: 56}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 187, Col: 56}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -574,7 +558,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
var templ_7745c5c3_Var29 string
|
var templ_7745c5c3_Var29 string
|
||||||
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(len(entries))
|
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(len(entries))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 207, Col: 45}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 188, Col: 45}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -584,449 +568,88 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
if chart.PointsVm != "" {
|
if chart.ConfigJSON != "" {
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div class=\"mb-6 overflow-auto\"><svg width=\"100%\" height=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "<div class=\"mb-6 overflow-auto\"><div class=\"web3-chart-frame\"><canvas id=\"vcenter-totals-chart\" class=\"web3-chart-canvas\" role=\"img\" aria-label=\"Totals over time\" data-chart-config=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var30 string
|
var templ_7745c5c3_Var30 string
|
||||||
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+80))
|
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(chart.ConfigJSON)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 211, Col: 67}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 193, Col: 145}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "\" viewBox=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "\"></canvas><div id=\"vcenter-totals-tooltip\" class=\"web3-chart-tooltip\" aria-hidden=\"true\"></div></div><script>\n\t\t\t\t\t\t\t\twindow.Web3Charts.renderFromDataset({\n\t\t\t\t\t\t\t\t\tcanvasId: \"vcenter-totals-chart\",\n\t\t\t\t\t\t\t\t\ttooltipId: \"vcenter-totals-tooltip\",\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t</script></div>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "<div class=\"overflow-hidden border border-slate-200 rounded\"><table class=\"web2-table\"><thead><tr><th>Snapshot Time</th><th class=\"text-right\">VMs</th><th class=\"text-right\">vCPUs</th><th class=\"text-right\">RAM (GB)</th></tr></thead> <tbody>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
for _, entry := range entries {
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "<tr><td>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var31 string
|
var templ_7745c5c3_Var31 string
|
||||||
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs("0 0 " + fmt.Sprintf("%d", chart.Width) + " " + fmt.Sprintf("%d", chart.Height+70))
|
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Snapshot)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 211, Col: 160}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 217, Col: 30}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "\" role=\"img\" aria-label=\"Totals over time\"><defs><linearGradient id=\"grid\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\"><stop offset=\"0%\" stop-color=\"#e2e8f0\" stop-opacity=\"0.6\"></stop></linearGradient></defs> <rect x=\"40\" y=\"10\" width=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "</td><td class=\"text-right\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var32 string
|
var templ_7745c5c3_Var32 string
|
||||||
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width-60))
|
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(entry.VmCount)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 217, Col: 68}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 218, Col: 48}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\" height=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "</td><td class=\"text-right\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var33 string
|
var templ_7745c5c3_Var33 string
|
||||||
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height))
|
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(entry.VcpuTotal)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 217, Col: 109}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 219, Col: 50}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "\" fill=\"white\" stroke=\"#e2e8f0\"></rect><!-- grid lines --><g stroke=\"#e2e8f0\" stroke-width=\"1\" stroke-dasharray=\"2,4\">")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "</td><td class=\"text-right\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
for _, y := range chart.GridY {
|
var templ_7745c5c3_Var34 string
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "<line x1=\"40\" y1=\"")
|
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(entry.RamTotalGB)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 220, Col: 51}
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var34 string
|
|
||||||
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", y))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 221, Col: 51}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "\" x2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var35 string
|
|
||||||
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width-20))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 221, Col: 90}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "\" y2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var36 string
|
|
||||||
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", y))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 221, Col: 118}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "\"></line> ")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, x := range chart.GridX {
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<line x1=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var37 string
|
|
||||||
templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", x))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 224, Col: 43}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\" y1=\"10\" x2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var38 string
|
|
||||||
templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", x))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 224, Col: 79}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "\" y2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var39 string
|
|
||||||
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 224, Col: 119}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "\"></line>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</g><!-- axes --><line x1=\"40\" y1=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var40 string
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "</td></tr>")
|
||||||
templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 228, Col: 61}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "\" x2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var41 string
|
|
||||||
templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width-20))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 228, Col: 100}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "\" y2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var42 string
|
|
||||||
templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 228, Col: 140}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "\" stroke=\"#94a3b8\" stroke-width=\"1.5\"></line> <line x1=\"40\" y1=\"10\" x2=\"40\" y2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var43 string
|
|
||||||
templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 229, Col: 77}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "\" stroke=\"#94a3b8\" stroke-width=\"1.5\"></line><!-- data --><polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var44 string
|
|
||||||
templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsVm)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 231, Col: 40}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "\" fill=\"none\" stroke=\"#2563eb\" stroke-width=\"2.5\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var45 string
|
|
||||||
templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsVcpu)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 232, Col: 42}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "\" fill=\"none\" stroke=\"#16a34a\" stroke-width=\"2.5\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var46 string
|
|
||||||
templ_7745c5c3_Var46, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsRam)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 233, Col: 41}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var46))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "\" fill=\"none\" stroke=\"#ea580c\" stroke-width=\"2.5\"></polyline><!-- tick labels --><g font-size=\"10\" fill=\"#475569\" text-anchor=\"end\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
for _, tick := range chart.YTicks {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "<text x=\"36\" y=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var47 string
|
|
||||||
templ_7745c5c3_Var47, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", tick.Pos+3))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 237, Col: 58}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var47))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var48 string
|
|
||||||
templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(tick.Label)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 237, Col: 71}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "</text>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "</g> <g font-size=\"10\" fill=\"#475569\" text-anchor=\"middle\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
for _, tick := range chart.XTicks {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "<text x=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var49 string
|
|
||||||
templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", tick.Pos))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 242, Col: 49}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "\" y=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var50 string
|
|
||||||
templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+24))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 242, Col: 88}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var51 string
|
|
||||||
templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(tick.Label)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 242, Col: 101}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "</text>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "</g><!-- legend --><g font-size=\"12\" fill=\"#475569\" transform=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var52 string
|
|
||||||
templ_7745c5c3_Var52, templ_7745c5c3_Err = templ.JoinStringErrs("translate(40 " + fmt.Sprintf("%d", chart.Height+54) + ")")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 246, Col: 111}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var52))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "\"><rect x=\"0\" y=\"0\" width=\"14\" height=\"8\" fill=\"#2563eb\"></rect><text x=\"22\" y=\"12\">VMs</text> <rect x=\"90\" y=\"0\" width=\"14\" height=\"8\" fill=\"#16a34a\"></rect><text x=\"112\" y=\"12\">vCPU</text> <rect x=\"180\" y=\"0\" width=\"14\" height=\"8\" fill=\"#ea580c\"></rect><text x=\"202\" y=\"12\">RAM (GB)</text></g><!-- axis labels --><text x=\"15\" y=\"20\" transform=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var53 string
|
|
||||||
templ_7745c5c3_Var53, templ_7745c5c3_Err = templ.JoinStringErrs("rotate(-90 15 20)")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 252, Col: 59}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var53))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "\" font-size=\"12\" fill=\"#475569\">Totals</text> <text x=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var54 string
|
|
||||||
templ_7745c5c3_Var54, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width/2))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 253, Col: 50}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var54))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\" y=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var55 string
|
|
||||||
templ_7745c5c3_Var55, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+70))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 253, Col: 89}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var55))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "\" font-size=\"12\" fill=\"#475569\">Snapshot sequence (newest right)</text></svg></div>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "<div class=\"overflow-hidden border border-slate-200 rounded\"><table class=\"web2-table\"><thead><tr><th>Snapshot Time</th><th class=\"text-right\">VMs</th><th class=\"text-right\">vCPUs</th><th class=\"text-right\">RAM (GB)</th></tr></thead> <tbody>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "</tbody></table></div></section></main></body>")
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
for _, entry := range entries {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "<tr><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var56 string
|
|
||||||
templ_7745c5c3_Var56, templ_7745c5c3_Err = templ.JoinStringErrs(entry.Snapshot)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 271, Col: 29}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var56))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "</td><td class=\"text-right\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var57 string
|
|
||||||
templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(entry.VmCount)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 272, Col: 47}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "</td><td class=\"text-right\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var58 string
|
|
||||||
templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(entry.VcpuTotal)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 273, Col: 49}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var58))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "</td><td class=\"text-right\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var59 string
|
|
||||||
templ_7745c5c3_Var59, templ_7745c5c3_Err = templ.JoinStringErrs(entry.RamTotalGB)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/snapshots.templ`, Line: 274, Col: 50}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var59))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "</td></tr>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "</tbody></table></div></section></main></body>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@@ -1034,7 +657,7 @@ func VcenterTotalsPage(vcenter string, entries []VcenterTotalsEntry, chart Vcent
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "</html>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "</html>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,18 +21,7 @@ type VmTraceEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VmTraceChart struct {
|
type VmTraceChart struct {
|
||||||
PointsVcpu string
|
ConfigJSON string
|
||||||
PointsRam string
|
|
||||||
PointsTin string
|
|
||||||
PointsBronze string
|
|
||||||
PointsSilver string
|
|
||||||
PointsGold string
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
GridX []float64
|
|
||||||
GridY []float64
|
|
||||||
XTicks []ChartTick
|
|
||||||
YTicks []ChartTick
|
|
||||||
}
|
}
|
||||||
|
|
||||||
templ VmTracePage(query string, display_query string, vm_id string, vm_uuid string, vm_name string, creationLabel string, deletionLabel string, creationApprox bool, entries []VmTraceEntry, chart VmTraceChart) {
|
templ VmTracePage(query string, display_query string, vm_id string, vm_uuid string, vm_name string, creationLabel string, deletionLabel string, creationApprox bool, entries []VmTraceEntry, chart VmTraceChart) {
|
||||||
@@ -40,7 +29,7 @@ templ VmTracePage(query string, display_query string, vm_id string, vm_uuid stri
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
@core.Header()
|
@core.Header()
|
||||||
<body class="flex flex-col min-h-screen web2-bg">
|
<body class="flex flex-col min-h-screen web2-bg">
|
||||||
<main class="flex-grow web2-shell space-y-8 max-w-screen-2xl mx-auto" style="max-width: 1400px;">
|
<main class="flex-grow web2-shell web2-shell-wide space-y-8 max-w-screen-2xl mx-auto">
|
||||||
<section class="web2-header">
|
<section class="web2-header">
|
||||||
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
<div class="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
|
||||||
<div>
|
<div>
|
||||||
@@ -77,47 +66,18 @@ templ VmTracePage(query string, display_query string, vm_id string, vm_uuid stri
|
|||||||
<h2 class="text-lg font-semibold">Snapshot Timeline</h2>
|
<h2 class="text-lg font-semibold">Snapshot Timeline</h2>
|
||||||
<span class="web2-badge">{len(entries)} samples</span>
|
<span class="web2-badge">{len(entries)} samples</span>
|
||||||
</div>
|
</div>
|
||||||
if chart.PointsVcpu != "" {
|
if chart.ConfigJSON != "" {
|
||||||
<div class="mb-6 overflow-auto">
|
<div class="mb-6 overflow-auto">
|
||||||
<svg width="100%" height="360" viewBox={"0 0 " + fmt.Sprintf("%d", chart.Width) + " 320"} role="img" aria-label="VM timeline">
|
<div class="web3-chart-frame">
|
||||||
<rect x="40" y="10" width={fmt.Sprintf("%d", chart.Width-60)} height={fmt.Sprintf("%d", chart.Height)} fill="white" stroke="#e2e8f0"></rect>
|
<canvas id="vm-trace-chart" class="web3-chart-canvas" role="img" aria-label="VM timeline" data-chart-config={chart.ConfigJSON}></canvas>
|
||||||
<g stroke="#e2e8f0" stroke-width="1" stroke-dasharray="2,4">
|
<div id="vm-trace-tooltip" class="web3-chart-tooltip" aria-hidden="true"></div>
|
||||||
for _, y := range chart.GridY {
|
</div>
|
||||||
<line x1="40" y1={fmt.Sprintf("%.1f", y)} x2={fmt.Sprintf("%d", chart.Width-20)} y2={fmt.Sprintf("%.1f", y)} />
|
<script>
|
||||||
}
|
window.Web3Charts.renderFromDataset({
|
||||||
for _, x := range chart.GridX {
|
canvasId: "vm-trace-chart",
|
||||||
<line x1={fmt.Sprintf("%.1f", x)} y1="10" x2={fmt.Sprintf("%.1f", x)} y2={fmt.Sprintf("%d", chart.Height+10)} />
|
tooltipId: "vm-trace-tooltip",
|
||||||
}
|
})
|
||||||
</g>
|
</script>
|
||||||
<line x1="40" y1={fmt.Sprintf("%d", chart.Height+10)} x2={fmt.Sprintf("%d", chart.Width-20)} y2={fmt.Sprintf("%d", chart.Height+10)} stroke="#94a3b8" stroke-width="1.5"></line>
|
|
||||||
<line x1="40" y1="10" x2="40" y2={fmt.Sprintf("%d", chart.Height+10)} stroke="#94a3b8" stroke-width="1.5"></line>
|
|
||||||
<polyline points={chart.PointsVcpu} fill="none" stroke="#2563eb" stroke-width="2.5"></polyline>
|
|
||||||
<polyline points={chart.PointsRam} fill="none" stroke="#16a34a" stroke-width="2.5"></polyline>
|
|
||||||
<polyline points={chart.PointsTin} fill="none" stroke="#0ea5e9" stroke-width="1.5" stroke-dasharray="4,4"></polyline>
|
|
||||||
<polyline points={chart.PointsBronze} fill="none" stroke="#a855f7" stroke-width="1.5" stroke-dasharray="4,4"></polyline>
|
|
||||||
<polyline points={chart.PointsSilver} fill="none" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="4,4"></polyline>
|
|
||||||
<polyline points={chart.PointsGold} fill="none" stroke="#f59e0b" stroke-width="1.5" stroke-dasharray="4,4"></polyline>
|
|
||||||
<g font-size="10" fill="#475569" text-anchor="end">
|
|
||||||
for _, tick := range chart.YTicks {
|
|
||||||
<text x="36" y={fmt.Sprintf("%.1f", tick.Pos+3)}>{tick.Label}</text>
|
|
||||||
}
|
|
||||||
</g>
|
|
||||||
<g font-size="10" fill="#475569" text-anchor="middle">
|
|
||||||
for _, tick := range chart.XTicks {
|
|
||||||
<text x={fmt.Sprintf("%.1f", tick.Pos)} y={fmt.Sprintf("%d", chart.Height+24)}>{tick.Label}</text>
|
|
||||||
}
|
|
||||||
</g>
|
|
||||||
<g font-size="12" fill="#475569" transform={"translate(40 " + fmt.Sprintf("%d", chart.Height+50) + ")"}>
|
|
||||||
<rect x="0" y="0" width="14" height="8" fill="#2563eb"></rect><text x="22" y="12">vCPU</text>
|
|
||||||
<rect x="90" y="0" width="14" height="8" fill="#16a34a"></rect><text x="112" y="12">RAM (GB)</text>
|
|
||||||
<rect x="200" y="0" width="14" height="8" fill="#0ea5e9"></rect><text x="222" y="12">Tin</text>
|
|
||||||
<rect x="260" y="0" width="14" height="8" fill="#a855f7"></rect><text x="282" y="12">Bronze</text>
|
|
||||||
<rect x="340" y="0" width="14" height="8" fill="#94a3b8"></rect><text x="362" y="12">Silver</text>
|
|
||||||
<rect x="420" y="0" width="14" height="8" fill="#f59e0b"></rect><text x="442" y="12">Gold</text>
|
|
||||||
</g>
|
|
||||||
<text x="15" y="20" transform={"rotate(-90 15 20)"} font-size="12" fill="#475569">Resources / Pool</text>
|
|
||||||
<text x={fmt.Sprintf("%d", chart.Width/2)} y={fmt.Sprintf("%d", chart.Height+70)} font-size="12" fill="#475569">Snapshots (oldest left, newest right)</text>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<div class="grid gap-3 md:grid-cols-2 mb-4">
|
<div class="grid gap-3 md:grid-cols-2 mb-4">
|
||||||
|
|||||||
@@ -29,18 +29,7 @@ type VmTraceEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type VmTraceChart struct {
|
type VmTraceChart struct {
|
||||||
PointsVcpu string
|
ConfigJSON string
|
||||||
PointsRam string
|
|
||||||
PointsTin string
|
|
||||||
PointsBronze string
|
|
||||||
PointsSilver string
|
|
||||||
PointsGold string
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
GridX []float64
|
|
||||||
GridY []float64
|
|
||||||
XTicks []ChartTick
|
|
||||||
YTicks []ChartTick
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func VmTracePage(query string, display_query string, vm_id string, vm_uuid string, vm_name string, creationLabel string, deletionLabel string, creationApprox bool, entries []VmTraceEntry, chart VmTraceChart) templ.Component {
|
func VmTracePage(query string, display_query string, vm_id string, vm_uuid string, vm_name string, creationLabel string, deletionLabel string, creationApprox bool, entries []VmTraceEntry, chart VmTraceChart) templ.Component {
|
||||||
@@ -72,14 +61,14 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<body class=\"flex flex-col min-h-screen web2-bg\"><main class=\"flex-grow web2-shell space-y-8 max-w-screen-2xl mx-auto\" style=\"max-width: 1400px;\"><section class=\"web2-header\"><div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\"><div><div class=\"web2-pill\">VM Trace</div><h1 class=\"mt-3 text-4xl font-bold\">Snapshot history")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<body class=\"flex flex-col min-h-screen web2-bg\"><main class=\"flex-grow web2-shell web2-shell-wide space-y-8 max-w-screen-2xl mx-auto\"><section class=\"web2-header\"><div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\"><div><div class=\"web2-pill\">VM Trace</div><h1 class=\"mt-3 text-4xl font-bold\">Snapshot history")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var2 string
|
var templ_7745c5c3_Var2 string
|
||||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(display_query)
|
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(display_query)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 48, Col: 74}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 37, Col: 74}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -92,7 +81,7 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
var templ_7745c5c3_Var3 string
|
var templ_7745c5c3_Var3 string
|
||||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(vm_id)
|
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(vm_id)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 58, Col: 123}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 47, Col: 123}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -105,7 +94,7 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
var templ_7745c5c3_Var4 string
|
var templ_7745c5c3_Var4 string
|
||||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(vm_uuid)
|
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(vm_uuid)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 62, Col: 129}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 51, Col: 129}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -118,7 +107,7 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
var templ_7745c5c3_Var5 string
|
var templ_7745c5c3_Var5 string
|
||||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(vm_name)
|
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(vm_name)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 66, Col: 123}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 55, Col: 123}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -131,7 +120,7 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
var templ_7745c5c3_Var6 string
|
var templ_7745c5c3_Var6 string
|
||||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(len(entries))
|
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(len(entries))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 78, Col: 44}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 67, Col: 44}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
@@ -141,576 +130,189 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
if chart.PointsVcpu != "" {
|
if chart.ConfigJSON != "" {
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<div class=\"mb-6 overflow-auto\"><svg width=\"100%\" height=\"360\" viewBox=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<div class=\"mb-6 overflow-auto\"><div class=\"web3-chart-frame\"><canvas id=\"vm-trace-chart\" class=\"web3-chart-canvas\" role=\"img\" aria-label=\"VM timeline\" data-chart-config=\"")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var7 string
|
var templ_7745c5c3_Var7 string
|
||||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs("0 0 " + fmt.Sprintf("%d", chart.Width) + " 320")
|
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(chart.ConfigJSON)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 82, Col: 95}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 72, Col: 133}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\" role=\"img\" aria-label=\"VM timeline\"><rect x=\"40\" y=\"10\" width=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\"></canvas><div id=\"vm-trace-tooltip\" class=\"web3-chart-tooltip\" aria-hidden=\"true\"></div></div><script>\n\t\t\t\t\t\t\t\twindow.Web3Charts.renderFromDataset({\n\t\t\t\t\t\t\t\t\tcanvasId: \"vm-trace-chart\",\n\t\t\t\t\t\t\t\t\ttooltipId: \"vm-trace-tooltip\",\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t</script></div>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var8 string
|
}
|
||||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width-60))
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<div class=\"grid gap-3 md:grid-cols-2 mb-4\"><div class=\"web2-card\"><p class=\"text-xs uppercase tracking-[0.15em] text-slate-500\">Creation time</p><p class=\"mt-2 text-base font-semibold text-slate-800\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 83, Col: 68}
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
var templ_7745c5c3_Var8 string
|
||||||
|
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(creationLabel)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 86, Col: 76}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "</p>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
if creationApprox {
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<p class=\"text-xs text-slate-500 mt-1\">Approximate (earliest snapshot)</p>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\" height=\"")
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "</div><div class=\"web2-card\"><p class=\"text-xs uppercase tracking-[0.15em] text-slate-500\">Deletion time</p><p class=\"mt-2 text-base font-semibold text-slate-800\">")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var9 string
|
||||||
|
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(deletionLabel)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 93, Col: 76}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "</p></div></div><div class=\"overflow-hidden border border-slate-200 rounded\"><table class=\"web2-table\"><thead><tr><th>Snapshot</th><th>VM Name</th><th>VmId</th><th>VmUuid</th><th>Vcenter</th><th>Resource Pool</th><th class=\"text-right\">vCPUs</th><th class=\"text-right\">RAM (GB)</th><th class=\"text-right\">Disk</th></tr></thead> <tbody>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
for _, e := range entries {
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<tr><td>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var9 string
|
var templ_7745c5c3_Var10 string
|
||||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height))
|
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(e.Snapshot)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 83, Col: 109}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 114, Col: 25}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\" fill=\"white\" stroke=\"#e2e8f0\"></rect> <g stroke=\"#e2e8f0\" stroke-width=\"1\" stroke-dasharray=\"2,4\">")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</td><td>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
for _, y := range chart.GridY {
|
var templ_7745c5c3_Var11 string
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<line x1=\"40\" y1=\"")
|
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(e.Name)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 115, Col: 21}
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var10 string
|
|
||||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", y))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 86, Col: 50}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\" x2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var11 string
|
|
||||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width-20))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 86, Col: 89}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\" y2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var12 string
|
|
||||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", y))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 86, Col: 117}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\"></line> ")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, x := range chart.GridX {
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<line x1=\"")
|
if templ_7745c5c3_Err != nil {
|
||||||
if templ_7745c5c3_Err != nil {
|
return templ_7745c5c3_Err
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var13 string
|
|
||||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", x))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 89, Col: 42}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\" y1=\"10\" x2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var14 string
|
|
||||||
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", x))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 89, Col: 78}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\" y2=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var15 string
|
|
||||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 89, Col: 118}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\"></line>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</g> <line x1=\"40\" y1=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "</td><td>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var12 string
|
||||||
|
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(e.VmId)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 116, Col: 21}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "</td><td>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var13 string
|
||||||
|
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(e.VmUuid)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 117, Col: 23}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "</td><td>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var14 string
|
||||||
|
templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(e.Vcenter)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 118, Col: 24}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "</td><td>")
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
var templ_7745c5c3_Var15 string
|
||||||
|
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(e.ResourcePool)
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 119, Col: 29}
|
||||||
|
}
|
||||||
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||||
|
if templ_7745c5c3_Err != nil {
|
||||||
|
return templ_7745c5c3_Err
|
||||||
|
}
|
||||||
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "</td><td class=\"text-right\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var16 string
|
var templ_7745c5c3_Var16 string
|
||||||
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(e.VcpuCount)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 92, Col: 60}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 120, Col: 45}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\" x2=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "</td><td class=\"text-right\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var17 string
|
var templ_7745c5c3_Var17 string
|
||||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width-20))
|
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(e.RamGB)
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 92, Col: 99}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 121, Col: 41}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "\" y2=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "</td><td class=\"text-right\">")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
var templ_7745c5c3_Var18 string
|
var templ_7745c5c3_Var18 string
|
||||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", e.ProvisionedDisk))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 92, Col: 139}
|
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 122, Col: 72}
|
||||||
}
|
}
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\" stroke=\"#94a3b8\" stroke-width=\"1.5\"></line> <line x1=\"40\" y1=\"10\" x2=\"40\" y2=\"")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "</td></tr>")
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var19 string
|
|
||||||
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+10))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 93, Col: 76}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\" stroke=\"#94a3b8\" stroke-width=\"1.5\"></line> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var20 string
|
|
||||||
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsVcpu)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 94, Col: 42}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "\" fill=\"none\" stroke=\"#2563eb\" stroke-width=\"2.5\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var21 string
|
|
||||||
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsRam)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 95, Col: 41}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "\" fill=\"none\" stroke=\"#16a34a\" stroke-width=\"2.5\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var22 string
|
|
||||||
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsTin)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 96, Col: 41}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "\" fill=\"none\" stroke=\"#0ea5e9\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var23 string
|
|
||||||
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsBronze)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 97, Col: 44}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "\" fill=\"none\" stroke=\"#a855f7\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var24 string
|
|
||||||
templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsSilver)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 98, Col: 44}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "\" fill=\"none\" stroke=\"#94a3b8\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\"></polyline> <polyline points=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var25 string
|
|
||||||
templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(chart.PointsGold)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 99, Col: 42}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\" fill=\"none\" stroke=\"#f59e0b\" stroke-width=\"1.5\" stroke-dasharray=\"4,4\"></polyline> <g font-size=\"10\" fill=\"#475569\" text-anchor=\"end\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
for _, tick := range chart.YTicks {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "<text x=\"36\" y=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var26 string
|
|
||||||
templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", tick.Pos+3))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 102, Col: 57}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var27 string
|
|
||||||
templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(tick.Label)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 102, Col: 70}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "</text>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "</g> <g font-size=\"10\" fill=\"#475569\" text-anchor=\"middle\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
for _, tick := range chart.XTicks {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "<text x=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var28 string
|
|
||||||
templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", tick.Pos))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 107, Col: 48}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "\" y=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var29 string
|
|
||||||
templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+24))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 107, Col: 87}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var30 string
|
|
||||||
templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(tick.Label)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 107, Col: 100}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "</text>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "</g> <g font-size=\"12\" fill=\"#475569\" transform=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var31 string
|
|
||||||
templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs("translate(40 " + fmt.Sprintf("%d", chart.Height+50) + ")")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 110, Col: 110}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "\"><rect x=\"0\" y=\"0\" width=\"14\" height=\"8\" fill=\"#2563eb\"></rect><text x=\"22\" y=\"12\">vCPU</text> <rect x=\"90\" y=\"0\" width=\"14\" height=\"8\" fill=\"#16a34a\"></rect><text x=\"112\" y=\"12\">RAM (GB)</text> <rect x=\"200\" y=\"0\" width=\"14\" height=\"8\" fill=\"#0ea5e9\"></rect><text x=\"222\" y=\"12\">Tin</text> <rect x=\"260\" y=\"0\" width=\"14\" height=\"8\" fill=\"#a855f7\"></rect><text x=\"282\" y=\"12\">Bronze</text> <rect x=\"340\" y=\"0\" width=\"14\" height=\"8\" fill=\"#94a3b8\"></rect><text x=\"362\" y=\"12\">Silver</text> <rect x=\"420\" y=\"0\" width=\"14\" height=\"8\" fill=\"#f59e0b\"></rect><text x=\"442\" y=\"12\">Gold</text></g> <text x=\"15\" y=\"20\" transform=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var32 string
|
|
||||||
templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs("rotate(-90 15 20)")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 118, Col: 58}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "\" font-size=\"12\" fill=\"#475569\">Resources / Pool</text> <text x=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var33 string
|
|
||||||
templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Width/2))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 119, Col: 49}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\" y=\"")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var34 string
|
|
||||||
templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", chart.Height+70))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 119, Col: 88}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "\" font-size=\"12\" fill=\"#475569\">Snapshots (oldest left, newest right)</text></svg></div>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "<div class=\"grid gap-3 md:grid-cols-2 mb-4\"><div class=\"web2-card\"><p class=\"text-xs uppercase tracking-[0.15em] text-slate-500\">Creation time</p><p class=\"mt-2 text-base font-semibold text-slate-800\">")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "</tbody></table></div></section></main></body>")
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var35 string
|
|
||||||
templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(creationLabel)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 126, Col: 76}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "</p>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
if creationApprox {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "<p class=\"text-xs text-slate-500 mt-1\">Approximate (earliest snapshot)</p>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "</div><div class=\"web2-card\"><p class=\"text-xs uppercase tracking-[0.15em] text-slate-500\">Deletion time</p><p class=\"mt-2 text-base font-semibold text-slate-800\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var36 string
|
|
||||||
templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(deletionLabel)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 133, Col: 76}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "</p></div></div><div class=\"overflow-hidden border border-slate-200 rounded\"><table class=\"web2-table\"><thead><tr><th>Snapshot</th><th>VM Name</th><th>VmId</th><th>VmUuid</th><th>Vcenter</th><th>Resource Pool</th><th class=\"text-right\">vCPUs</th><th class=\"text-right\">RAM (GB)</th><th class=\"text-right\">Disk</th></tr></thead> <tbody>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
for _, e := range entries {
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "<tr><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var37 string
|
|
||||||
templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(e.Snapshot)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 154, Col: 25}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "</td><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var38 string
|
|
||||||
templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(e.Name)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 155, Col: 21}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "</td><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var39 string
|
|
||||||
templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(e.VmId)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 156, Col: 21}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "</td><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var40 string
|
|
||||||
templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(e.VmUuid)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 157, Col: 23}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "</td><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var41 string
|
|
||||||
templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(e.Vcenter)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 158, Col: 24}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "</td><td>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var42 string
|
|
||||||
templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(e.ResourcePool)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 159, Col: 29}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "</td><td class=\"text-right\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var43 string
|
|
||||||
templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(e.VcpuCount)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 160, Col: 45}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "</td><td class=\"text-right\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var44 string
|
|
||||||
templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(e.RamGB)
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 161, Col: 41}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "</td><td class=\"text-right\">")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
var templ_7745c5c3_Var45 string
|
|
||||||
templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f", e.ProvisionedDisk))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `views/vm_trace.templ`, Line: 162, Col: 72}
|
|
||||||
}
|
|
||||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45))
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "</td></tr>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
|
||||||
return templ_7745c5c3_Err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, "</tbody></table></div></section></main></body>")
|
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
@@ -718,7 +320,7 @@ func VmTracePage(query string, display_query string, vm_id string, vm_uuid strin
|
|||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "</html>")
|
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "</html>")
|
||||||
if templ_7745c5c3_Err != nil {
|
if templ_7745c5c3_Err != nil {
|
||||||
return templ_7745c5c3_Err
|
return templ_7745c5c3_Err
|
||||||
}
|
}
|
||||||
|
|||||||
68
dist/assets/css/web3.css
vendored
68
dist/assets/css/web3.css
vendored
@@ -17,6 +17,9 @@ body {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 2rem 1.5rem 4rem;
|
padding: 2rem 1.5rem 4rem;
|
||||||
}
|
}
|
||||||
|
.web2-shell-wide {
|
||||||
|
max-width: 1400px;
|
||||||
|
}
|
||||||
.web2-header {
|
.web2-header {
|
||||||
background: var(--web2-card);
|
background: var(--web2-card);
|
||||||
border: 1px solid var(--web2-border);
|
border: 1px solid var(--web2-border);
|
||||||
@@ -176,3 +179,68 @@ body {
|
|||||||
color: var(--web2-muted);
|
color: var(--web2-muted);
|
||||||
background: #f8fafc;
|
background: #f8fafc;
|
||||||
}
|
}
|
||||||
|
.web3-chart-frame {
|
||||||
|
position: relative;
|
||||||
|
min-width: 760px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.web3-chart-canvas {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 360px;
|
||||||
|
background: #ffffff;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
background: rgba(15, 23, 42, 0.95);
|
||||||
|
color: #f8fafc;
|
||||||
|
padding: 0.55rem 0.65rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.35;
|
||||||
|
min-width: 170px;
|
||||||
|
box-shadow: 0 10px 30px rgba(2, 6, 23, 0.25);
|
||||||
|
z-index: 20;
|
||||||
|
transition: opacity 0.08s linear;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip.visible {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip-title {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #e2e8f0;
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0.65rem;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip-label {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #cbd5e1;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip-value {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #f8fafc;
|
||||||
|
}
|
||||||
|
.web3-chart-tooltip-swatch {
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 999px;
|
||||||
|
margin-right: 0.35rem;
|
||||||
|
}
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.web3-chart-frame {
|
||||||
|
min-width: 640px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
521
dist/assets/js/web3-charts.js
vendored
Normal file
521
dist/assets/js/web3-charts.js
vendored
Normal file
@@ -0,0 +1,521 @@
|
|||||||
|
(function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function clamp(value, min, max) {
|
||||||
|
if (value < min) {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
if (value > max) {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toNumber(value) {
|
||||||
|
var num = Number(value);
|
||||||
|
return Number.isFinite(num) ? num : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHTML(value) {
|
||||||
|
return String(value)
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """)
|
||||||
|
.replace(/'/g, "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatValue(value, format) {
|
||||||
|
if (value === null || value === undefined || Number.isNaN(value)) {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
switch (format) {
|
||||||
|
case "int":
|
||||||
|
return String(Math.round(value));
|
||||||
|
case "float1":
|
||||||
|
return Number(value).toFixed(1);
|
||||||
|
case "float2":
|
||||||
|
return Number(value).toFixed(2);
|
||||||
|
default:
|
||||||
|
return String(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pickTickIndices(total, desired) {
|
||||||
|
if (total <= 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
if (total === 1) {
|
||||||
|
return [0];
|
||||||
|
}
|
||||||
|
var target = Math.max(2, Math.min(total, desired || 6));
|
||||||
|
if (target >= total) {
|
||||||
|
var all = [];
|
||||||
|
for (var i = 0; i < total; i++) {
|
||||||
|
all.push(i);
|
||||||
|
}
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
var indices = [0];
|
||||||
|
var step = (total - 1) / (target - 1);
|
||||||
|
for (var j = 1; j < target - 1; j++) {
|
||||||
|
indices.push(Math.round(j * step));
|
||||||
|
}
|
||||||
|
indices.push(total - 1);
|
||||||
|
var seen = {};
|
||||||
|
var deduped = [];
|
||||||
|
for (var k = 0; k < indices.length; k++) {
|
||||||
|
var idx = indices[k];
|
||||||
|
if (!seen[idx]) {
|
||||||
|
seen[idx] = true;
|
||||||
|
deduped.push(idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deduped.sort(function (a, b) {
|
||||||
|
return a - b;
|
||||||
|
});
|
||||||
|
return deduped;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPlotBounds(width, height) {
|
||||||
|
return {
|
||||||
|
left: 52,
|
||||||
|
top: 16,
|
||||||
|
right: width - 20,
|
||||||
|
bottom: height - 78,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildScales(config, plot) {
|
||||||
|
var maxY = 0;
|
||||||
|
for (var i = 0; i < config.series.length; i++) {
|
||||||
|
var values = config.series[i].values || [];
|
||||||
|
for (var j = 0; j < values.length; j++) {
|
||||||
|
var value = toNumber(values[j]);
|
||||||
|
if (value !== null && value > maxY) {
|
||||||
|
maxY = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxY <= 0) {
|
||||||
|
maxY = 1;
|
||||||
|
}
|
||||||
|
var count = config.labels.length;
|
||||||
|
var xSpan = plot.right - plot.left;
|
||||||
|
var ySpan = plot.bottom - plot.top;
|
||||||
|
|
||||||
|
return {
|
||||||
|
maxY: maxY,
|
||||||
|
xForIndex: function (index) {
|
||||||
|
if (count <= 1) {
|
||||||
|
return plot.left;
|
||||||
|
}
|
||||||
|
return plot.left + (index / (count - 1)) * xSpan;
|
||||||
|
},
|
||||||
|
yForValue: function (value) {
|
||||||
|
var numeric = toNumber(value);
|
||||||
|
if (numeric === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return plot.bottom - (numeric / maxY) * ySpan;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawGrid(ctx, plot, config, scales) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = "#e2e8f0";
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.setLineDash([2, 4]);
|
||||||
|
|
||||||
|
var yTickCount = Math.max(2, config.yTicks || 5);
|
||||||
|
for (var i = 0; i < yTickCount; i++) {
|
||||||
|
var yRatio = i / (yTickCount - 1);
|
||||||
|
var y = plot.top + yRatio * (plot.bottom - plot.top);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(plot.left, y);
|
||||||
|
ctx.lineTo(plot.right, y);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
|
||||||
|
var xIndices = pickTickIndices(config.labels.length, config.xTicks || 6);
|
||||||
|
for (var j = 0; j < xIndices.length; j++) {
|
||||||
|
var x = scales.xForIndex(xIndices[j]);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x, plot.top);
|
||||||
|
ctx.lineTo(x, plot.bottom);
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawAxes(ctx, plot) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = "#94a3b8";
|
||||||
|
ctx.lineWidth = 1.5;
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(plot.left, plot.bottom);
|
||||||
|
ctx.lineTo(plot.right, plot.bottom);
|
||||||
|
ctx.stroke();
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(plot.left, plot.top);
|
||||||
|
ctx.lineTo(plot.left, plot.bottom);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawLabels(ctx, plot, config, scales) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.fillStyle = "#475569";
|
||||||
|
ctx.font = "10px sans-serif";
|
||||||
|
|
||||||
|
var yTickCount = Math.max(2, config.yTicks || 5);
|
||||||
|
for (var i = 0; i < yTickCount; i++) {
|
||||||
|
var ratio = i / (yTickCount - 1);
|
||||||
|
var y = plot.top + ratio * (plot.bottom - plot.top);
|
||||||
|
var value = scales.maxY * (1 - ratio);
|
||||||
|
ctx.textAlign = "right";
|
||||||
|
ctx.textBaseline = "middle";
|
||||||
|
ctx.fillText(formatValue(value, "int"), plot.left - 8, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
var xIndices = pickTickIndices(config.labels.length, config.xTicks || 6);
|
||||||
|
for (var j = 0; j < xIndices.length; j++) {
|
||||||
|
var idx = xIndices[j];
|
||||||
|
var tick = (config.tickLabels && config.tickLabels[idx]) || config.labels[idx] || "";
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
ctx.textBaseline = "top";
|
||||||
|
ctx.fillText(tick, scales.xForIndex(idx), plot.bottom + 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.yLabel) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(16, plot.top + (plot.bottom-plot.top)/2);
|
||||||
|
ctx.rotate(-Math.PI / 2);
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
ctx.textBaseline = "top";
|
||||||
|
ctx.font = "12px sans-serif";
|
||||||
|
ctx.fillText(config.yLabel, 0, 0);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.xLabel) {
|
||||||
|
ctx.textAlign = "center";
|
||||||
|
ctx.textBaseline = "top";
|
||||||
|
ctx.font = "12px sans-serif";
|
||||||
|
ctx.fillText(config.xLabel, plot.left + (plot.right-plot.left)/2, plot.bottom + 48);
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawSeries(ctx, plot, config, scales) {
|
||||||
|
for (var i = 0; i < config.series.length; i++) {
|
||||||
|
var series = config.series[i];
|
||||||
|
var values = series.values || [];
|
||||||
|
if (!values.length) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = series.color || "#2563eb";
|
||||||
|
ctx.lineWidth = series.lineWidth || 2.5;
|
||||||
|
ctx.setLineDash(Array.isArray(series.dash) ? series.dash : []);
|
||||||
|
ctx.beginPath();
|
||||||
|
var moved = false;
|
||||||
|
for (var j = 0; j < values.length; j++) {
|
||||||
|
var y = scales.yForValue(values[j]);
|
||||||
|
if (y === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var x = scales.xForIndex(j);
|
||||||
|
if (!moved) {
|
||||||
|
ctx.moveTo(x, y);
|
||||||
|
moved = true;
|
||||||
|
} else {
|
||||||
|
ctx.lineTo(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawLegend(ctx, config, width, height) {
|
||||||
|
var x = 52;
|
||||||
|
var y = height - 32;
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.font = "12px sans-serif";
|
||||||
|
ctx.textBaseline = "middle";
|
||||||
|
for (var i = 0; i < config.series.length; i++) {
|
||||||
|
var series = config.series[i];
|
||||||
|
var label = series.name || "Series";
|
||||||
|
ctx.strokeStyle = series.color || "#2563eb";
|
||||||
|
ctx.fillStyle = "#475569";
|
||||||
|
ctx.lineWidth = series.lineWidth || 2.5;
|
||||||
|
ctx.setLineDash(Array.isArray(series.dash) ? series.dash : []);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x, y);
|
||||||
|
ctx.lineTo(x + 16, y);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
ctx.fillText(label, x + 22, y);
|
||||||
|
x += 22 + ctx.measureText(label).width + 18;
|
||||||
|
if (x > width - 160) {
|
||||||
|
x = 52;
|
||||||
|
y += 18;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTooltip(state, config) {
|
||||||
|
if (!state.tooltip) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (state.hoverIndex === null) {
|
||||||
|
state.tooltip.classList.remove("visible");
|
||||||
|
state.tooltip.setAttribute("aria-hidden", "true");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var idx = state.hoverIndex;
|
||||||
|
var rows = [];
|
||||||
|
rows.push('<div class="web3-chart-tooltip-title">' + escapeHTML(config.labels[idx] || "") + "</div>");
|
||||||
|
for (var i = 0; i < config.series.length; i++) {
|
||||||
|
var series = config.series[i];
|
||||||
|
if (series.tooltipHidden) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var values = series.values || [];
|
||||||
|
var value = toNumber(values[idx]);
|
||||||
|
var valueLabel = formatValue(value, series.tooltipFormat || "int");
|
||||||
|
rows.push(
|
||||||
|
'<div class="web3-chart-tooltip-row">' +
|
||||||
|
'<span class="web3-chart-tooltip-label"><span class="web3-chart-tooltip-swatch" style="background:' + escapeHTML(series.color || "#2563eb") + '"></span>' +
|
||||||
|
escapeHTML(series.name || "Series") +
|
||||||
|
"</span>" +
|
||||||
|
'<span class="web3-chart-tooltip-value">' + escapeHTML(valueLabel) + "</span>" +
|
||||||
|
"</div>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hoverRows = config.hoverRows || [];
|
||||||
|
for (var j = 0; j < hoverRows.length; j++) {
|
||||||
|
var hover = hoverRows[j];
|
||||||
|
var values = hover.values || [];
|
||||||
|
var label = values[idx] || "-";
|
||||||
|
rows.push(
|
||||||
|
'<div class="web3-chart-tooltip-row">' +
|
||||||
|
'<span class="web3-chart-tooltip-label">' + escapeHTML(hover.name || "Value") + "</span>" +
|
||||||
|
'<span class="web3-chart-tooltip-value">' + escapeHTML(label) + "</span>" +
|
||||||
|
"</div>"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.tooltip.innerHTML = rows.join("");
|
||||||
|
state.tooltip.classList.add("visible");
|
||||||
|
state.tooltip.setAttribute("aria-hidden", "false");
|
||||||
|
|
||||||
|
var box = state.wrapper.getBoundingClientRect();
|
||||||
|
var tooltipBox = state.tooltip.getBoundingClientRect();
|
||||||
|
var left = clamp(state.mouseX + 14, 4, box.width - tooltipBox.width - 4);
|
||||||
|
var top = clamp(state.mouseY + 14, 4, box.height - tooltipBox.height - 4);
|
||||||
|
state.tooltip.style.left = left + "px";
|
||||||
|
state.tooltip.style.top = top + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawHover(ctx, plot, config, scales, hoverIndex) {
|
||||||
|
if (hoverIndex === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var x = scales.xForIndex(hoverIndex);
|
||||||
|
ctx.save();
|
||||||
|
ctx.strokeStyle = "#94a3b8";
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.setLineDash([3, 4]);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(x, plot.top);
|
||||||
|
ctx.lineTo(x, plot.bottom);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]);
|
||||||
|
|
||||||
|
for (var i = 0; i < config.series.length; i++) {
|
||||||
|
var series = config.series[i];
|
||||||
|
var values = series.values || [];
|
||||||
|
var y = scales.yForValue(values[hoverIndex]);
|
||||||
|
if (y === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ctx.fillStyle = "#ffffff";
|
||||||
|
ctx.strokeStyle = series.color || "#2563eb";
|
||||||
|
ctx.lineWidth = 1.5;
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(x, y, 3.5, 0, Math.PI * 2);
|
||||||
|
ctx.fill();
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderLineChart(options) {
|
||||||
|
if (!options || !options.canvasId || !options.config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var canvas = document.getElementById(options.canvasId);
|
||||||
|
if (!canvas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var config = options.config;
|
||||||
|
if (!Array.isArray(config.labels) || config.labels.length === 0 || !Array.isArray(config.series) || config.series.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var wrapper = canvas.parentElement;
|
||||||
|
var tooltip = options.tooltipId ? document.getElementById(options.tooltipId) : null;
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
if (!ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var state = {
|
||||||
|
canvas: canvas,
|
||||||
|
wrapper: wrapper,
|
||||||
|
tooltip: tooltip,
|
||||||
|
hoverIndex: null,
|
||||||
|
mouseX: 0,
|
||||||
|
mouseY: 0,
|
||||||
|
scales: null,
|
||||||
|
plot: null,
|
||||||
|
cssWidth: 0,
|
||||||
|
cssHeight: config.height || 360,
|
||||||
|
};
|
||||||
|
|
||||||
|
function redraw() {
|
||||||
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
var dpr = window.devicePixelRatio || 1;
|
||||||
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||||
|
ctx.fillStyle = "#ffffff";
|
||||||
|
ctx.fillRect(0, 0, state.cssWidth, state.cssHeight);
|
||||||
|
|
||||||
|
drawGrid(ctx, state.plot, config, state.scales);
|
||||||
|
drawAxes(ctx, state.plot);
|
||||||
|
drawSeries(ctx, state.plot, config, state.scales);
|
||||||
|
drawLabels(ctx, state.plot, config, state.scales);
|
||||||
|
drawLegend(ctx, config, state.cssWidth, state.cssHeight);
|
||||||
|
drawHover(ctx, state.plot, config, state.scales, state.hoverIndex);
|
||||||
|
updateTooltip(state, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var width = Math.max(320, Math.floor(rect.width));
|
||||||
|
var height = config.height || 360;
|
||||||
|
var dpr = window.devicePixelRatio || 1;
|
||||||
|
|
||||||
|
canvas.width = Math.round(width * dpr);
|
||||||
|
canvas.height = Math.round(height * dpr);
|
||||||
|
canvas.style.height = height + "px";
|
||||||
|
|
||||||
|
state.cssWidth = width;
|
||||||
|
state.cssHeight = height;
|
||||||
|
state.plot = getPlotBounds(width, height);
|
||||||
|
state.scales = buildScales(config, state.plot);
|
||||||
|
redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.addEventListener("mousemove", function (event) {
|
||||||
|
var rect = canvas.getBoundingClientRect();
|
||||||
|
var x = event.clientX - rect.left;
|
||||||
|
var y = event.clientY - rect.top;
|
||||||
|
state.mouseX = x;
|
||||||
|
state.mouseY = y;
|
||||||
|
|
||||||
|
if (!state.plot || config.labels.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (x < state.plot.left || x > state.plot.right || y < state.plot.top || y > state.plot.bottom) {
|
||||||
|
state.hoverIndex = null;
|
||||||
|
redraw();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ratio = (x - state.plot.left) / (state.plot.right - state.plot.left);
|
||||||
|
var idx = Math.round(ratio * (config.labels.length - 1));
|
||||||
|
state.hoverIndex = clamp(idx, 0, config.labels.length - 1);
|
||||||
|
redraw();
|
||||||
|
});
|
||||||
|
|
||||||
|
canvas.addEventListener("mouseleave", function () {
|
||||||
|
state.hoverIndex = null;
|
||||||
|
redraw();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", resize);
|
||||||
|
if (window.ResizeObserver) {
|
||||||
|
var observer = new ResizeObserver(function () {
|
||||||
|
resize();
|
||||||
|
});
|
||||||
|
observer.observe(wrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
resize();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderFromScript(options) {
|
||||||
|
if (!options || !options.configId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var configNode = document.getElementById(options.configId);
|
||||||
|
if (!configNode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var payload = configNode.textContent || "";
|
||||||
|
if (!payload.trim()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var config = JSON.parse(payload);
|
||||||
|
renderLineChart({
|
||||||
|
canvasId: options.canvasId,
|
||||||
|
tooltipId: options.tooltipId,
|
||||||
|
config: config,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// Leave page functional even when chart config is malformed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderFromDataset(options) {
|
||||||
|
if (!options || !options.canvasId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var canvas = document.getElementById(options.canvasId);
|
||||||
|
if (!canvas) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var payload = canvas.dataset.chartConfig || "";
|
||||||
|
if (!payload.trim()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var config = JSON.parse(payload);
|
||||||
|
renderLineChart({
|
||||||
|
canvasId: options.canvasId,
|
||||||
|
tooltipId: options.tooltipId,
|
||||||
|
config: config,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
// Leave page functional even when chart config is malformed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Web3Charts = {
|
||||||
|
renderLineChart: renderLineChart,
|
||||||
|
renderFromScript: renderFromScript,
|
||||||
|
renderFromDataset: renderFromDataset,
|
||||||
|
};
|
||||||
|
})();
|
||||||
101
server/handler/chart_builders_test.go
Normal file
101
server/handler/chart_builders_test.go
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
"vctp/components/views"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuildVcenterChartEncodesClientConfig(t *testing.T) {
|
||||||
|
entries := []views.VcenterTotalsEntry{
|
||||||
|
{
|
||||||
|
RawTime: 2_000,
|
||||||
|
VmCount: 30,
|
||||||
|
VcpuTotal: 80,
|
||||||
|
RamTotalGB: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawTime: 1_000,
|
||||||
|
VmCount: 20,
|
||||||
|
VcpuTotal: 60,
|
||||||
|
RamTotalGB: 90,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
chart := buildVcenterChart(entries)
|
||||||
|
if chart.ConfigJSON == "" {
|
||||||
|
t.Fatal("expected config json for non-empty vcenter chart")
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg lineChartConfig
|
||||||
|
if err := json.Unmarshal([]byte(chart.ConfigJSON), &cfg); err != nil {
|
||||||
|
t.Fatalf("failed to decode chart config json: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.Labels) != 2 {
|
||||||
|
t.Fatalf("expected 2 labels, got %d", len(cfg.Labels))
|
||||||
|
}
|
||||||
|
expectedFirst := time.Unix(1_000, 0).Local().Format("2006-01-02 15:04:05")
|
||||||
|
if cfg.Labels[0] != expectedFirst {
|
||||||
|
t.Fatalf("expected oldest label first %q, got %q", expectedFirst, cfg.Labels[0])
|
||||||
|
}
|
||||||
|
if len(cfg.Series) != 3 {
|
||||||
|
t.Fatalf("expected 3 series, got %d", len(cfg.Series))
|
||||||
|
}
|
||||||
|
if cfg.Series[0].Values[0] != 20 {
|
||||||
|
t.Fatalf("expected first VM value 20, got %v", cfg.Series[0].Values[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildVmTraceChartEncodesPoolState(t *testing.T) {
|
||||||
|
entries := []views.VmTraceEntry{
|
||||||
|
{
|
||||||
|
RawTime: 1_000,
|
||||||
|
ResourcePool: "Tin",
|
||||||
|
VcpuCount: 4,
|
||||||
|
RamGB: 16,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RawTime: 2_000,
|
||||||
|
ResourcePool: "Gold",
|
||||||
|
VcpuCount: 8,
|
||||||
|
RamGB: 24,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
chart := buildVmTraceChart(entries)
|
||||||
|
if chart.ConfigJSON == "" {
|
||||||
|
t.Fatal("expected config json for non-empty vm trace chart")
|
||||||
|
}
|
||||||
|
|
||||||
|
var cfg lineChartConfig
|
||||||
|
if err := json.Unmarshal([]byte(chart.ConfigJSON), &cfg); err != nil {
|
||||||
|
t.Fatalf("failed to decode vm trace chart config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cfg.Series) != 6 {
|
||||||
|
t.Fatalf("expected 6 series, got %d", len(cfg.Series))
|
||||||
|
}
|
||||||
|
if len(cfg.HoverRows) != 1 || cfg.HoverRows[0].Name != "Resource Pool" {
|
||||||
|
t.Fatalf("expected resource pool hover row, got %#v", cfg.HoverRows)
|
||||||
|
}
|
||||||
|
if cfg.HoverRows[0].Values[0] != "Tin" || cfg.HoverRows[0].Values[1] != "Gold" {
|
||||||
|
t.Fatalf("unexpected hover row values: %#v", cfg.HoverRows[0].Values)
|
||||||
|
}
|
||||||
|
if cfg.Series[2].Values[0] == 0 || cfg.Series[2].Values[1] != 0 {
|
||||||
|
t.Fatalf("tin series should be active only for first point: %#v", cfg.Series[2].Values)
|
||||||
|
}
|
||||||
|
if cfg.Series[5].Values[0] != 0 || cfg.Series[5].Values[1] == 0 {
|
||||||
|
t.Fatalf("gold series should be active only for second point: %#v", cfg.Series[5].Values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildChartsEmptyInput(t *testing.T) {
|
||||||
|
if chart := buildVcenterChart(nil); chart.ConfigJSON != "" {
|
||||||
|
t.Fatalf("expected empty config for empty vcenter input, got %q", chart.ConfigJSON)
|
||||||
|
}
|
||||||
|
if chart := buildVmTraceChart(nil); chart.ConfigJSON != "" {
|
||||||
|
t.Fatalf("expected empty config for empty vm trace input, got %q", chart.ConfigJSON)
|
||||||
|
}
|
||||||
|
}
|
||||||
41
server/handler/chart_config.go
Normal file
41
server/handler/chart_config.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
type lineChartConfig struct {
|
||||||
|
Height int `json:"height,omitempty"`
|
||||||
|
XTicks int `json:"xTicks,omitempty"`
|
||||||
|
YTicks int `json:"yTicks,omitempty"`
|
||||||
|
YLabel string `json:"yLabel,omitempty"`
|
||||||
|
XLabel string `json:"xLabel,omitempty"`
|
||||||
|
Labels []string `json:"labels"`
|
||||||
|
TickLabels []string `json:"tickLabels,omitempty"`
|
||||||
|
Series []lineChartSeries `json:"series"`
|
||||||
|
HoverRows []lineChartHoverRow `json:"hoverRows,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type lineChartSeries struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Color string `json:"color"`
|
||||||
|
Values []float64 `json:"values"`
|
||||||
|
Dash []float64 `json:"dash,omitempty"`
|
||||||
|
LineWidth float64 `json:"lineWidth,omitempty"`
|
||||||
|
TooltipFormat string `json:"tooltipFormat,omitempty"`
|
||||||
|
TooltipHidden bool `json:"tooltipHidden,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type lineChartHoverRow struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Values []string `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeLineChartConfig(cfg lineChartConfig) string {
|
||||||
|
if len(cfg.Labels) == 0 || len(cfg.Series) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
out, err := json.Marshal(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return string(out)
|
||||||
|
}
|
||||||
@@ -141,91 +141,54 @@ func buildVcenterChart(entries []views.VcenterTotalsEntry) views.VcenterChartDat
|
|||||||
plot = append(plot, entries[i])
|
plot = append(plot, entries[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
width := 1200.0
|
labels := make([]string, 0, len(plot))
|
||||||
height := 260.0
|
tickLabels := make([]string, 0, len(plot))
|
||||||
plotWidth := width - 60.0
|
vmValues := make([]float64, 0, len(plot))
|
||||||
startX := 40.0
|
vcpuValues := make([]float64, 0, len(plot))
|
||||||
maxVal := float64(0)
|
ramValues := make([]float64, 0, len(plot))
|
||||||
|
|
||||||
for _, e := range plot {
|
for _, e := range plot {
|
||||||
if float64(e.VmCount) > maxVal {
|
t := time.Unix(e.RawTime, 0).Local()
|
||||||
maxVal = float64(e.VmCount)
|
labels = append(labels, t.Format("2006-01-02 15:04:05"))
|
||||||
}
|
tickLabels = append(tickLabels, t.Format("01-02 15:04"))
|
||||||
if float64(e.VcpuTotal) > maxVal {
|
vmValues = append(vmValues, float64(e.VmCount))
|
||||||
maxVal = float64(e.VcpuTotal)
|
vcpuValues = append(vcpuValues, float64(e.VcpuTotal))
|
||||||
}
|
ramValues = append(ramValues, float64(e.RamTotalGB))
|
||||||
if float64(e.RamTotalGB) > maxVal {
|
|
||||||
maxVal = float64(e.RamTotalGB)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if maxVal == 0 {
|
|
||||||
maxVal = 1
|
cfg := lineChartConfig{
|
||||||
}
|
Height: 360,
|
||||||
stepX := plotWidth
|
XTicks: 6,
|
||||||
if len(plot) > 1 {
|
YTicks: 5,
|
||||||
stepX = plotWidth / float64(len(plot)-1)
|
YLabel: "Totals",
|
||||||
}
|
XLabel: "Snapshots (oldest left, newest right)",
|
||||||
pointsVm := ""
|
Labels: labels,
|
||||||
pointsVcpu := ""
|
TickLabels: tickLabels,
|
||||||
pointsRam := ""
|
Series: []lineChartSeries{
|
||||||
for i, e := range plot {
|
{
|
||||||
x := startX + float64(i)*stepX
|
Name: "VMs",
|
||||||
yVm := 10 + (1-(float64(e.VmCount)/maxVal))*height
|
Color: "#2563eb",
|
||||||
yVcpu := 10 + (1-(float64(e.VcpuTotal)/maxVal))*height
|
Values: vmValues,
|
||||||
yRam := 10 + (1-(float64(e.RamTotalGB)/maxVal))*height
|
TooltipFormat: "int",
|
||||||
if i == 0 {
|
LineWidth: 2.5,
|
||||||
pointsVm = fmt.Sprintf("%.1f,%.1f", x, yVm)
|
},
|
||||||
pointsVcpu = fmt.Sprintf("%.1f,%.1f", x, yVcpu)
|
{
|
||||||
pointsRam = fmt.Sprintf("%.1f,%.1f", x, yRam)
|
Name: "vCPU",
|
||||||
} else {
|
Color: "#16a34a",
|
||||||
pointsVm = pointsVm + " " + fmt.Sprintf("%.1f,%.1f", x, yVm)
|
Values: vcpuValues,
|
||||||
pointsVcpu = pointsVcpu + " " + fmt.Sprintf("%.1f,%.1f", x, yVcpu)
|
TooltipFormat: "int",
|
||||||
pointsRam = pointsRam + " " + fmt.Sprintf("%.1f,%.1f", x, yRam)
|
LineWidth: 2.5,
|
||||||
}
|
},
|
||||||
}
|
{
|
||||||
gridX := []float64{}
|
Name: "RAM (GB)",
|
||||||
if len(plot) > 1 {
|
Color: "#ea580c",
|
||||||
for i := 0; i < len(plot); i++ {
|
Values: ramValues,
|
||||||
gridX = append(gridX, startX+float64(i)*stepX)
|
TooltipFormat: "int",
|
||||||
}
|
LineWidth: 2.5,
|
||||||
}
|
},
|
||||||
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})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return views.VcenterChartData{
|
return views.VcenterChartData{
|
||||||
PointsVm: pointsVm,
|
ConfigJSON: encodeLineChartConfig(cfg),
|
||||||
PointsVcpu: pointsVcpu,
|
|
||||||
PointsRam: pointsRam,
|
|
||||||
Width: int(width),
|
|
||||||
Height: int(height),
|
|
||||||
GridX: gridX,
|
|
||||||
GridY: gridY,
|
|
||||||
YTicks: yTicks,
|
|
||||||
XTicks: xTicks,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,114 +108,135 @@ func buildVmTraceChart(entries []views.VmTraceEntry) views.VmTraceChart {
|
|||||||
if len(entries) == 0 {
|
if len(entries) == 0 {
|
||||||
return views.VmTraceChart{}
|
return views.VmTraceChart{}
|
||||||
}
|
}
|
||||||
width := 1200.0
|
maxResource := float64(0)
|
||||||
height := 220.0
|
|
||||||
plotWidth := width - 60.0
|
|
||||||
startX := 40.0
|
|
||||||
maxVal := float64(0)
|
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
if float64(e.VcpuCount) > maxVal {
|
if float64(e.VcpuCount) > maxResource {
|
||||||
maxVal = float64(e.VcpuCount)
|
maxResource = float64(e.VcpuCount)
|
||||||
}
|
}
|
||||||
if float64(e.RamGB) > maxVal {
|
if float64(e.RamGB) > maxResource {
|
||||||
maxVal = float64(e.RamGB)
|
maxResource = float64(e.RamGB)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if maxVal == 0 {
|
if maxResource == 0 {
|
||||||
maxVal = 1
|
maxResource = 1
|
||||||
}
|
}
|
||||||
stepX := plotWidth
|
|
||||||
if len(entries) > 1 {
|
tinLevel := maxResource
|
||||||
stepX = plotWidth / float64(len(entries)-1)
|
bronzeLevel := maxResource * 0.9
|
||||||
}
|
silverLevel := maxResource * 0.8
|
||||||
scale := height / maxVal
|
goldLevel := maxResource * 0.7
|
||||||
var ptsVcpu, ptsRam, ptsTin, ptsBronze, ptsSilver, ptsGold string
|
|
||||||
appendPt := func(s string, x, y float64) string {
|
labels := make([]string, 0, len(entries))
|
||||||
if s == "" {
|
tickLabels := make([]string, 0, len(entries))
|
||||||
return fmt.Sprintf("%.1f,%.1f", x, y)
|
vcpuValues := make([]float64, 0, len(entries))
|
||||||
|
ramValues := make([]float64, 0, len(entries))
|
||||||
|
tinValues := make([]float64, 0, len(entries))
|
||||||
|
bronzeValues := make([]float64, 0, len(entries))
|
||||||
|
silverValues := make([]float64, 0, len(entries))
|
||||||
|
goldValues := make([]float64, 0, len(entries))
|
||||||
|
poolNames := make([]string, 0, len(entries))
|
||||||
|
|
||||||
|
for _, e := range entries {
|
||||||
|
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"))
|
||||||
|
vcpuValues = append(vcpuValues, float64(e.VcpuCount))
|
||||||
|
ramValues = append(ramValues, float64(e.RamGB))
|
||||||
|
|
||||||
|
pool := strings.TrimSpace(e.ResourcePool)
|
||||||
|
if pool == "" {
|
||||||
|
pool = "Unknown"
|
||||||
}
|
}
|
||||||
return s + " " + fmt.Sprintf("%.1f,%.1f", x, y)
|
poolNames = append(poolNames, pool)
|
||||||
}
|
|
||||||
for i, e := range entries {
|
lower := strings.ToLower(pool)
|
||||||
x := startX + float64(i)*stepX
|
|
||||||
yVcpu := 10 + height - float64(e.VcpuCount)*scale
|
|
||||||
yRam := 10 + height - float64(e.RamGB)*scale
|
|
||||||
ptsVcpu = appendPt(ptsVcpu, x, yVcpu)
|
|
||||||
ptsRam = appendPt(ptsRam, x, yRam)
|
|
||||||
poolY := map[string]float64{
|
|
||||||
"tin": 10 + height - scale*maxVal,
|
|
||||||
"bronze": 10 + height - scale*maxVal*0.9,
|
|
||||||
"silver": 10 + height - scale*maxVal*0.8,
|
|
||||||
"gold": 10 + height - scale*maxVal*0.7,
|
|
||||||
}
|
|
||||||
lower := strings.ToLower(e.ResourcePool)
|
|
||||||
if lower == "tin" {
|
if lower == "tin" {
|
||||||
ptsTin = appendPt(ptsTin, x, poolY["tin"])
|
tinValues = append(tinValues, tinLevel)
|
||||||
} else {
|
} else {
|
||||||
ptsTin = appendPt(ptsTin, x, 10+height)
|
tinValues = append(tinValues, 0)
|
||||||
}
|
}
|
||||||
if lower == "bronze" {
|
if lower == "bronze" {
|
||||||
ptsBronze = appendPt(ptsBronze, x, poolY["bronze"])
|
bronzeValues = append(bronzeValues, bronzeLevel)
|
||||||
} else {
|
} else {
|
||||||
ptsBronze = appendPt(ptsBronze, x, 10+height)
|
bronzeValues = append(bronzeValues, 0)
|
||||||
}
|
}
|
||||||
if lower == "silver" {
|
if lower == "silver" {
|
||||||
ptsSilver = appendPt(ptsSilver, x, poolY["silver"])
|
silverValues = append(silverValues, silverLevel)
|
||||||
} else {
|
} else {
|
||||||
ptsSilver = appendPt(ptsSilver, x, 10+height)
|
silverValues = append(silverValues, 0)
|
||||||
}
|
}
|
||||||
if lower == "gold" {
|
if lower == "gold" {
|
||||||
ptsGold = appendPt(ptsGold, x, poolY["gold"])
|
goldValues = append(goldValues, goldLevel)
|
||||||
} else {
|
} else {
|
||||||
ptsGold = appendPt(ptsGold, x, 10+height)
|
goldValues = append(goldValues, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gridY := []float64{}
|
|
||||||
for i := 0; i <= 4; i++ {
|
cfg := lineChartConfig{
|
||||||
gridY = append(gridY, 10+float64(i)*(height/4))
|
Height: 360,
|
||||||
}
|
XTicks: 8,
|
||||||
gridX := []float64{}
|
YTicks: 5,
|
||||||
for i := 0; i < len(entries); i++ {
|
YLabel: "Resources / Pool",
|
||||||
gridX = append(gridX, startX+float64(i)*stepX)
|
XLabel: "Snapshots (oldest left, newest right)",
|
||||||
}
|
Labels: labels,
|
||||||
yTicks := []views.ChartTick{}
|
TickLabels: tickLabels,
|
||||||
for i := 0; i <= 4; i++ {
|
Series: []lineChartSeries{
|
||||||
val := maxVal * float64(4-i) / 4
|
{
|
||||||
pos := 10 + float64(i)*(height/4)
|
Name: "vCPU",
|
||||||
yTicks = append(yTicks, views.ChartTick{Pos: pos, Label: fmt.Sprintf("%.0f", val)})
|
Color: "#2563eb",
|
||||||
}
|
Values: vcpuValues,
|
||||||
xTicks := []views.ChartTick{}
|
TooltipFormat: "int",
|
||||||
maxTicks := 8
|
LineWidth: 2.5,
|
||||||
stepIdx := 1
|
},
|
||||||
if len(entries) > 1 {
|
{
|
||||||
stepIdx = (len(entries)-1)/maxTicks + 1
|
Name: "RAM (GB)",
|
||||||
}
|
Color: "#16a34a",
|
||||||
for idx := 0; idx < len(entries); idx += stepIdx {
|
Values: ramValues,
|
||||||
x := startX + float64(idx)*stepX
|
TooltipFormat: "int",
|
||||||
label := time.Unix(entries[idx].RawTime, 0).Local().Format("01-02 15:04")
|
LineWidth: 2.5,
|
||||||
xTicks = append(xTicks, views.ChartTick{Pos: x, Label: label})
|
},
|
||||||
}
|
{
|
||||||
if len(entries) > 1 {
|
Name: "Tin",
|
||||||
lastIdx := len(entries) - 1
|
Color: "#0ea5e9",
|
||||||
xLast := startX + float64(lastIdx)*stepX
|
Values: tinValues,
|
||||||
labelLast := time.Unix(entries[lastIdx].RawTime, 0).Local().Format("01-02 15:04")
|
Dash: []float64{4, 4},
|
||||||
if len(xTicks) == 0 || xTicks[len(xTicks)-1].Pos != xLast {
|
LineWidth: 1.5,
|
||||||
xTicks = append(xTicks, views.ChartTick{Pos: xLast, Label: labelLast})
|
TooltipHidden: true,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
Name: "Bronze",
|
||||||
|
Color: "#a855f7",
|
||||||
|
Values: bronzeValues,
|
||||||
|
Dash: []float64{4, 4},
|
||||||
|
LineWidth: 1.5,
|
||||||
|
TooltipHidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Silver",
|
||||||
|
Color: "#94a3b8",
|
||||||
|
Values: silverValues,
|
||||||
|
Dash: []float64{4, 4},
|
||||||
|
LineWidth: 1.5,
|
||||||
|
TooltipHidden: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Gold",
|
||||||
|
Color: "#f59e0b",
|
||||||
|
Values: goldValues,
|
||||||
|
Dash: []float64{4, 4},
|
||||||
|
LineWidth: 1.5,
|
||||||
|
TooltipHidden: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
HoverRows: []lineChartHoverRow{
|
||||||
|
{
|
||||||
|
Name: "Resource Pool",
|
||||||
|
Values: poolNames,
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return views.VmTraceChart{
|
return views.VmTraceChart{
|
||||||
PointsVcpu: ptsVcpu,
|
ConfigJSON: encodeLineChartConfig(cfg),
|
||||||
PointsRam: ptsRam,
|
|
||||||
PointsTin: ptsTin,
|
|
||||||
PointsBronze: ptsBronze,
|
|
||||||
PointsSilver: ptsSilver,
|
|
||||||
PointsGold: ptsGold,
|
|
||||||
Width: int(width),
|
|
||||||
Height: int(height),
|
|
||||||
GridX: gridX,
|
|
||||||
GridY: gridY,
|
|
||||||
XTicks: xTicks,
|
|
||||||
YTicks: yTicks,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user