@@ -35,6 +35,10 @@ const history = {
3535let clockEl , dateEl , appGridEl , searchBtn , themeBtn , viewBtn , editBtn , commandPalette , searchInput , searchResults , statsDetailsEl ;
3636let editModal , editListEl , editSaveBtn , editCancelBtn , editAddBtn ;
3737let editCategoryOrderListEl , editCategoryOrderAddBtn , editCategoryOrderInput ;
38+ let cpuValueEl , ramValueEl , tempValueEl ;
39+ let hostCpuSparkEl , hostRamSparkEl , hostTempSparkEl , hostTxSparkEl , hostRxSparkEl ;
40+ let hostCpuValueEl , hostRamValueEl , hostTempValueEl , hostTxValueEl , hostRxValueEl ;
41+ let statCpuEl , statRamEl , statTempEl , hostTxCardEl , hostRxCardEl ;
3842let isEditMode = false ;
3943let editAppsDraft = [ ] ;
4044let editCategoryOrderDraft = [ ] ;
@@ -55,6 +59,24 @@ document.addEventListener('DOMContentLoaded', () => {
5559 searchInput = document . getElementById ( 'searchInput' ) ;
5660 searchResults = document . getElementById ( 'searchResults' ) ;
5761 statsDetailsEl = document . getElementById ( 'statsDetails' ) ;
62+ cpuValueEl = document . getElementById ( 'cpu-value' ) ;
63+ ramValueEl = document . getElementById ( 'ram-value' ) ;
64+ tempValueEl = document . getElementById ( 'temp-value' ) ;
65+ hostCpuSparkEl = document . getElementById ( 'host-cpu-spark' ) ;
66+ hostRamSparkEl = document . getElementById ( 'host-ram-spark' ) ;
67+ hostTempSparkEl = document . getElementById ( 'host-temp-spark' ) ;
68+ hostTxSparkEl = document . getElementById ( 'host-tx-spark' ) ;
69+ hostRxSparkEl = document . getElementById ( 'host-rx-spark' ) ;
70+ hostCpuValueEl = document . getElementById ( 'host-cpu-value' ) ;
71+ hostRamValueEl = document . getElementById ( 'host-ram-value' ) ;
72+ hostTempValueEl = document . getElementById ( 'host-temp-value' ) ;
73+ hostTxValueEl = document . getElementById ( 'host-tx-value' ) ;
74+ hostRxValueEl = document . getElementById ( 'host-rx-value' ) ;
75+ statCpuEl = document . getElementById ( 'stat-cpu' ) ;
76+ statRamEl = document . getElementById ( 'stat-ram' ) ;
77+ statTempEl = document . getElementById ( 'stat-temp' ) ;
78+ hostTxCardEl = document . getElementById ( 'host-tx-card' ) ;
79+ hostRxCardEl = document . getElementById ( 'host-rx-card' ) ;
5880 editModal = document . getElementById ( 'editModal' ) ;
5981 editListEl = document . getElementById ( 'editList' ) ;
6082 editSaveBtn = document . getElementById ( 'editSaveBtn' ) ;
@@ -981,14 +1003,14 @@ function renderStats(s) {
9811003 pruneHistory ( history . host . netTx , now ) ;
9821004 pruneHistory ( history . host . netRx , now ) ;
9831005 renderHostSparklines ( ) ;
984- if ( config . showCPU ) {
985- document . getElementById ( 'cpu-value' ) . textContent = s . cpu !== null ? s . cpu . toFixed ( 0 ) : '--' ;
1006+ if ( config . showCPU && cpuValueEl ) {
1007+ cpuValueEl . textContent = s . cpu !== null ? s . cpu . toFixed ( 0 ) : '--' ;
9861008 }
987- if ( config . showRAM ) {
988- document . getElementById ( 'ram-value' ) . textContent = s . ram !== null ? s . ram . toFixed ( 0 ) : '--' ;
1009+ if ( config . showRAM && ramValueEl ) {
1010+ ramValueEl . textContent = s . ram !== null ? s . ram . toFixed ( 0 ) : '--' ;
9891011 }
990- if ( config . showTemp ) {
991- document . getElementById ( 'temp-value' ) . textContent = s . temp !== null ? s . temp . toFixed ( 0 ) : '--' ;
1012+ if ( config . showTemp && tempValueEl ) {
1013+ tempValueEl . textContent = s . temp !== null ? s . temp . toFixed ( 0 ) : '--' ;
9921014 }
9931015 updateHostTrendValues ( s ) ;
9941016}
@@ -1031,13 +1053,11 @@ function hydrateHistory(samples) {
10311053}
10321054
10331055function applyStatsVisibility ( ) {
1034- document . getElementById ( 'stat-cpu' ) . style . display = config . showCPU ? '' : 'none' ;
1035- document . getElementById ( 'stat-ram' ) . style . display = config . showRAM ? '' : 'none' ;
1036- document . getElementById ( 'stat-temp' ) . style . display = config . showTemp ? '' : 'none' ;
1037- const hostTxCard = document . getElementById ( 'host-tx-card' ) ;
1038- const hostRxCard = document . getElementById ( 'host-rx-card' ) ;
1039- if ( hostTxCard ) hostTxCard . style . display = config . showNetTX ? '' : 'none' ;
1040- if ( hostRxCard ) hostRxCard . style . display = config . showNetRX ? '' : 'none' ;
1056+ if ( statCpuEl ) statCpuEl . style . display = config . showCPU ? '' : 'none' ;
1057+ if ( statRamEl ) statRamEl . style . display = config . showRAM ? '' : 'none' ;
1058+ if ( statTempEl ) statTempEl . style . display = config . showTemp ? '' : 'none' ;
1059+ if ( hostTxCardEl ) hostTxCardEl . style . display = config . showNetTX ? '' : 'none' ;
1060+ if ( hostRxCardEl ) hostRxCardEl . style . display = config . showNetRX ? '' : 'none' ;
10411061 if ( statsDetailsEl ) {
10421062 const showDetails = config . showNetTX || config . showNetRX ;
10431063 statsDetailsEl . style . display = showDetails ? '' : 'none' ;
@@ -1079,58 +1099,67 @@ function pushHistory(list, timestamp, value) {
10791099
10801100function pruneHistory ( list , now ) {
10811101 const cutoff = now - HISTORY_WINDOW_MS ;
1082- while ( list . length && list [ 0 ] . t < cutoff ) {
1083- list . shift ( ) ;
1102+ let firstValidIndex = 0 ;
1103+ const listLength = list . length ;
1104+ while ( firstValidIndex < listLength && list [ firstValidIndex ] . t < cutoff ) {
1105+ firstValidIndex += 1 ;
1106+ }
1107+ if ( firstValidIndex > 0 ) {
1108+ list . splice ( 0 , firstValidIndex ) ;
10841109 }
10851110}
10861111
10871112function renderHostSparklines ( ) {
1088- const cpuEl = document . getElementById ( 'host-cpu-spark' ) ;
1089- const ramEl = document . getElementById ( 'host-ram-spark' ) ;
1090- const tempEl = document . getElementById ( 'host-temp-spark' ) ;
1091- const txEl = document . getElementById ( 'host-tx-spark' ) ;
1092- const rxEl = document . getElementById ( 'host-rx-spark' ) ;
1093- if ( cpuEl ) cpuEl . innerHTML = renderSparkline ( history . host . cpu , { min : 0 , max : 100 } ) || '' ;
1094- if ( ramEl ) ramEl . innerHTML = renderSparkline ( history . host . ram , { min : 0 , max : 100 } ) || '' ;
1095- if ( tempEl ) tempEl . innerHTML = renderSparkline ( history . host . temp ) || '' ;
1096- if ( txEl ) txEl . innerHTML = renderSparkline ( history . host . netTx ) || '' ;
1097- if ( rxEl ) rxEl . innerHTML = renderSparkline ( history . host . netRx ) || '' ;
1113+ if ( hostCpuSparkEl ) hostCpuSparkEl . innerHTML = renderSparkline ( history . host . cpu , { min : 0 , max : 100 } ) || '' ;
1114+ if ( hostRamSparkEl ) hostRamSparkEl . innerHTML = renderSparkline ( history . host . ram , { min : 0 , max : 100 } ) || '' ;
1115+ if ( hostTempSparkEl ) hostTempSparkEl . innerHTML = renderSparkline ( history . host . temp ) || '' ;
1116+ if ( hostTxSparkEl ) hostTxSparkEl . innerHTML = renderSparkline ( history . host . netTx ) || '' ;
1117+ if ( hostRxSparkEl ) hostRxSparkEl . innerHTML = renderSparkline ( history . host . netRx ) || '' ;
10981118}
10991119
11001120function updateHostTrendValues ( s ) {
1101- const cpuEl = document . getElementById ( 'host-cpu-value' ) ;
1102- const ramEl = document . getElementById ( 'host-ram-value' ) ;
1103- const tempEl = document . getElementById ( 'host-temp-value' ) ;
1104- const txEl = document . getElementById ( 'host-tx-value' ) ;
1105- const rxEl = document . getElementById ( 'host-rx-value' ) ;
1106- if ( cpuEl ) cpuEl . textContent = s . cpu !== null && s . cpu !== undefined ? `${ s . cpu . toFixed ( 0 ) } %` : '--' ;
1107- if ( ramEl ) ramEl . textContent = s . ram !== null && s . ram !== undefined ? `${ s . ram . toFixed ( 0 ) } %` : '--' ;
1108- if ( tempEl ) tempEl . textContent = s . temp !== null && s . temp !== undefined ? `${ s . temp . toFixed ( 0 ) } °C` : '--' ;
1109- if ( txEl ) {
1121+ if ( hostCpuValueEl ) hostCpuValueEl . textContent = s . cpu !== null && s . cpu !== undefined ? `${ s . cpu . toFixed ( 0 ) } %` : '--' ;
1122+ if ( hostRamValueEl ) hostRamValueEl . textContent = s . ram !== null && s . ram !== undefined ? `${ s . ram . toFixed ( 0 ) } %` : '--' ;
1123+ if ( hostTempValueEl ) hostTempValueEl . textContent = s . temp !== null && s . temp !== undefined ? `${ s . temp . toFixed ( 0 ) } °C` : '--' ;
1124+ if ( hostTxValueEl ) {
11101125 const formatted = s . netTx !== null && s . netTx !== undefined ? formatNetValue ( s . netTx ) : null ;
1111- txEl . textContent = formatted ? `${ formatted . value } ${ formatted . unit } ` : '--' ;
1126+ hostTxValueEl . textContent = formatted ? `${ formatted . value } ${ formatted . unit } ` : '--' ;
11121127 }
1113- if ( rxEl ) {
1128+ if ( hostRxValueEl ) {
11141129 const formatted = s . netRx !== null && s . netRx !== undefined ? formatNetValue ( s . netRx ) : null ;
1115- rxEl . textContent = formatted ? `${ formatted . value } ${ formatted . unit } ` : '--' ;
1130+ hostRxValueEl . textContent = formatted ? `${ formatted . value } ${ formatted . unit } ` : '--' ;
11161131 }
11171132}
11181133
11191134function renderSparkline ( series , options = { } ) {
1120- const points = series . filter ( point => point . v !== null && point . v !== undefined ) ;
1121- if ( points . length < 2 ) return '' ;
1122- const minVal = options . min !== undefined ? options . min : Math . min ( ...points . map ( p => p . v ) ) ;
1123- const maxVal = options . max !== undefined ? options . max : Math . max ( ...points . map ( p => p . v ) ) ;
1135+ const values = [ ] ;
1136+ let minVal = options . min ;
1137+ let maxVal = options . max ;
1138+
1139+ for ( let i = 0 ; i < series . length ; i ++ ) {
1140+ const value = series [ i ] . v ;
1141+ if ( value === null || value === undefined ) continue ;
1142+ values . push ( value ) ;
1143+ if ( minVal === undefined || value < minVal ) minVal = value ;
1144+ if ( maxVal === undefined || value > maxVal ) maxVal = value ;
1145+ }
1146+
1147+ if ( values . length < 2 ) return '' ;
1148+
11241149 const span = maxVal - minVal || 1 ;
11251150 const width = 120 ;
11261151 const height = 28 ;
11271152 const strokeWidth = options . strokeWidth || 2 ;
1128- const step = width / ( points . length - 1 ) ;
1129- const path = points . map ( ( point , index ) => {
1153+ const step = width / ( values . length - 1 ) ;
1154+ let path = '' ;
1155+
1156+ for ( let index = 0 ; index < values . length ; index ++ ) {
1157+ const value = values [ index ] ;
11301158 const x = index * step ;
1131- const y = height - ( ( point . v - minVal ) / span ) * height ;
1132- return `${ index === 0 ? 'M' : 'L' } ${ x . toFixed ( 1 ) } ,${ y . toFixed ( 1 ) } ` ;
1133- } ) . join ( ' ' ) ;
1159+ const y = height - ( ( value - minVal ) / span ) * height ;
1160+ path += `${ index === 0 ? 'M' : 'L' } ${ x . toFixed ( 1 ) } ,${ y . toFixed ( 1 ) } ` ;
1161+ }
1162+
11341163 return `<svg viewBox="0 0 ${ width } ${ height } " preserveAspectRatio="none"><path d="${ path } " fill="none" stroke="currentColor" stroke-width="${ strokeWidth } " stroke-linecap="round" stroke-linejoin="round"/></svg>` ;
11351164}
11361165
0 commit comments