- ChartCache + ChartCacheHandle (Arc<Mutex<...>>) cacheable entre
frames. El Render host crea uno con chart_cache() y lo pasa al
Element con .with_cache(handle). Sin handle, cada frame rebuild
completo (correcto pero sin la optimización).
- Hash estructural: plot rect + viewport.span (no x_min/y_min) +
per-series (data.revision + data.len + stroke). 5 tests cubren
estabilidad, pan no invalida, zoom invalida, data revision
invalida, plot rect invalida.
- En paint: si el hash matches, pan-blit = copia las coords
cacheadas con offset (dx_px, dy_px) calculado del diff entre
viewport.x_min cached vs actual. Salteamos LTTB + projection.
- LineSeries::compute_projected expone el pipe LTTB + project_buffer
como método público para que el Element pueda cachear sin pasar
por paint().
- Demo multi-series usa el cache; header muestra "cache: N
pan-blits / M rebuilds" en vivo para que se vea la métrica al
draguear (pan-blits crece) y al zoomear (rebuilds crece).
Limitación v0.1 anotada en código: el doc canónico (sección 4.4)
usa una textura offscreen blitable; GPUI 0.2 no expone esa primitiva
directa. La impl actual cachea coords proyectadas y emite las
polilíneas con offset — mismo ahorro de CPU (saltea LTTB) sin GPU
texture cache.
51 tests verdes (28 cartesian incluyendo 5 nuevos del structural_hash,
20 core, 3 render).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- ChartViewport: pan/zoom anchor-preserving en coords de dominio.
- CoordinateSystem: proyección dominio→pixel + project_buffer zero-alloc.
- trait Series + LineSeries que emite una sola stroke_polyline por frame
(valida P3 del ARCHITECTURE.md). LTTB se dispara cuando data.len()
excede 3× el ancho del plot.
- hit_test sobre coords sorted-by-X con binary search + threshold 8px.
- 14 tests cubren pan, zoom, projection, downsample y hit-test.
Element GPUI queda para la siguiente fase (requiere pionear paint custom
sobre PaintContext — el monorepo no tiene precedente todavía).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>