トラブルシューティング

一般的なチャート統合の障害について、コピー可能なチェックと修正を提示します。

/* Generated from the versioned @sixtyfold/mcp developer-guidance.json source. */

これらの障害モードは、diagnose_chartで使用される同じバージョン化された知識から生成されています。アプリケーションに最も近い症状から始め、診断チェックを適用し、文書化されたライフサイクルと型付き配列の所有権契約を保持する修正のみを採用してください。

該当する項目がない場合は、ネストされた API リファレンスの該当シンボルを確認するか、ローカル MCP サーバーにフォーカス診断を実行するよう依頼してください。再現を診断手順としてのみ renderMode: "main"animated: false のみに縮小し、本番構成として自動適用しないでください。

症状インデックス

キャンバスが空白、またはサイズがゼロ

対象: linestock

症状: チャートはエラーなしで初期化されるが、プロットが表示されないかキャンバスの高さがゼロである。

考えられる原因: レンダラーが初期化された時点でキャンバスホストに具体的な高さがなかった。

チェック

  • ホストとキャンバスを getBoundingClientRect(); で検査してください。幅と高さは両方ともゼロより大きくなければなりません。
  • flex または grid の祖先要素がチャート行を折りたたんでいないか確認してください。

修正

  • initialize() が実行される前にホストに具体的な height または min-height を与えてください。
  • キャンバスが内在的な寸法に依存するのではなく、そのホストを埋めるようにしてください。

チャートに計測可能なホストを与える

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

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

データがチャートの準備完了前にインストールされる

対象: linestock

症状: 最初のデータセットが表示されず、後の更新や再マウントで正常に表示される。

考えられる原因: プレーンな統合が initialize() の完了前にデータメソッドを呼び出した、または同じキャンバスを複数回初期化した。

チェック

  • 各チャートインスタンスについて initialize() がちょうど一度だけ await されていることを確認してください。
  • フレームワークがビューを所有する場合は、マウントとアンマウントの順序が処理される公式アダプターを使用することを推奨します。

修正

  • setData() または setMultiSeriesData() を呼ぶ前に initialize() を await してください。
  • 別のインスタンスに同じキャンバスを再利用する前に古いチャートを破棄してください。

バニラのライフサイクルを順序どおりに使用する

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();
}

Worker レンダリングがメインスレッドにフォールバックする

適用対象: linestock

症状。 チャートは動作するがメインスレッドでレンダリングされる、または本番環境でのみ Worker の構築に失敗する。

考えられる原因。 Worker、OffscreenCanvas、transferControlToOffscreen、または配備されたコンテンツセキュリティポリシーにより Worker レンダラが起動できなかった。

確認する

  • 一時的に setStatsCallback() を使用して統計を確認する。renderMode。
  • ブラウザコンソールと worker-src の Content Security Policy 指令を確認する。

修正する

  • 診断のためにモードを強制する必要がない限り、renderMode を auto のままにする。
  • アプリケーション生成の Worker URL を worker-src で許可し、メインスレッドフォールバックを有効に保つ。

解決されたレンダラを確認する

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

Typed 配列が setData の後に切り離される

適用対象: linestock

症状。 ソースの Typed 配列の byteLength が 0 になるか、Worker バックのチャートへデータを渡した後に読み取れなくなる。

考えられる原因。 バルクチャートデータは Worker モードでレンダラへ転送される;転送された ArrayBuffers は呼び出し元を離れる。

確認する

  • バルクデータ呼び出しの直前と直後で byteLength を検査する。
  • 別のサブシステムが読み取り可能なコピーを保持する必要が本当にあるか確認する。

修正する

  • バルクデータ呼び出しを所有権の移譲として扱う。
  • 別のサブシステムが保持すべき列だけをクローンする;デフォルトで数百万の値を持つデータセットを複製するのは避ける。

意図したアプリケーションコピーを保持する

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

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

// retainedX and retainedY remain readable.

時間軸が圧縮されている、空である、または未来に大きくずれている

適用対象: linestock

症状。 目盛があり得ない日付を示す、表示レンジが縮む、またはパンが予測不能に動作する。

考えられる原因。 X 列が秒や文字列を使っており有限で順序付けされたエポックミリ秒でなかった、または観測値がソートされていなかった。

確認する

  • 最初と最後のタイムスタンプを検査し new Date(value) で変換する。
  • すべてのタイムスタンプが有限で非減少であることを検証する。

修正する

  • エポック秒を Float64Array を作成する前にミリ秒に変換する。
  • ISO 日付を取り込み時に一度パースし、完全な観測を列に分割する前にソートする。

取り込み時にタイムスタンプを正規化する

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

列の長さが異なる、または無効な数値がある

適用対象: linestock

症状。 チャートがデータセットを拒否する、予期せず切り詰められる、または値が誤ったタイムスタンプで描画される。

考えられる原因。 列指向データが別々のフィルタやマッピングから作成されたため、時間と値の列が同じ観測を記述しなくなった。

確認する

  • チャートを呼び出す前にすべての列長を比較する。
  • バッファを転送する前に数値変換を検証する。

修正

  • 完全な生観測をまずフィルタおよびソートし、次にそれらを整列した型付き列に分割する。
  • 文書化されたライン系列のギャップにのみ明示的な NaN を使用すること。OHLCV 値は有効なキャンドルのままでなければならない。

転送前に整列していない列を拒否する

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 またはハイドレーションがブラウザ専用のチャート API にアクセスしている

適用対象: linestock

症状。 window、document、Worker、または HTMLCanvasElement が利用できないためにサーバーレンダーが例外を投げる、あるいはハイドレーションで異なるツリーが生成される。

考えられる原因。 インタラクティブなブラウザチャートがクライアントのマウント後ではなくサーバー評価中に構築された。

確認する

  • モジュールスコープまたはサーバーコンポーネント内でのチャート構築を探す。
  • サーバー側の画像生成を @sixtyfold/ssr を通してブラウザの操作と分離する。

修正

  • クライアント管理コンポーネント内で公式のフレームワークアダプタを使用する。
  • SSR 中は安定したホストをレンダリングし、インタラクティブなチャートはマウント後にのみ初期化する。

クライアント境界の背後に Next.js チャートを保持する

"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 またはメモリが残る

適用対象: linestock

症状。 ビューを何度も開閉するとメモリが増加する、または古いチャートがナビゲーション後もレンダリングを続ける。

考えられる原因。 バニラチャートや一時データ Worker が所有ビューの削除時に破棄されていない。

確認する

  • いくつかの mount/unmount サイクルの前後でブラウザのヒープスナップショットを記録する。
  • 保持されているチャートインスタンス、Worker、オブザーバ、またはデコード済みソース配列を探す。

修正

  • 各バニラチャートインスタンスに対して destroy() をちょうど一度呼ぶ。
  • 一時的な fetch/decode Worker は最終転送後に終了させること;公式フレームワークアダプタはチャートワーカーを自動的に破棄する。

チャートおよびインジェスションワーカーを解放する

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

操作が遅い、またはフレームを落とす

適用対象: linestock

症状。 ズーム、パン、初期デコード、またはストリーミング更新が目に見えてブロックする、あるいは目標フレームレートを達成できない。

考えられる原因。 メインスレッドがあまりにも多くのデータをデコードまたはリシェイプしている、チャートがフォールバックレンダラに解決された、または可視ワークロードが目標デバイスで維持できる描画パスより多くの描画パスを含む。

確認する

  • 実際の操作シーケンス中の stats.renderMode、frameTime、可視作業、および LOD 準備状況を検査する。
  • フェッチ、デコード、変換、転送、レンダリングを個別にプロファイルする。

修正

  • renderMode 自動を使用し、型付き列配列を専用のデータ Worker で準備し、一度だけ転送してそのインジェスション Worker を終了する。
  • 代表的なブラウザ、DPR、シリーズ数、ジェスチャをベンチマークする;60 FPS は設計目標でありデバイス独立の保証ではない。

アクティブなレンダリングパスを測定する

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

ズームが落ち着いた後にラインの詳細が急変する

適用対象: line

症状。 ビューポートはスムーズにアニメーションするがジェスチャ終了時にラインテクスチャが再度変化する。

考えられる原因。 表示密度やグリッドのリベースがワークロードに対して過度に攻撃的であるか、アニメーション完了後にアプリケーション側のコードがデータや表示を置き換えている。

確認する

  • 表示密度、グリッド差分、クエリ訪問を観察しながら同じビューポートのシーケンスをリプレイする。
  • アニメーションが落ち着いた後にアプリケーション側でsetData()、setAppearance()、またはビューポート復元が行われていないか確認する。

対処方法

  • まずはadaptiveモード、密度0.75、rebaseRatio 1.25、quantizationStep 0.25で開始する。
  • setLODOptions()を使って係数を一つずつ調整する。コストの高い範囲塗りや非常に大きなマルチシリーズ処理では密度0.25を使用する。

チャートを再作成せずに表示を調整する

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

欠測の観測値をまたいで線がつながっている

適用先: line

症状。 線が測定のない区間を視覚的に横切っている。

考えられる原因。 欠測の観測値が削除されたか、整列したNaNギャップとして表現されずにゼロで置き換えられている。

確認する

  • 視覚的な切れ目が必要な場合、共有X列に欠測区間が含まれていることを確認する。
  • 取り込み処理がnull値をゼロに変換していないか検査する。

修正方法

  • 整列したX位置を維持し、欠測の線値はNumber.NaNとして符号化する。
  • OHLCVキャンドルを合成したり市場のクローズを接続したりしないこと。株式の時間スケールの挙動は観測されたキャンドルによって駆動される。

実際のラインシリーズのギャップを表現する

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