Fehlerbehebung

Kopierbare Prüfungen und Lösungen für häufige Fehler bei der Chart-Integration.

Diese Fehlerfälle werden aus dem gleichen versionierten Wissen erzeugt, das von diagnose_chart verwendet wird. Beginnen Sie mit dem Symptom, das der Anwendung am nächsten kommt, führen Sie die Diagnoseschritte aus und wenden Sie nur Korrekturen an, die den dokumentierten Lebenszyklus und den Ownership-Vertrag für Typed-Arrays erhalten.

Wenn kein Eintrag passt, prüfen Sie das relevante Symbol in der verschachtelten API-Referenz oder bitten Sie den lokalen MCP server, eine fokussierte Diagnose durchzuführen. Reduzieren Sie die Reproduktion zu renderMode: "main" und animated: false nur als Diagnoseschritt, nicht als automatische Produktionskonfiguration.

Symptomindex

Die Canvas ist leer oder hat null Größe

Gilt für: line, stock.

Symptom. Das Chart initialisiert sich ohne sichtbaren Fehler, aber es erscheint kein Plot oder die Canvas ist null Pixel hoch.

Wahrscheinliche Ursache. Der Host der Canvas hatte keine konkrete Höhe, als der Renderer initialisiert wurde.

Prüfen

  • Untersuchen Sie Host und Canvas mit getBoundingClientRect(); sowohl Breite als auch Höhe müssen größer als null sein.
  • Prüfen Sie, ob ein Flex- oder Grid-Vorfahr die Chart-Zeile kollabiert hat.

Beheben

  • Geben Sie dem Host vor dem Aufruf von initialize() eine konkrete height oder min-height.
  • Lassen Sie die Canvas dieses Host füllen, statt sich auf intrinsische Canvas-Dimensionen zu verlassen.

Geben Sie dem Chart einen messbaren Host

.chart-host {
  position: relative;
  width: 100%;
  height: clamp(20rem, 55vh, 34rem);
}

.chart-host > canvas {
  display: block;
  width: 100%;
  height: 100%;
}

Daten werden installiert, bevor das Chart bereit ist

Gilt für: line, stock.

Symptom. Der erste Datensatz erscheint nicht, während ein späteres Update oder Remount funktioniert.

Wahrscheinliche Ursache. Eine Vanilla-Integration rief eine Datenmethode auf, bevor initialize() abgeschlossen war, oder hat dieselbe Canvas mehr als einmal initialisiert.

Prüfen

  • Stellen Sie sicher, dass initialize() genau einmal für jede Chart-Instanz awaited wird.
  • Wenn ein Framework die View besitzt, bevorzugen Sie den offiziellen Adapter, sodass Mount- und Unmount-Reihenfolge für Sie gehandhabt werden.

Beheben

  • Awaiten Sie initialize() bevor Sie setData() oder setMultiSeriesData() aufrufen.
  • Zerstören Sie das alte Chart, bevor Sie seine Canvas für eine andere Instanz wiederverwenden.

Verwenden Sie den Vanilla-Lebenszyklus in der richtigen Reihenfolge

const chart = new LineChart(canvas, { renderMode: "auto" });
await chart.initialize();
chart.setData(data);

// Call this when the view is permanently removed.
export function disposeChart() {
  chart.destroy();
}

Rendering im Worker fällt auf den Hauptthread zurück

Gilt für: line, stock.

Symptom. Ein Diagramm funktioniert, rendert jedoch im Hauptthread, oder der Worker wird nur in der Produktion nicht erstellt.

Wahrscheinliche Ursache. Der Worker, OffscreenCanvas, transferControlToOffscreen oder die bereitgestellte Content Security Policy verhinderte das Starten des Worker-Renderers.

Prüfen

  • Verwenden Sie vorübergehend setStatsCallback() und untersuchen Sie die Statistiken.renderMode.
  • Überprüfen Sie die Browser-Konsole und die worker-src Content-Security-Policy-Direktive.

Beheben

  • Lassen Sie renderMode auf auto gesetzt, sofern kein erzwungener Modus für die Diagnose notwendig ist.
  • Erlauben Sie die anwendungsseitig generierte Worker-URL in worker-src und behalten Sie die Main-Thread-Fallback-Option bei.

Bestätigen Sie den aufgelösten Renderer

chart.setStatsCallback((stats) => {
  console.info("Sixtyfold renderer:", stats.renderMode);
  chart.setStatsCallback(null);
});

Typisierte Arrays werden nach setData detached

Gilt für: line, stock.

Symptom. Ein Quell‑Typed‑Array hat nach der Übergabe an ein Worker-unterstütztes Diagramm eine Länge von byteLength oder ist nicht mehr lesbar.

Wahrscheinliche Ursache. Große Diagrammdaten werden im Worker‑Modus an den Renderer übertragen; übertragene ArrayBuffers verlassen den Aufrufer.

Prüfen

  • Untersuchen Sie byteLength unmittelbar vor und nach dem Bulk‑Daten‑Aufruf.
  • Bestätigen Sie, ob ein anderes Subsystem tatsächlich eine lesbare Kopie behalten muss.

Beheben

  • Behandeln Sie den Bulk‑Daten‑Aufruf als Besitzübertragung.
  • Klonen Sie nur die Spalten, die ein anderes Subsystem behalten muss; vermeiden Sie standardmäßig die Duplizierung von Datensätzen mit mehreren Millionen Werten.

Behalten Sie bei Bedarf eine beabsichtigte Anwendungs‑Kopie

const retainedX = sourceX.slice();
const retainedY = sourceY.slice();

chart.setData({
  x: sourceX,
  y: sourceY,
  length: sourceX.length,
});

// retainedX and retainedY remain readable.

Die Zeitachse ist komprimiert, leer oder weit in der Zukunft

Gilt für: line, stock.

Symptom. Achsenmarken zeigen unplausible Daten, der sichtbare Bereich kollabiert oder das Verschieben verhält sich unvorhersehbar.

Wahrscheinliche Ursache. Die X‑Spalte verwendete Sekunden oder Strings statt endlicher, geordneter Epoch‑Millisekunden, oder Beobachtungen waren nicht sortiert.

Prüfen

  • Prüfen Sie die ersten und letzten Zeitstempel und konvertieren Sie sie mit new Date(value).
  • Verifizieren Sie, dass jeder Zeitstempel endlich und nicht fallend ist.

Beheben

  • Konvertieren Sie Epoch‑Sekunden in Millisekunden, bevor Sie die Float64Array erstellen.
  • Parsen Sie ISO‑Daten einmal während der Ingestion und sortieren Sie vollständige Beobachtungen, bevor Sie sie in Spalten aufteilen.

Normalisieren Sie Zeitstempel während der Ingestion

const timestamp = Float64Array.from(rows, (row) => {
  const value = Date.parse(row.recordedAt);
  if (!Number.isFinite(value)) throw new TypeError("Invalid recordedAt value");
  return value;
});

Spalten haben unterschiedliche Längen oder ungültige numerische Werte

Gilt für: line, stock.

Symptom. Das Diagramm lehnt einen Datensatz ab, kürzt unerwartet oder rendert Werte unter falschen Zeitstempeln.

Wahrscheinliche Ursache. Daten in Spaltenform wurden aus separaten Filtern oder Mappings erstellt, sodass Zeit‑ und Wert‑Spalten nicht mehr dieselben Beobachtungen beschreiben.

Prüfen

  • Vergleichen Sie vor dem Aufruf des Diagramms die Länge jeder Spalte.
  • Validieren Sie die numerische Konvertierung, bevor Sie Puffer übertragen.

Beheben

  • Filter und sortiere vollständige Quellbeobachtungen zuerst, dann in ausgerichtete typisierte Spalten aufteilen.
  • Verwende explizites NaN nur für eine dokumentierte Lücken im Liniendiagramm; OHLCV‑Werte müssen gültige Kerzen bleiben.

Lehne fehl ausgerichtete Spalten vor der Übertragung ab

const lengths = [timestamp.length, open.length, high.length, low.length, close.length, volume.length];
if (!lengths.every((length) => length === lengths[0])) {
  throw new RangeError(`OHLCV columns are misaligned: ${lengths.join(", ")}`);
}

SSR oder Hydration greift auf browser‑exklusive Chart‑APIs zu

Gilt für: line, stock.

Symptom. Ein Server‑Render wirft, weil window, document, Worker oder HTMLCanvasElement nicht verfügbar sind, oder die Hydration erzeugt einen anderen Baum.

Wahrscheinliche Ursache. Das interaktive Browser‑Chart wurde während der Server‑Auswertung statt nach der Client‑Mounting‑Phase konstruiert.

Prüfen

  • Finde Chart‑Konstruktion im Modul‑Scope oder innerhalb einer Serverkomponente.
  • Trenne serverseitige Bildgenerierung über @sixtyfold/ssr von Browser‑Interaktion.

Beheben

  • Verwende den offiziellen Framework‑Adapter innerhalb einer client‑besessenen Komponente.
  • Rendere einen stabilen Host während SSR und initialisiere das interaktive Chart erst nach dem Mount.

Halte ein Next.js‑Chart hinter der Client‑Grenze

"use client";

import type { MultiSeriesData, TimeSeriesData } from "@sixtyfold/core";
import { SixtyfoldLineChart } from "@sixtyfold/react/line";

type LineData = TimeSeriesData | MultiSeriesData;

export function ChartPanel({ data }: { data: LineData }) {
  return <SixtyfoldLineChart data={data} options={{ renderMode: "auto" }} />;
}

Worker oder Speicher bleiben nach der Navigation bestehen

Gilt für: line, stock.

Symptom. Der Speicher wächst nach wiederholtem Öffnen der Ansicht, oder alte Charts rendern nach der Navigation weiter.

Wahrscheinliche Ursache. Ein Vanilla‑Chart oder ein temporärer Daten‑Worker wurde beim Entfernen der zugehörigen Ansicht nicht zerstört.

Prüfen

  • Erstelle vor und nach mehreren mount/unmount‑Zyklen ein Browser‑Heap‑Snapshot.
  • Suche nach gehaltenen Chart‑Instanzen, Workern, Observers oder decodierten Quellarrays.

Beheben

  • Rufe destroy() genau einmal für jede Vanilla‑Chart‑Instanz auf.
  • Beende temporäre fetch/decode‑Worker nach deren letzter Übertragung; offizielle Framework‑Adapter zerstören Chart‑Worker automatisch.

Chart‑ und Ingestions‑Worker freigeben

return () => {
  dataWorker?.terminate();
  chart.destroy();
};

Interaktion ist langsam oder verliert Frames

Gilt für: line, stock.

Symptom. Zoomen, Schwenken, initiales Decoding oder Streaming‑Updates blockieren sichtbar oder erreichen nicht die Ziel‑Framerate.

Wahrscheinliche Ursache. Der Hauptthread decodiert oder formatiert zu viele Daten, das Chart fiel auf den Fallback‑Renderer zurück, oder die sichtbare Arbeitslast umfasst mehr Zeichen‑Durchläufe, als das Zielgerät leisten kann.

Prüfen

  • Untersuche Statistiken.renderMode, frameTime, sichtbare Arbeit und LOD‑Bereitschaft während der tatsächlichen Interaktionssequenz.
  • Profile Fetch, Decoding, Konversion, Transfer und Rendering separat.

Beheben

  • Verwende renderMode auto, bereite spaltenorientierte typisierte Arrays in einem dedizierten Daten‑Worker vor, transferiere einmal und beende diesen Ingestions‑Worker.
  • Benchmarke repräsentative Browser, DPRs, Serienzahlen und Gesten; 60 FPS ist ein Designziel, keine geräteunabhängige Garantie.

Messe den aktiven Rendering‑Pfad

chart.setStatsCallback((stats) => {
  console.table({
    mode: stats.renderMode,
    fps: stats.fps,
    frameTime: stats.frameTime,
    ready: stats.lodReady,
  });
}, { intervalMs: 250 });

Linien‑Detail ändert sich abrupt, nachdem das Zoom stabilisiert ist

Gilt für: line.

Symptom. Der Viewport animiert flüssig, aber die Linien‑Textur ändert sich am Ende der Geste erneut.

Wahrscheinliche Ursache. Die Darstellungsdichte oder das Grid-Rebasing ist für die Arbeitslast zu aggressiv, oder Anwendungslogik ersetzt Daten oder Erscheinungsbild nach Abschluss der Animation.

Prüfen

  • Wiederhole dieselbe Viewport‑Sequenz und beobachte Darstellungsdichte, Grid‑Delta und Query‑Besuche.
  • Prüfe auf anwendungsseitige setData(), setAppearance() oder Viewport‑Wiederherstellung nachdem die Animation abgeklungen ist.

Beheben

  • Beginne mit adaptivem Modus, Dichte 0.75, rebaseRatio 1.25 und quantizationStep 0.25.
  • Verwende setLODOptions() um je einen Koeffizienten zu justieren; nutze Dichte 0.25 für kostenintensive Bereichsfüllungen oder außergewöhnlich große Multi‑Series‑Arbeiten.

Präsenta­tion anpassen ohne das Diagramm neu zu erstellen

chart.setLODOptions({
  mode: "adaptive",
  density: 0.75,
  rebaseRatio: 1.25,
  quantizationStep: 0.25,
});

Eine Linie verbindet fehlende Beobachtungen

Gilt für: line.

Symptom. Eine Linie überquert visuell ein Intervall, in dem keine Messung vorliegt.

Wahrscheinliche Ursache. Fehlende Beobachtungen wurden entfernt oder durch Null ersetzt, anstatt als ausgerichtete NaN‑Lücke dargestellt zu werden.

Prüfen

  • Bestätige, dass die gemeinsame X‑Spalte das fehlende Intervall enthält, wenn eine sichtbare Unterbrechung erforderlich ist.
  • Prüfe, ob die Ingestion null‑Werte in Null konvertiert hat.

Beheben

  • Behalte ausgerichtete X‑Positionen bei und kodie­re fehlende Linienwerte als Number.NaN.
  • Synthetisiere keine OHLCV‑Kerzen und verbinde keine Markt‑Schließungen; das zeitliche Verhalten von Aktien wird durch beobachtete Kerzen bestimmt.

Eine echte Linien‑Serie‑Lücke darstellen

const data = {
  x: new Float64Array([0, 1, 2, 3]),
  y: new Float64Array([12, Number.NaN, Number.NaN, 18]),
  length: 4,
};