특정변수 검색 필터 추가
This commit is contained in:
118
graph.h
118
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(
|
||||
</div>
|
||||
|
||||
<div class="signal-selector">
|
||||
<div class="search-container">
|
||||
<span class="search-icon">🔍</span>
|
||||
<input type="text"
|
||||
id="search-box"
|
||||
class="search-box"
|
||||
placeholder="Search by signal name, CAN ID, or unit..."
|
||||
oninput="filterSignals()">
|
||||
<div id="search-info" class="search-info" style="display:none;"></div>
|
||||
</div>
|
||||
|
||||
<div class="sort-controls">
|
||||
<span class="sort-label">Sort by:</span>
|
||||
<button class="sort-btn active" id="sort-selection" onclick="setSortMode('selection')">Selection Order</button>
|
||||
@@ -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, '<span class="highlight">$1</span>');
|
||||
}
|
||||
|
||||
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 = '<div class="no-results">' +
|
||||
'<div class="no-results-icon">🔍</div>' +
|
||||
'<div><strong>No signals found</strong></div>' +
|
||||
'<div style="margin-top: 8px; color: #999;">Try a different search term</div>' +
|
||||
'</div>';
|
||||
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 =
|
||||
'<div class="signal-name">' + signal.name + '</div>' +
|
||||
'<div class="signal-name">' + highlightedName + '</div>' +
|
||||
'<div class="signal-info">' +
|
||||
'ID: 0x' + signal.messageId.toString(16).toUpperCase() + ' | ' +
|
||||
'ID: ' + highlightedId + ' | ' +
|
||||
signal.bitLength + 'bit' +
|
||||
(signal.unit ? ' | ' + signal.unit : '') +
|
||||
(signal.unit ? ' | ' + unitText : '') +
|
||||
'</div>';
|
||||
signalList.appendChild(item);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user