Building a Shape Classifier Around CSS Classes Is Coupling Your Analysis to Your Authoring Conventions
TLDR
Relying on CSS classes (class="wire") or custom data attributes to classify vector shapes creates fragile systems that break whenever users import SVGs created outside your specific application. Metadata represents authoring convention; geometry represents intrinsic truth. Combining a fast class-name lookup (for native authoring) with a geometric metric fallback (for external imports) provides both speed and cross-tool interoperability.
| Classifier Approach | Native Performance | Interoperability with External SVG | Reliability |
|---|---|---|---|
| Pure Class Matching | Instant ($O(1)$ attribute check) | Fails on unclassed SVGs (0% compatibility) | Fragile |
| Pure Geometry Metrics | Fast (Path length & area math) | 100% Compatible across all SVG sources | Highly reliable |
| Hybrid (Fast Path + Fallback) | Instant native, 100% import fallback | 100% Compatible | Production Grade |
Problem statement: the limits of closed-system classifiers
Many canvas libraries (mxGraph, JointJS, custom SVG engines) inspect CSS classes to determine element behavior:
if (el.classList.contains('wire')) attachWireBehavior(el);
While this pattern works inside closed systems where your own tool generates every element, it fails when users import diagrams from Inkscape, Illustrator, Figma, or KiCad.
Technical failure mode: silent analysis corruption
When an importer loads an SVG lacking your application's proprietary class attributes, class-based classifiers return component for every element.
The application does not crash. Instead, it yields silently corrupt results:
- Conductors are misidentified as component bodies.
- Connectivity graph analysis misses wire endpoints.
- Netlist exporters generate empty or invalid hardware descriptions.
The fix & architecture: hybrid fast-path + geometric fallback
Use CSS class matching as a high-speed optimization during active drawing, but fall back to intrinsic geometric metrics whenever metadata is missing or unrecognized:
function classifyElement(el) {
// 1. FAST PATH: Trust explicit internal metadata if present
const explicitClass = el.getAttribute('data-geo-class');
if (explicitClass === 'wire') return 'wire';
if (explicitClass === 'connector') return 'connector';
if (explicitClass === 'component') return 'component';
// 2. FALLBACK PATH: Derive classification from intrinsic geometry const pathPoints = extractAndTransformPoints(el); const isClosed = isPathClosed(el); return classifyByGeometry(pathPoints, isClosed); }
By computing Linearity Ratio ($L > 0.85$) and Isoperimetric Quotient ($Q > 0.65$), the system classifies imported shapes deterministically without requiring third-party class mappings.
Rule of thumb: Use metadata (classes, attributes) to accelerate rendering in native workflows, but always provide a geometric fallback path when importing vector assets from external sources.