diff --git a/graph.h b/graph.h index d14ae6c..c730011 100644 --- a/graph.h +++ b/graph.h @@ -74,6 +74,53 @@ const char graph_html[] PROGMEM = R"rawliteral( border-radius: 10px; margin-bottom: 15px; } + + .search-container { + margin-bottom: 15px; + position: relative; + } + .search-box { + width: 100%; + padding: 12px 12px 12px 40px; + border: 2px solid #43cea2; + border-radius: 8px; + font-size: 0.95em; + transition: all 0.3s; + } + .search-box:focus { + outline: none; + border-color: #185a9d; + box-shadow: 0 0 0 3px rgba(67, 206, 162, 0.1); + } + .search-icon { + position: absolute; + left: 12px; + top: 50%; + transform: translateY(-50%); + color: #43cea2; + font-size: 1.2em; + } + .search-info { + margin-top: 8px; + padding: 8px 12px; + background: #e3f2fd; + border-radius: 5px; + font-size: 0.85em; + color: #185a9d; + font-weight: 600; + } + .no-results { + text-align: center; + padding: 40px 20px; + color: #666; + font-size: 0.95em; + } + .no-results-icon { + font-size: 3em; + margin-bottom: 10px; + opacity: 0.5; + } + .sort-controls { display: flex; gap: 10px; @@ -122,6 +169,11 @@ const char graph_html[] PROGMEM = R"rawliteral( .signal-item.selected { border-color: #185a9d; background: #e3f2fd; } .signal-name { font-weight: 600; color: #333; margin-bottom: 5px; font-size: 0.9em; } .signal-info { font-size: 0.8em; color: #666; } + .highlight { + background-color: #ffeb3b; + padding: 2px 0; + font-weight: 600; + } .controls { display: flex; @@ -216,6 +268,16 @@ const char graph_html[] PROGMEM = R"rawliteral(
+
+ 🔍 + + +
+
Sort by: @@ -240,7 +302,9 @@ const char graph_html[] PROGMEM = R"rawliteral( let dbcData = {}; let selectedSignals = []; let allSignals = []; + let filteredSignals = []; let sortMode = 'selection'; + let searchQuery = ''; const MAX_SIGNALS = 20; function initWebSocket() { @@ -348,10 +412,41 @@ const char graph_html[] PROGMEM = R"rawliteral( } } + filteredSignals = [...allSignals]; displaySignals(); showStatus('DBC loaded: ' + Object.keys(dbcData.messages).length + ' messages', 'success'); } + function filterSignals() { + searchQuery = document.getElementById('search-box').value.toLowerCase().trim(); + + if (searchQuery === '') { + filteredSignals = [...allSignals]; + document.getElementById('search-info').style.display = 'none'; + } else { + filteredSignals = allSignals.filter(signal => { + const nameMatch = signal.name.toLowerCase().includes(searchQuery); + const idMatch = signal.messageId.toString(16).toLowerCase().includes(searchQuery); + const unitMatch = signal.unit && signal.unit.toLowerCase().includes(searchQuery); + + return nameMatch || idMatch || unitMatch; + }); + + const searchInfo = document.getElementById('search-info'); + searchInfo.textContent = 'Showing ' + filteredSignals.length + ' of ' + allSignals.length + ' signals'; + searchInfo.style.display = 'block'; + } + + displaySignals(); + } + + function highlightText(text, query) { + if (!query) return text; + + const regex = new RegExp('(' + query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + ')', 'gi'); + return text.replace(regex, '$1'); + } + function setSortMode(mode) { sortMode = mode; @@ -384,7 +479,16 @@ const char graph_html[] PROGMEM = R"rawliteral( const signalList = document.getElementById('signal-list'); signalList.innerHTML = ''; - const sortedSignals = sortSignals([...allSignals]); + const sortedSignals = sortSignals([...filteredSignals]); + + if (sortedSignals.length === 0) { + signalList.innerHTML = '
' + + '
🔍
' + + '
No signals found
' + + '
Try a different search term
' + + '
'; + return; + } sortedSignals.forEach(signal => { const item = document.createElement('div'); @@ -395,12 +499,18 @@ const char graph_html[] PROGMEM = R"rawliteral( } item.onclick = () => toggleSignal(signal, item); + + const highlightedName = highlightText(signal.name, searchQuery); + const canId = '0x' + signal.messageId.toString(16).toUpperCase(); + const highlightedId = highlightText(canId, searchQuery); + const unitText = signal.unit ? highlightText(signal.unit, searchQuery) : ''; + item.innerHTML = - '
' + signal.name + '
' + + '
' + highlightedName + '
' + '
' + - 'ID: 0x' + signal.messageId.toString(16).toUpperCase() + ' | ' + + 'ID: ' + highlightedId + ' | ' + signal.bitLength + 'bit' + - (signal.unit ? ' | ' + signal.unit : '') + + (signal.unit ? ' | ' + unitText : '') + '
'; signalList.appendChild(item); });