f4c47a72ac
- layout.pug: formatNetworkChartValue now calls scaleFromGH() for Hashrate labels instead of appending the fixed (GH/s) unit, so tooltip values match the Y-axis auto-scaled unit (MH/s…PH/s) - custom.js: promote HASH_UNITS and scaleFromGH to global scope so layout.pug inline scripts can reuse them; fix unused 'mutations' param - settings.json.tmpl: disable block_line on both charts (was green rgba(0,128,0)); color updated to purple rgba(120,60,220,0.25)
174 lines
6.9 KiB
JavaScript
174 lines
6.9 KiB
JavaScript
// ══════════════════════════════════════════════════════════════
|
||
// HASHRATE AUTO-SCALING (global scope — reused by layout.pug chart scripts)
|
||
// The server sends hashrate already divided by nethash_units ("G"),
|
||
// so values arrive in GH/s. We scale to keep the display 1–999.
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
var HASH_UNITS = [
|
||
{ div: 1e6, label: 'PH/s' },
|
||
{ div: 1e3, label: 'TH/s' },
|
||
{ div: 1, label: 'GH/s' },
|
||
{ div: 1e-3, label: 'MH/s' },
|
||
{ div: 1e-6, label: 'KH/s' },
|
||
{ div: 1e-9, label: 'H/s' }
|
||
];
|
||
|
||
// Returns {num, unit} where 1 ≤ |num| < 1000 (best fit)
|
||
function scaleFromGH(gh) {
|
||
var abs = Math.abs(gh);
|
||
for (var i = 0; i < HASH_UNITS.length; i++) {
|
||
if (abs >= HASH_UNITS[i].div) {
|
||
return { num: gh / HASH_UNITS[i].div, unit: HASH_UNITS[i].label };
|
||
}
|
||
}
|
||
return { num: gh, unit: 'GH/s' };
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
|
||
// ── Panel: reformat #hashrate + update unit label ─────────────
|
||
function refreshHashratePanel() {
|
||
var $el = $('#hashrate');
|
||
if (!$el.length) return;
|
||
|
||
// Read raw text ("42,650.8351" or similar), strip formatting
|
||
var raw = $el.text().replace(/[,\s]/g, '');
|
||
var ghVal = parseFloat(raw);
|
||
if (!isFinite(ghVal) || ghVal <= 0) return;
|
||
|
||
var s = scaleFromGH(ghVal);
|
||
|
||
// Format to max 4 significant digits, always 2 decimals
|
||
var decimals = (s.num >= 100) ? 1 : (s.num >= 10) ? 2 : 3;
|
||
var formatted = s.num.toFixed(decimals);
|
||
var parts = formatted.split('.');
|
||
|
||
// Temporarily disconnect observer to avoid loop
|
||
_hashrateObserver.disconnect();
|
||
$el.html(parts[0] + '.<span class="decimal">' + parts[1] + '</span>');
|
||
_hashrateObserver.observe($el[0], { childList: true, subtree: true });
|
||
|
||
// Update the unit label "(GH/s)" → "(TH/s)" etc.
|
||
var $unitSpan = $el.closest('.card').find('.card-header span.small');
|
||
if ($unitSpan.length) $unitSpan.text('(' + s.unit + ')');
|
||
}
|
||
|
||
var _hashrateObserver = new MutationObserver(function() {
|
||
refreshHashratePanel();
|
||
});
|
||
|
||
// Start watching once #hashrate appears in the DOM
|
||
var _panelWatcher = new MutationObserver(function(_mutations, obs) {
|
||
var el = document.getElementById('hashrate');
|
||
if (el) {
|
||
obs.disconnect();
|
||
_hashrateObserver.observe(el, { childList: true, subtree: true });
|
||
}
|
||
});
|
||
_panelWatcher.observe(document.body, { childList: true, subtree: true });
|
||
|
||
|
||
// ══════════════════════════════════════════════════════════════
|
||
// CHART.JS IMPROVEMENTS
|
||
// ══════════════════════════════════════════════════════════════
|
||
|
||
if (typeof Chart === 'undefined') return;
|
||
|
||
var font = { family: 'Inter, system-ui, sans-serif', size: 11 };
|
||
|
||
// ── Y-axis tick formatters ────────────────────────────────────
|
||
|
||
// Generic large-number formatter (difficulty, etc.)
|
||
function fmtAxis(value) {
|
||
var abs = Math.abs(value);
|
||
if (abs >= 1e9) return (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'B';
|
||
if (abs >= 1e6) return (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'M';
|
||
if (abs >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'K';
|
||
return value;
|
||
}
|
||
|
||
// Hashrate formatter for nethashChart Y-axis ticks
|
||
// Scales GH/s values to the 1-999 range with the right unit
|
||
function fmtHashAxis(gh) {
|
||
if (gh === 0) return '0';
|
||
var s = scaleFromGH(gh);
|
||
var decimals = (Math.abs(s.num) >= 100) ? 0 : (Math.abs(s.num) >= 10) ? 1 : 2;
|
||
return s.num.toFixed(decimals) + ' ' + s.unit;
|
||
}
|
||
|
||
// ── Linear scale defaults ─────────────────────────────────────
|
||
var lin = Chart.defaults.scales.linear;
|
||
if (lin) {
|
||
lin.ticks = Object.assign({}, lin.ticks, {
|
||
// 'this' inside callback is the scale; this.chart.canvas.id identifies the chart
|
||
callback: function(value) {
|
||
if (this.chart && this.chart.canvas &&
|
||
this.chart.canvas.id === 'nethashChart') {
|
||
return fmtHashAxis(value);
|
||
}
|
||
return fmtAxis(value);
|
||
},
|
||
font: font,
|
||
color: 'rgba(200,160,255,0.85)',
|
||
padding: 8,
|
||
maxTicksLimit: 6
|
||
});
|
||
lin.title = Object.assign({}, lin.title, {
|
||
font: Object.assign({}, font, { weight: '700', size: 11 }),
|
||
color: 'rgba(216,180,254,1)'
|
||
});
|
||
lin.grid = Object.assign({}, lin.grid, {
|
||
color: 'rgba(80,40,130,0.3)'
|
||
});
|
||
}
|
||
|
||
// ── Time scale (X-axis) ───────────────────────────────────────
|
||
['time', 'timeseries'].forEach(function(t) {
|
||
var s = Chart.defaults.scales[t];
|
||
if (!s) return;
|
||
s.ticks = Object.assign({}, s.ticks, {
|
||
font: font,
|
||
color: 'rgba(200,160,255,0.75)',
|
||
maxTicksLimit: 6,
|
||
maxRotation: 30,
|
||
minRotation: 0,
|
||
padding: 6
|
||
});
|
||
s.grid = Object.assign({}, s.grid, { color: 'rgba(80,40,130,0.3)' });
|
||
});
|
||
|
||
// ── Plugin: update nethashChart Y-axis title to match auto unit ──
|
||
Chart.register({
|
||
id: 'btcpHashrateUnit',
|
||
afterUpdate: function(chart) {
|
||
if (!chart.canvas || chart.canvas.id !== 'nethashChart') return;
|
||
var yScale = chart.scales && chart.scales.y;
|
||
if (!yScale || !yScale.max) return;
|
||
|
||
var s = scaleFromGH(yScale.max);
|
||
var newTitle = 'Hashrate (' + s.unit + ')';
|
||
var opts = yScale.options;
|
||
if (opts && opts.title && opts.title.text !== newTitle) {
|
||
opts.title.text = newTitle;
|
||
}
|
||
}
|
||
});
|
||
|
||
// ── Tooltip ───────────────────────────────────────────────────
|
||
Object.assign(Chart.defaults.plugins.tooltip, {
|
||
backgroundColor: 'rgba(10,0,28,0.96)',
|
||
borderColor: 'rgba(93,33,182,0.65)',
|
||
borderWidth: 1,
|
||
titleColor: 'rgba(216,180,254,1)',
|
||
titleFont: Object.assign({}, font, { weight: '700', size: 12 }),
|
||
bodyColor: 'rgba(240,230,255,0.9)',
|
||
bodyFont: Object.assign({}, font, { size: 12 }),
|
||
padding: 11,
|
||
cornerRadius: 7
|
||
});
|
||
|
||
// ── Legend ────────────────────────────────────────────────────
|
||
Chart.defaults.plugins.legend.labels.font = Object.assign({}, font, { size: 12 });
|
||
Chart.defaults.plugins.legend.labels.color = 'rgba(216,180,254,1)';
|
||
});
|