Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion source/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,10 @@
}
.sidebar-separator { margin-bottom: 20px; }
.sidebar-find-search { display: flex; align-items: center; background: #fff; border-radius: 16px; margin: 0px 20px 8px 20px; padding: 0px 8px 0px 8px; }
.sidebar-find-query { width: 100vw; background: none; font-family: inherit; font-size: 13px; padding: 8px 8px 8px 8px; border: 0; outline: 0; }
.sidebar-find-query { flex: 1; background: none; font-family: inherit; font-size: 13px; padding: 8px 8px 8px 8px; border: 0; outline: 0; }
.sidebar-find-nodetype-dropdown { position: absolute; right: 0; top: 100%; margin-top: 4px; background: #fff; border: 1px solid #ddd; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); z-index: 1000; min-width: 120px; max-height: 200px; overflow-y: auto; }
.sidebar-find-nodetype-dropdown > div { padding: 6px 12px; cursor: pointer; font-size: 12px; color: #333; }
.sidebar-find-nodetype-dropdown > div:hover { background: #f5f5f5; }
.sidebar-find-toggle { margin-left: auto; margin-right: 2px; width: 16px; height: 16px; cursor: pointer; }
.sidebar-find-toggle input[type="checkbox"] { display: none; }
.sidebar-find-toggle input[type="checkbox"]:not(:checked) + svg { fill: #ccc; stroke: #ccc; }
Expand Down Expand Up @@ -290,6 +293,9 @@
.sidebar-documentation code { background-color: #1e1e1e; }
.sidebar-documentation pre { background-color: #1e1e1e; }
.sidebar-find-search { background: #383838; color: #dfdfdf; border-color: #424242; }
.sidebar-find-nodetype-dropdown { background: #383838; border-color: #555; }
.sidebar-find-nodetype-dropdown > div { color: #dfdfdf; }
.sidebar-find-nodetype-dropdown > div:hover { background: #424242; }
.sidebar-find-toggle input[type="checkbox"]:not(:checked) + svg { fill: #555; stroke: #555; }
.sidebar-find-toggle input[type="checkbox"]:checked + svg { fill: #aaa; stroke: #aaa; }
.sidebar-find-content li { color: #aaaaaa; }
Expand Down Expand Up @@ -334,6 +340,11 @@ <h1 id="sidebar-title" class="sidebar-title"></h1>
<circle cx="10" cy="15" r="1" />
<circle cx="15" cy="15" r="1" />
</symbol>
<symbol id="sidebar-icon-filter" viewBox="0 0 20 20">
<line x1="4" y1="5" x2="16" y2="5" stroke-width="2" stroke-linecap="round"/>
<line x1="6" y1="10" x2="14" y2="10" stroke-width="2" stroke-linecap="round"/>
<line x1="8" y1="15" x2="12" y2="15" stroke-width="2" stroke-linecap="round"/>
</symbol>
</defs>
</svg>
</div>
Expand Down
119 changes: 118 additions & 1 deletion source/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -4072,13 +4072,15 @@ view.FindSidebar = class extends view.Control {
query: '',
node: true,
connection: true,
weight: true
weight: true,
nodeType: ''
};
this._toggles = {
node: { hide: 'Hide Nodes', show: 'Show Nodes' },
connection: { hide: 'Hide Connections', show: 'Show Connections' },
weight: { hide: 'Hide Weights', show: 'Show Weights' }
};
this._isOnnxModel = this._view._model && this._view._model.format && this._view._model.format.startsWith('ONNX');
}

get identifier() {
Expand Down Expand Up @@ -4194,6 +4196,13 @@ view.FindSidebar = class extends view.Control {
const name = node.name;
const type = node.type.name;
const identifier = node.identifier;
// Apply node type filter for ONNX models
if (this._isOnnxModel && this._state.nodeType && this._state.nodeType !== '') {
const nodeTypeName = type.split('.').pop(); // Get base type name (e.g., "Conv" from "ai.onnx.Conv")
if (nodeTypeName.toLowerCase() !== this._state.nodeType.toLowerCase()) {
return; // Skip nodes that don't match the selected type
}
}
if ((name && this._term(name)) || (type && this._term(type)) || (identifier && this._term(identifier))) {
const content = `${name || `[${type}]`}`;
this._add(node, content, 'node');
Expand Down Expand Up @@ -4259,6 +4268,20 @@ view.FindSidebar = class extends view.Control {
}
}

_collectNodeTypes() {
if (!this._isOnnxModel || !this._target || !this._target.nodes) {
return [];
}
const nodeTypes = new Set();
for (const node of this._target.nodes) {
if (node.type && node.type.name) {
const typeName = node.type.name.split('.').pop(); // Get base type name (e.g., "Conv" from "ai.onnx.Conv")
nodeTypes.add(typeName);
}
}
return Array.from(nodeTypes).sort();
}

_update() {
try {
this._reset();
Expand Down Expand Up @@ -4295,6 +4318,97 @@ view.FindSidebar = class extends view.Control {
this._search = this.createElement('div', 'sidebar-find-search');
this._query = this.createElement('input', 'sidebar-find-query');
this._search.appendChild(this._query);

// Add node type filter button for ONNX models
if (this._isOnnxModel) {
const container = this.createElement('div');
container.style.position = 'relative';

this._nodeTypeFilterButton = this.createElement('label', 'sidebar-find-toggle');
this._nodeTypeFilterButton.innerHTML = `<svg class='sidebar-find-toggle-icon'><use href="#sidebar-icon-filter"></use></svg>`;
this._nodeTypeFilterButton.setAttribute('title', 'Filter by Node Type');

// Create dropdown menu (initially hidden)
this._nodeTypeDropdown = this.createElement('div', 'sidebar-find-nodetype-dropdown');
this._nodeTypeDropdown.style.display = 'none';

const defaultOption = this.createElement('div');
defaultOption.style.padding = '6px 12px';
defaultOption.style.cursor = 'pointer';
defaultOption.style.fontSize = '12px';
defaultOption.textContent = 'All Types';
defaultOption.addEventListener('click', () => {
this._state.nodeType = '';
this._updateDropdownSelection();
this.emit('state-changed', this._state);
this._update();
this._nodeTypeDropdown.style.display = 'none';
});
this._nodeTypeDropdown.appendChild(defaultOption);

const nodeTypes = this._collectNodeTypes();
for (const nodeType of nodeTypes) {
const option = this.createElement('div');
option.style.padding = '6px 12px';
option.style.cursor = 'pointer';
option.style.fontSize = '12px';
option.textContent = nodeType;
option.addEventListener('click', () => {
this._state.nodeType = nodeType;
this._updateDropdownSelection();
this.emit('state-changed', this._state);
this._update();
this._nodeTypeDropdown.style.display = 'none';
});
option.addEventListener('mouseenter', () => {
if (this._state.nodeType !== nodeType) {
option.style.background = '#f5f5f5';
}
});
option.addEventListener('mouseleave', () => {
if (this._state.nodeType !== nodeType) {
option.style.background = 'transparent';
}
});
this._nodeTypeDropdown.appendChild(option);
}

container.appendChild(this._nodeTypeFilterButton);
container.appendChild(this._nodeTypeDropdown);

this._nodeTypeFilterButton.addEventListener('click', (e) => {
e.stopPropagation();
const isVisible = this._nodeTypeDropdown.style.display !== 'none';
this._nodeTypeDropdown.style.display = isVisible ? 'none' : 'block';
});

// Close dropdown when clicking outside
const closeDropdown = (e) => {
if (container && !container.contains(e.target)) {
this._nodeTypeDropdown.style.display = 'none';
}
};
this._host.document.addEventListener('click', closeDropdown);

const nodeTypesList = nodeTypes;
this._updateDropdownSelection = () => {
const options = this._nodeTypeDropdown.children;
for (let i = 0; i < options.length; i++) {
const option = options[i];
const isSelected = (i === 0 && this._state.nodeType === '') ||
(i > 0 && this._state.nodeType === nodeTypesList[i - 1]);
option.style.color = isSelected ? '#2e6bd2' : '';
option.style.fontWeight = isSelected ? 'bold' : 'normal';
if (!isSelected) {
option.style.background = 'transparent';
}
}
};

this._search.appendChild(container);
this._updateDropdownSelection();
}

this._content = this.createElement('ol', 'sidebar-find-content');
this._elements = [this._query, this._content];
this._query.setAttribute('id', 'search');
Expand Down Expand Up @@ -4359,6 +4473,9 @@ view.FindSidebar = class extends view.Control {
toggle.checkbox.checked = this._state[name];
toggle.element.setAttribute('title', this._state[name] ? toggle.hide : toggle.show);
}
if (this._isOnnxModel && this._updateDropdownSelection) {
this._updateDropdownSelection();
}
this._update();
this._host.event('open_sidebar', {
sidebar_identifier: this.identifier,
Expand Down
Loading