0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EChartsでanimation:falseにしたらfinishedイベントが一度も来なかった話

0
Last updated at Posted at 2026-10-11

グラフ入りダッシュボードのPDF出力が、必ず500で落ちていました。
原因は ECharts の finished イベントを取り逃がしていたことだったので、備忘録として残します。

何が起きていたのか

PDFは Playwright で印刷用ページを開いて生成しています。
グラフが描き終わったら window.__chartsReady を立て、それを待ってからPDFにする作りです。

await page.waitForFunction(() => window.__chartsReady === true, { timeout: 15000 });

グラフが無いダッシュボードは成功します。
グラフが1つでもあると page.waitForFunction: Timeout 30000ms exceeded で落ちます(約37秒)。

15秒を指定しているのに30秒で落ちている点は、後ほど説明します。

animation: false だと finished が来ない

印刷ページにアニメーションは不要なので、animation: false で描いていました。
「アニメーション無しなら finished が安定する」と考えていましたが、実際は逆で、一度も発火していませんでした。

  • animation: false だと、ECharts は描画と rendered / finished を setOption の中で同期的に終わらせる
  • echarts-for-react はイベントの購読を setOption の後に行う

つまり、購読した時点で finished はすでに終わっています。来るはずがありません。

onChartReady は呼ばれますが、そこで購読した finished / rendered も来ませんでした。

直し方

onChartReady は購読の後に呼ばれるので、そこで「描画済み」として通知することにしました。

<ReactECharts
  option={option}
  onChartReady={() => notifyRendered()}
/>

通知は1チャートにつき1回だけにしています。
finished が複数回来るケースでも、カウントが実際のグラフ数を超えないようにするためです。

ついでに: waitForFunction のタイムアウト

// NG: 第2引数は arg なので timeout が効かない
await page.waitForFunction(fn, { timeout: 15000 });

// OK: タイムアウトは第3引数
await page.waitForFunction(fn, undefined, { timeout: 15000 });

15秒のつもりが既定の30秒になっていたのは、これが原因でした。

これで、グラフ2つのダッシュボードが「37秒かけて500」から「9秒で200」になりました。

最後に

  • アニメーションを切っているときの finished / rendered は、購読する前に発火済みになっていないかを見る
  • テストが通っていても、実ブラウザ・実サーバーで通していない機能は動いていないことがある。PDF生成のように外のプロセスをまたぐ処理は、E2Eで一度通す

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?