Rendering the same wafer data in both libraries. Timings from performance.now() — data fetch excluded.
Both libraries above draw a wafer in single-digit milliseconds, and if drawing were the
whole job the choice would come down to taste. It isn't. The panel below is the same
wafer, the same data — with one extra call, analyzeWaferMap.
wafermap has now compared every ring, quadrant, sector and reticle position against the rest of the wafer, corrected for multiple comparisons, and kept only the differences that are both statistically significant and large enough to act on. Click a finding to highlight the dies it covers. Open the Insights tab for the distributions, correlations and per-test pass rates behind it.
Plotly can render this scatter. It has no concept of a ring, a reticle field, a bin, a spec limit or a yield — so none of what follows is something you would configure differently. It is something you would write yourself.
Building analysis…
What each library handles natively vs what requires manual implementation.
| Feature | @wafertools/wafermap | Plotly.js |
|---|---|---|
| Geometry | ||
| Circular wafer boundary | ✓ NativeComputed from die pitch and wafer diameter | △ Shape overlay onlyCircle drawn on top — dies outside are not clipped |
| Die coordinates → wafer grid | ✓ NativeProber step positions accepted directly | △ Manualx/y used as scatter coordinates; no grid semantics |
| Die pitch and sizing | ✓ Inferred automatically | ✗ Fixed pixel marker sizeGaps or overlaps depending on zoom |
| Edge exclusion ring | ✓ Native | ✗ Manual pre-filter |
| Wafer notch / orientation | ✓ Native (rotate, flip) | ✗ Manual coordinate transform |
| Data handling | ||
| Hard bin (categorical pass/fail) | ✓ Native — named, colour-mapped | △ Numeric colorscale onlyNo bin names, no pass/fail semantics |
| Soft bin mode | ✓ Native | ✗ Separate manual trace |
| Multiple test values per die | ✓ Native — test selector in toolbar | ✗ One value per trace; manual UI to switch |
| Spec limits + out-of-spec flagging | ✓ Native — ▽/△ markers | ✗ Manual pre-classification |
| Retest policy (best / worst / last) | ✓ Native | ✗ Manual pre-process |
| Interactivity | ||
| In-map toolbar (end-user configurable) | ✓ NativeAlways-visible toolbar (top-right). Does everything Plotly's modebar does — zoom, pan, box-select, save image — plus live wafer config: plot mode & test, colour scheme, overlays (rings, quadrants, axes, reticle, spec pass/fail), legend position, rotate/flip — all with no code | △ Modebar onlyZoom, pan, select, export. Colours, overlays and layout require code changes and a re-render |
| Zoom / pan | ✓ | ✓ |
| Die tooltip | ✓ Native — bin, soft bin, all test values | △ Custom templateOnly values passed to the trace |
| Box-select → sub-region yield | ✓ Native | ✗ Manual selected-point callback |
| PNG export | ✓ Toolbar button | ✓ Modebar button |
| Analysis | ||
| Ring yield differential | ✓ Built-in (analyzeWaferMap) | ✗ Not available |
| Failure cluster detection | ✓ Built-in | ✗ Not available |
| Quadrant / sector analysis | ✓ Built-in | ✗ Not available |
| Reticle / stepper overlay | ✓ Built-in | ✗ Not available |
| Lot-level gallery + findings | ✓ Built-in (renderWaferGallery + analyzeWaferLot) | ✗ Manual layout + no lot analysis |
| Integration | ||
| Library size (gzip) | ~104 KB (core)+~25 KB lazy-loaded on first Insights open, +~34 KB if the in-app guide is opened — neither is downloaded otherwise | ~1.3 MB (full bundle)~350 KB with plotly-basic (no WebGL, so no scattergl) |
| Zero runtime dependencies | ✓ | ✓ |
| React / Vue / Svelte / vanilla JS | ✓ | ✓ |
| Web Worker support | ✓ (buildWaferMap runs off main thread) | ✗ |
| Lines of code (basic wafer map) | 2 | ~25–30Scatter trace + layout + circle shape + color mapping |