Compare commits
2 Commits
742928a93d
...
e06b0c1fcd
| Author | SHA1 | Date | |
|---|---|---|---|
| e06b0c1fcd | |||
| 7204f637ac |
+3
-1
@@ -142,6 +142,7 @@ type GPUInfo struct {
|
||||
CoreClock float64 `json:"core_clock_mhz"`
|
||||
MemClock float64 `json:"mem_clock_mhz"`
|
||||
Power float64 `json:"power_watts"`
|
||||
FanSpeed float64 `json:"fan_speed"`
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════
|
||||
@@ -1085,7 +1086,7 @@ func tryNvidiaSMI() []GPUInfo {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
out, err := exec.CommandContext(ctx, "nvidia-smi",
|
||||
"--query-gpu=index,name,memory.total,memory.used,memory.free,temperature.gpu,utilization.gpu,clocks.current.graphics,clocks.current.memory,power.draw",
|
||||
"--query-gpu=index,name,memory.total,memory.used,memory.free,temperature.gpu,utilization.gpu,clocks.current.graphics,clocks.current.memory,power.draw,fan.speed",
|
||||
"--format=csv,noheader,nounits",
|
||||
).Output()
|
||||
if err != nil {
|
||||
@@ -1109,6 +1110,7 @@ func tryNvidiaSMI() []GPUInfo {
|
||||
CoreClock: parseFloat(parts[7]),
|
||||
MemClock: parseFloat(parts[8]),
|
||||
Power: parseFloat(parts[9]),
|
||||
FanSpeed: parseFloat(parts[10]),
|
||||
})
|
||||
}
|
||||
return gpus
|
||||
|
||||
+133
-121
@@ -395,8 +395,8 @@
|
||||
display: grid;
|
||||
grid-template-columns:repeat(auto-fill, minmax(760px, 1fr));
|
||||
align-items: start;
|
||||
gap: 22px;
|
||||
padding: 24px 28px 48px
|
||||
gap: 14px;
|
||||
padding: 16px 20px 36px
|
||||
}
|
||||
|
||||
/* ═══ Card ═══ */
|
||||
@@ -437,22 +437,22 @@
|
||||
}
|
||||
|
||||
.card-hd {
|
||||
padding: 16px 20px 0;
|
||||
padding: 8px 12px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 10px
|
||||
gap: 6px
|
||||
}
|
||||
|
||||
.card-id {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: 6px;
|
||||
min-width: 0
|
||||
}
|
||||
|
||||
.card-id h3 {
|
||||
font-size: 16px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
@@ -460,25 +460,25 @@
|
||||
}
|
||||
|
||||
.card-tm {
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
color: var(--dim);
|
||||
font-family: var(--mono);
|
||||
flex-shrink: 0
|
||||
}
|
||||
|
||||
.card-sub {
|
||||
padding: 2px 20px 0;
|
||||
font-size: 12px;
|
||||
padding: 1px 12px 0;
|
||||
font-size: 9px;
|
||||
color: var(--dim)
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 9px;
|
||||
font-size: 7px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1.2px;
|
||||
letter-spacing: .8px;
|
||||
text-transform: uppercase;
|
||||
padding: 3px 9px;
|
||||
border-radius: 16px;
|
||||
padding: 2px 6px;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
transition: background .3s, color .3s
|
||||
}
|
||||
@@ -498,7 +498,7 @@
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0;
|
||||
padding: 12px 0 0
|
||||
padding: 5px 0 0
|
||||
}
|
||||
|
||||
.card-col {
|
||||
@@ -506,8 +506,8 @@
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--gap);
|
||||
padding: 0 20px 18px
|
||||
gap: 3px;
|
||||
padding: 0 12px 8px
|
||||
}
|
||||
|
||||
.card-left {
|
||||
@@ -529,17 +529,17 @@
|
||||
/* ═══ Section ═══ */
|
||||
.sec {
|
||||
background: var(--sec);
|
||||
border-radius: var(--sec-r);
|
||||
padding: var(--sec-pad)
|
||||
border-radius: 6px;
|
||||
padding: 6px 10px
|
||||
}
|
||||
|
||||
.sec-tt {
|
||||
font-size: 10px;
|
||||
font-size: 8px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 1.5px;
|
||||
letter-spacing: .8px;
|
||||
text-transform: uppercase;
|
||||
color: var(--dim);
|
||||
margin-bottom: 10px
|
||||
margin-bottom: 3px
|
||||
}
|
||||
|
||||
.sec-tt .hl {
|
||||
@@ -555,49 +555,49 @@
|
||||
|
||||
.sr .sl {
|
||||
color: var(--dim);
|
||||
font-size: 12px;
|
||||
font-size: 9px;
|
||||
flex-shrink: 0
|
||||
}
|
||||
|
||||
.sr .sv {
|
||||
font-family: var(--mono);
|
||||
font-size: 12px;
|
||||
font-size: 9px;
|
||||
font-weight: 500
|
||||
}
|
||||
|
||||
.bar {
|
||||
height: 12px;
|
||||
height: 5px;
|
||||
background: var(--dim-bar);
|
||||
border-radius: 6px;
|
||||
border-radius: 3px;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.bar .bf {
|
||||
height: 100%;
|
||||
border-radius: 6px;
|
||||
border-radius: 3px;
|
||||
transition: width .5s ease;
|
||||
min-width: 2px
|
||||
}
|
||||
|
||||
.bar.mini {
|
||||
height: 7px;
|
||||
border-radius: 4px
|
||||
height: 3px;
|
||||
border-radius: 2px
|
||||
}
|
||||
|
||||
.bar.mini .bf {
|
||||
border-radius: 4px
|
||||
border-radius: 2px
|
||||
}
|
||||
|
||||
/* ═══ CPU ═══ */
|
||||
.cpu-top {
|
||||
display: flex;
|
||||
gap: 14px;
|
||||
gap: 10px;
|
||||
align-items: center
|
||||
}
|
||||
|
||||
.gauge {
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0
|
||||
}
|
||||
|
||||
@@ -619,15 +619,15 @@
|
||||
|
||||
.g-val {
|
||||
font-family: var(--mono);
|
||||
font-size: 16px;
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
fill: var(--text)
|
||||
}
|
||||
|
||||
.g-lbl {
|
||||
font-size: 7px;
|
||||
font-size: 5px;
|
||||
fill: var(--dim);
|
||||
letter-spacing: 1px
|
||||
letter-spacing: .6px
|
||||
}
|
||||
|
||||
.cpu-inf {
|
||||
@@ -639,17 +639,17 @@
|
||||
|
||||
.cores {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
gap: 1px;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 6px
|
||||
margin-top: 4px
|
||||
}
|
||||
|
||||
.cbar {
|
||||
flex: 1;
|
||||
min-width: 8px;
|
||||
height: 20px;
|
||||
min-width: 4px;
|
||||
height: 8px;
|
||||
background: var(--dim-bar);
|
||||
border-radius: 2px;
|
||||
border-radius: 1px;
|
||||
position: relative;
|
||||
overflow: hidden
|
||||
}
|
||||
@@ -668,91 +668,90 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin-bottom: 6px
|
||||
margin-bottom: 3px
|
||||
}
|
||||
|
||||
.mem-hd .mp {
|
||||
font-family: var(--mono);
|
||||
font-size: 16px;
|
||||
font-size: 12px;
|
||||
font-weight: 700
|
||||
}
|
||||
|
||||
/* ═══ GPU ═══ */
|
||||
.gpu-item {
|
||||
background: rgba(0, 0, 0, .18);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px
|
||||
.gpu-table-wrap {
|
||||
overflow-x: auto
|
||||
}
|
||||
|
||||
.gpu-item + .gpu-item {
|
||||
margin-top: 6px
|
||||
.gpu-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 8px;
|
||||
font-family: var(--mono)
|
||||
}
|
||||
|
||||
.gpu-hdr {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 6px
|
||||
.gpu-table th {
|
||||
text-align: left;
|
||||
font-size: 7px;
|
||||
font-weight: 600;
|
||||
letter-spacing: .4px;
|
||||
text-transform: uppercase;
|
||||
color: var(--dim);
|
||||
padding: 2px 4px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.gpu-nm {
|
||||
font-size: 12px;
|
||||
font-weight: 500
|
||||
.gpu-table td {
|
||||
padding: 2px 4px;
|
||||
border-bottom: 1px solid rgba(30, 37, 58, .5);
|
||||
white-space: nowrap
|
||||
}
|
||||
|
||||
.gpu-tmp {
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
font-weight: 500
|
||||
.gpu-table tr:last-child td {
|
||||
border-bottom: none
|
||||
}
|
||||
|
||||
.gpu-rows {
|
||||
display: grid;
|
||||
grid-template-columns:1fr 1fr;
|
||||
gap: 4px 14px;
|
||||
font-size: 11px
|
||||
.gpu-table tr:hover td {
|
||||
background: rgba(0, 229, 160, .03)
|
||||
}
|
||||
|
||||
.gr {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px
|
||||
}
|
||||
|
||||
.gr-l {
|
||||
.gpu-idx {
|
||||
color: var(--dim);
|
||||
font-size: 10px
|
||||
}
|
||||
|
||||
.gr-v {
|
||||
font-family: var(--mono);
|
||||
font-weight: 500
|
||||
.gpu-nm {
|
||||
font-family: var(--font);
|
||||
font-weight: 500;
|
||||
font-size: 11px
|
||||
}
|
||||
|
||||
.gpu-vram {
|
||||
grid-column: 1/-1;
|
||||
margin-top: 4px
|
||||
.gpu-vram-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 60px
|
||||
}
|
||||
|
||||
/* ═══ Mining ═══ */
|
||||
.m-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 10px
|
||||
gap: 6px;
|
||||
font-size: 10px;
|
||||
margin-bottom: 6px
|
||||
}
|
||||
|
||||
.m-agent {
|
||||
color: var(--dim);
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
font-family: var(--mono);
|
||||
margin-left: auto
|
||||
}
|
||||
|
||||
.m-country {
|
||||
color: var(--dim);
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
font-family: var(--mono);
|
||||
margin-left: auto
|
||||
}
|
||||
@@ -760,8 +759,8 @@
|
||||
.m-hr-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 6px
|
||||
gap: 6px;
|
||||
margin-bottom: 4px
|
||||
}
|
||||
|
||||
.m-hr-row:last-of-type {
|
||||
@@ -769,19 +768,19 @@
|
||||
}
|
||||
|
||||
.m-hr-lbl {
|
||||
width: 26px;
|
||||
width: 22px;
|
||||
text-align: right;
|
||||
font-family: var(--mono);
|
||||
font-size: 10px;
|
||||
font-size: 8px;
|
||||
color: var(--dim);
|
||||
flex-shrink: 0
|
||||
}
|
||||
|
||||
.m-hr-bar {
|
||||
flex: 1;
|
||||
height: 8px;
|
||||
height: 6px;
|
||||
background: var(--dim-bar);
|
||||
border-radius: 4px;
|
||||
border-radius: 3px;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
@@ -792,10 +791,10 @@
|
||||
}
|
||||
|
||||
.m-hr-val {
|
||||
min-width: 86px;
|
||||
min-width: 70px;
|
||||
text-align: right;
|
||||
font-family: var(--mono);
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
font-weight: 500;
|
||||
flex-shrink: 0
|
||||
}
|
||||
@@ -803,9 +802,9 @@
|
||||
.m-shares {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 10px;
|
||||
margin-top: 6px;
|
||||
font-family: var(--mono);
|
||||
font-size: 11px
|
||||
font-size: 9px
|
||||
}
|
||||
|
||||
.m-sh.valid {
|
||||
@@ -822,29 +821,29 @@
|
||||
|
||||
.m-chart {
|
||||
background: rgba(0, 0, 0, .15);
|
||||
border-radius: 8px;
|
||||
padding: 10px 12px;
|
||||
margin-top: 10px;
|
||||
border-radius: 5px;
|
||||
padding: 6px 8px;
|
||||
margin-top: 6px;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.chart-lbl {
|
||||
font-size: 10px;
|
||||
font-size: 8px;
|
||||
color: var(--dim);
|
||||
font-family: var(--mono);
|
||||
margin-bottom: 6px
|
||||
margin-bottom: 4px
|
||||
}
|
||||
|
||||
.chart-empty {
|
||||
color: var(--dim);
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
text-align: center;
|
||||
padding: 20px 0
|
||||
padding: 14px 0
|
||||
}
|
||||
|
||||
/* ═══ Misc ═══ */
|
||||
.hw-status {
|
||||
padding: 10px 16px
|
||||
padding: 6px 10px
|
||||
}
|
||||
|
||||
.hw-status-row {
|
||||
@@ -880,17 +879,17 @@
|
||||
.off-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding-top: 2px
|
||||
padding-top: 0
|
||||
}
|
||||
|
||||
.btn-del {
|
||||
padding: 5px 14px;
|
||||
padding: 2px 8px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 7px;
|
||||
border-radius: 4px;
|
||||
background: 0;
|
||||
color: var(--dim);
|
||||
font-family: var(--font);
|
||||
font-size: 11px;
|
||||
font-size: 9px;
|
||||
cursor: pointer;
|
||||
transition: all .2s
|
||||
}
|
||||
@@ -1409,29 +1408,42 @@
|
||||
var h = '<div class="sec"><div class="sec-tt">MEMORY</div>';
|
||||
if (isOn && mem.total_bytes) {
|
||||
var pct = mem.percent || 0;
|
||||
h += '<div class="mem-hd"><span style="font-size:12px">' + fmtB(mem.used_bytes) + ' / ' + fmtB(mem.total_bytes) + '</span><span class="mp" style="color:' + pC(pct) + '">' + pct.toFixed(1) + '%</span></div><div class="bar"><div class="bf" style="width:' + pct + '%;background:' + pC(pct) + '"></div></div>'
|
||||
} else if (mem.total_bytes) h += '<div style="font-size:12px;color:var(--dim)">总计 ' + fmtB(mem.total_bytes) + '</div>';
|
||||
else h += '<div style="font-size:12px;color:var(--dim)">无数据</div>';
|
||||
h += '<div class="mem-hd"><span style="font-size:10px">' + fmtB(mem.used_bytes) + ' / ' + fmtB(mem.total_bytes) + '</span><span class="mp" style="color:' + pC(pct) + '">' + pct.toFixed(1) + '%</span></div><div class="bar"><div class="bf" style="width:' + pct + '%;background:' + pC(pct) + '"></div></div>'
|
||||
} else if (mem.total_bytes) h += '<div style="font-size:10px;color:var(--dim)">总计 ' + fmtB(mem.total_bytes) + '</div>';
|
||||
else h += '<div style="font-size:10px;color:var(--dim)">无数据</div>';
|
||||
return h + '</div>';
|
||||
}
|
||||
|
||||
function buildGPU(gpus, infoGPUs, isOn) {
|
||||
var list = isOn ? gpus : (infoGPUs || []);
|
||||
if (!list.length) return '<div class="sec"><div class="sec-tt">GPU</div><div style="color:var(--dim);font-size:12px">未检测到</div></div>';
|
||||
var h = '<div class="sec"><div class="sec-tt">GPU</div>';
|
||||
if (!list.length) return '<div class="sec"><div class="sec-tt">GPU</div><div style="color:var(--dim);font-size:11px">未检测到</div></div>';
|
||||
var h = '<div class="sec"><div class="sec-tt">GPU \u00B7 <span class="hl">' + list.length + ' \u5F20</span></div>';
|
||||
h += '<div class="gpu-table-wrap"><table class="gpu-table"><thead><tr>'
|
||||
+ '<th>\u7F16\u53F7</th><th>\u8D1F\u8F7D</th><th>\u6E29\u5EA6</th><th>\u529F\u8017</th><th>\u6838\u5FC3</th><th>\u663E\u5B58</th><th>\u7528\u91CF</th><th>\u98CE\u6247</th>'
|
||||
+ '</tr></thead><tbody>';
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var g = list[i], gl = g.load_percent || 0, tmp = g.temperature || 0,
|
||||
pwr = g.power || g.power_watts || 0, cc = g.core_clock || g.core_clock_mhz || 0,
|
||||
mc = g.mem_clock || g.mem_clock_mhz || 0, vt = g.vram_total || g.vram_total_mb || 0,
|
||||
vu = g.vram_used || g.vram_used_mb || 0;
|
||||
h += '<div class="gpu-item"><div class="gpu-hdr"><span class="gpu-nm">' + esc(g.name || 'N/A') + '</span><span class="gpu-tmp">' + tT(tmp > 0 ? tmp : null) + '</span></div>';
|
||||
if (isOn && (gl > 0 || pwr > 0 || cc > 0)) h += '<div class="gpu-rows"><div class="gr"><span class="gr-l">GPU 负载</span><span class="gr-v" style="color:' + pC(gl) + '">' + gl.toFixed(1) + '%</span></div><div class="gr"><span class="gr-l">功耗</span><span class="gr-v">' + Math.round(pwr) + ' W</span></div><div class="gr"><span class="gr-l">核心频率</span><span class="gr-v">' + Math.round(cc) + ' MHz</span></div><div class="gr"><span class="gr-l">显存频率</span><span class="gr-v">' + Math.round(mc) + ' MHz</span></div></div>';
|
||||
vu = g.vram_used || g.vram_used_mb || 0, fan = g.fan_speed || 0;
|
||||
h += '<tr>'
|
||||
+ '<td class="gpu-idx">GPU' + (i + 1) + '</td>'
|
||||
+ '<td style="color:' + pC(gl) + '">' + gl.toFixed(0) + '%</td>'
|
||||
+ '<td>' + tT(tmp > 0 ? tmp : null) + '</td>'
|
||||
+ '<td>' + Math.round(pwr) + ' W</td>'
|
||||
+ '<td>' + Math.round(cc) + ' MHz</td>'
|
||||
+ '<td>' + Math.round(mc) + ' MHz</td>';
|
||||
if (vt > 0) {
|
||||
var vp = vu / vt * 100;
|
||||
h += '<div class="gpu-vram"><div class="sr" style="margin-bottom:4px"><span class="sl">显存</span><span class="sv">' + (vu / 1024).toFixed(1) + ' / ' + (vt / 1024).toFixed(1) + ' GB</span></div><div class="bar mini"><div class="bf" style="width:' + vp + '%;background:' + pC(vp) + '"></div></div></div>'
|
||||
h += '<td><div class="gpu-vram-cell"><span>' + (vu / 1024).toFixed(1) + '/' + (vt / 1024).toFixed(0) + 'G</span>'
|
||||
+ '<div class="bar mini"><div class="bf" style="width:' + vp + '%;background:' + pC(vp) + '"></div></div></div></td>';
|
||||
} else {
|
||||
h += '<td>\u2014</td>';
|
||||
}
|
||||
h += '</div>';
|
||||
h += '<td>' + (fan > 0 ? Math.round(fan) + '%' : '\u2014') + '</td>';
|
||||
h += '</tr>';
|
||||
}
|
||||
h += '</tbody></table></div>';
|
||||
return h + '</div>';
|
||||
}
|
||||
|
||||
@@ -1468,7 +1480,7 @@
|
||||
h += hrBar('30m', m.hashrate_30m || 0, maxHr) + hrBar('3h', m.hashrate_3h || 0, maxHr) + hrBar('24h', m.hashrate_24h || 0, maxHr);
|
||||
|
||||
/* 时间信息 */
|
||||
h += '<div class="m-times" style="display:flex;gap:16px;margin-top:10px;font-size:11px">';
|
||||
h += '<div class="m-times" style="display:flex;gap:12px;margin-top:6px;font-size:9px">';
|
||||
h += '<span><span style="color:var(--dim)">\u6D3B\u8DC3 </span><span style="font-family:var(--mono)">' + fmtMsTs(m.last_active) + '</span></span>';
|
||||
h += '<span><span style="color:var(--dim)">\u5F00\u59CB </span><span style="font-family:var(--mono)">' + fmtMsTs(m.opened_at) + '</span></span>';
|
||||
if (m.last_active > 0 && m.opened_at > 0) {
|
||||
@@ -1509,7 +1521,7 @@
|
||||
/* ═══ SVG Chart ═══ */
|
||||
function buildChart(hist) {
|
||||
if (!hist || hist.length < 2) return '<div class="chart-empty">数据采集中 (' + ((hist && hist.length) || 0) + '/2)...</div>';
|
||||
var W = 420, H = 100, pad = {t: 14, b: 16, l: 50, r: 10}, cW = W - pad.l - pad.r, cH = H - pad.t - pad.b;
|
||||
var W = 420, H = 70, pad = {t: 10, b: 12, l: 44, r: 8}, cW = W - pad.l - pad.r, cH = H - pad.t - pad.b;
|
||||
var vals = [], i;
|
||||
for (i = 0; i < hist.length; i++) vals.push(hist[i].v);
|
||||
var lo = vals[0], hi = vals[0];
|
||||
@@ -1546,10 +1558,10 @@
|
||||
svg += '<line x1="' + pad.l + '" y1="' + gy + '" x2="' + (W - pad.r) + '" y2="' + gy + '" stroke="#1a1f30" stroke-width="1"/>'
|
||||
}
|
||||
svg += '<path d="' + area + '" fill="url(#' + gid + ')"/><path d="' + line + '" fill="none" stroke="#00e5a0" stroke-width="1.5" stroke-linejoin="round" stroke-linecap="round"/><circle cx="' + last.x + '" cy="' + last.y + '" r="3" fill="#00e5a0" stroke="#111520" stroke-width="1.5"/>';
|
||||
svg += '<text x="' + (pad.l - 4) + '" y="' + (pad.t + 3) + '" fill="#5a627a" font-size="9" font-family="JetBrains Mono,monospace" text-anchor="end">' + fmtHR(hi) + '</text>';
|
||||
svg += '<text x="' + (pad.l - 4) + '" y="' + (H - pad.b + 3) + '" fill="#5a627a" font-size="9" font-family="JetBrains Mono,monospace" text-anchor="end">' + fmtHR(lo) + '</text>';
|
||||
svg += '<text x="' + pad.l + '" y="' + (H - 2) + '" fill="#5a627a" font-size="9" font-family="JetBrains Mono,monospace">' + fT(t0) + '</text>';
|
||||
svg += '<text x="' + (W - pad.r) + '" y="' + (H - 2) + '" fill="#5a627a" font-size="9" font-family="JetBrains Mono,monospace" text-anchor="end">' + fT(tN) + '</text></svg>';
|
||||
svg += '<text x="' + (pad.l - 3) + '" y="' + (pad.t + 2) + '" fill="#5a627a" font-size="7" font-family="JetBrains Mono,monospace" text-anchor="end">' + fmtHR(hi) + '</text>';
|
||||
svg += '<text x="' + (pad.l - 3) + '" y="' + (H - pad.b + 2) + '" fill="#5a627a" font-size="7" font-family="JetBrains Mono,monospace" text-anchor="end">' + fmtHR(lo) + '</text>';
|
||||
svg += '<text x="' + pad.l + '" y="' + (H - 1) + '" fill="#5a627a" font-size="7" font-family="JetBrains Mono,monospace">' + fT(t0) + '</text>';
|
||||
svg += '<text x="' + (W - pad.r) + '" y="' + (H - 1) + '" fill="#5a627a" font-size="7" font-family="JetBrains Mono,monospace" text-anchor="end">' + fT(tN) + '</text></svg>';
|
||||
return svg;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user