mcpField
G
graphic-chart

graphic-chart

github.com/varnan-techデータ・データベース68744 回インストール2 週間前に更新
リポジトリ

graphic-chart について

JSON または CSV のデータから PNG の可視化を作るスキルです。Playwright を介してヘッドレス Chromium 上で Apache ECharts を描画し、設定、スタイル、描画確認、書き出しまで扱います。

主な機能

  1. 01棒、折れ線、面、円、散布図、レーダー、ツリーマップに対応
  2. 02JSON 配列、オブジェクト配列、CSV の解析
  3. 035 種類のスタイルプリセット
  4. 04Apache ECharts と Playwright による HTML 描画
  5. 05デバイス倍率 2 倍で PNG を出力

活用シーン

  1. 01構造化データから静的なチャート画像を作成
  2. 02指定した値やカテゴリの強調
  3. 03指定スタイルとサイズでのチャート出力

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/varnan-tech/opendirectory --skill graphic-chart

インストール後、Claude Code で/graphic-chartを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
evals/
evals.json
references/
chart-library.md
style-presets.md
scripts/
export-chart.sh
screenshot-chart.mjs

詳細

graphic-chart

データを可視化したグラフを PNG として生成します。Playwright 経由でヘッドレス Chromium 上に Apache ECharts v6 を使用して HTML をレンダリングし、2×の Retina 品質でスクリーンショットを撮影します。

CDN: https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js


重要なルール(生成のたびに確認してください)

  1. area タイプ → type: 'line' + areaStyle: {} — ECharts に type: 'area' はありません。
  2. doughnut → type: 'pie' + radius: ['40%', '70%'] — ECharts に type: 'doughnut' はありません。
  3. 準備完了のシグナル:chart.setOption() より前に chart.on('finished', fn) を登録する — ECharts のバグ #14101/#17500 により、リスナーを setOption の後に登録すると、イベントが何も通知されません。finished と rendered の両方のイベントを必ず setOption の前に登録してください。
  4. xAxis.type: 'category' を明示する必要があります — ECharts はデータからこれを推測しません。指定し忘れると、グラフは空白になります。
  5. カテゴリラベルは data.labels 配列ではなく、xAxis.data に指定します。 ECharts の構造はフラットです:{ xAxis, yAxis, series, grid, title, legend } — data や options の下にネストする構造ではありません。
  6. データラベルは組み込み機能です — どの系列でも label: { show: true } を使用してください。プラグインは不要です。
  7. 特定の棒やポイントを強調するには、項目ごとの itemStyle を使用します — { value: N, itemStyle: { color: '#...' } } を data 配列に直接指定してください。Chart.js 形式の backgroundColor 配列は使用しないでください。
  8. ECharts の初期化には <canvas> ではなく <div> コンテナーを使用します — echarts.init(document.getElementById('chart'))。コンテナーの div には明示的な寸法が必要です。
  9. オプションで animation: false を指定します — アニメーションを無効にして、即座にレンダリングします。準備完了のシグナルを受け取るには、setOption の前に finished と rendered のイベントを引き続き登録してください。
  10. HTML をチャットに出力しないでください。 ファイルに保存し、概要のみを表示してください。
  11. タイトルには主題ではなく、示唆する内容を記載します。 「月間売上」ではなく「売上は12か月で3倍に成長」。
  12. 円グラフ/ドーナツグラフ:body の padding: 64px 80px と .chart-container { max-height: 860px } を使用します — タイトルがない場合に、グラフが端まで広がるのを防ぎます。

ステップ 1:情報の確認

必須: chart_type、data

任意のパラメーターとデフォルト値:

パラメーターデフォルト値説明
chart_type—bar / line / area / pie / doughnut / scatter / radar / treemap
data—JSON 配列または CSV — 必須
title—示唆する内容を記載。10語以内
subtitle—文脈を説明する1文
styleclean-slateclean-slate / midnight-editorial / matt-gray / electric-burst / brutalist
dimensions1080x1080幅×高さのピクセル数(出力 PNG は deviceScaleFactor により2倍)
x_label—X 軸のラベルテキスト
y_label—Y 軸のラベルテキスト
source—フッターに表示するデータソース
highlight—強調するデータラベル(例:「Q4」、「Dec」、インデックス 3)

chart_type または data がない場合は、次のとおりに尋ねてください:

"グラフを作成するには、次の情報が必要です:

  1. グラフの種類 — bar / line / area / pie / doughnut / scatter / radar / treemap
  2. データ — JSON 配列または CSV で指定してください(例:ラベル ['Q1','Q2','Q3','Q4','Q5'] を付けた [12, 18, 22, 25, 31])

任意:タイトル、スタイル(デフォルト:clean-slate)、寸法(デフォルト:1080×1080)、強調するデータポイント"

両方が指定されている場合は、ステップ 2 に進んでください。


ステップ 2:内部アーキテクチャ(ユーザーには表示しません)

1. グラフの種類を正規化します:

  • area → line + 系列に areaStyle: {} を指定
  • doughnut → pie + 系列に radius: ['40%', '70%'] を指定
  • horizontal bar → bar + xAxis/yAxis を入れ替え(y 軸をカテゴリ軸にする)
  • それ以外:そのまま使用します

2. references/chart-library.md を読み込みます — このグラフの種類の設定仕様をすべて読み込みます。

3. references/style-presets.md を読み込みます — 選択したスタイルの CSS トークンとデータパレットを読み込みます。

4. デザインの方向性を決定します:

決定事項判断基準
トーンプロフェッショナル/エディトリアル/大胆/技術的 — データの対象読者に合わせます
データのストーリーこのグラフが示す単一の洞察(タイトルになります)
強調方法視覚的に強調する必要があるデータポイントとその理由
背景明るい(clean-slate、matt-gray)または暗い(midnight-editorial、electric-burst、brutalist)

5. データを解析します:

  • 単純な配列 [12, 18, 22] → series.data に設定し、ラベルは別途指定します
  • オブジェクトの配列 [{x: 'Jan', y: 12}] → x のキーを xAxis.data に、y の値を series.data に設定します
  • CSV:ヘッダー行を xAxis.data に、値の行を series.data に設定します
  • 複数系列:それぞれ type、name、data を持つ複数の series エントリを使用します
  • 散布図:series.data: [[x1,y1], [x2,y2], ...] の形式を使用します

6. 寸法を解析します: "1080x1080" → W=1080、H=1080。本文 = WxH。出力 PNG = 2W × 2H。


ステップ 3:HTML の生成

生成前にすべて読み込みます:

  • このグラフの種類の ECharts 設定仕様全体については references/chart-library.md
  • 選択したスタイルの CSS トークンとパレットについては references/style-presets.md

必須の HTML 構造:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[font CDN link from style preset]
<style>
:root {
  [all CSS tokens from style preset]
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
  width: [W]px; height: [H]px;
  overflow: hidden;
  background: var(--bg);
  font-family: var(--font-body);
}
body {
  display: flex;
  flex-direction: column;
  padding: 40px 48px 32px;   /* pie/doughnut: use 64px 80px */
}

/* ECharts container must have explicit size */
.chart-container {
  flex: 1;
  min-height: 0;
  /* pie/doughnut only: max-height: 860px; */
}

.chart-header { margin-bottom: 24px; }
.chart-title {
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 2.5vw, 1.6rem);
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}
.chart-subtitle {
  font-family: var(--font-body);
  font-size: clamp(0.75rem, 1.2vw, 0.9rem);
  color: var(--text-muted);
  margin-top: 6px;
  line-height: 1.5;
}
.chart-footer {
  margin-top: 14px;
  font-family: var(--font-body);
  font-size: 10px;
  color: var(--text-muted);
  opacity: 0.65;
}
</style>
</head>
<body>

[if title or subtitle: <div class="chart-header"><div class="chart-title">...</div>...</div>]

<div id="chart" class="chart-container"></div>

[if source: <div class="chart-footer">Source: [source]</div>]

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>

<script>
window.__chartReady = false;

document.fonts.ready.then(() => {
  const container = document.getElementById('chart');
  const chart = echarts.init(container, null, { renderer: 'canvas' });

  // CRITICAL: register events BEFORE setOption — ECharts bug #14101/#17500
  // 'finished' may silently not fire if registered after setOption with animation:false
  chart.on('finished', () => {
    window.__chartReady = true;
  });
  // Belt-and-suspenders fallback via 'rendered'
  chart.on('rendered', () => {
    clearTimeout(window.__renderDebounce);
    window.__renderDebounce = setTimeout(() => { window.__chartReady = true; }, 100);
  });

  const palette = [palette from style preset];

  const option = {
    animation: false,                            // instant render for screenshot

    backgroundColor: 'transparent',             // body CSS handles bg color

    textStyle: {
      fontFamily: '[--font-body value]',
      color: '[--text-muted value]',
    },

    [title config if title param provided],
    [legend config per chart type],
    [grid config per chart type],
    [xAxis config per chart type],
    [yAxis config per chart type],

    series: [{
      [full series config from chart-library.md for this type]
      [palette colors applied per chart type]
      [if highlight: per-item itemStyle on the highlighted data point]
    }]
  };

  chart.setOption(option);   // setOption ALWAYS comes after event registration
});
</script>
</body>
</html>

デザイン品質のルール:

  • タイトルのフォント:fontWeight: 'bold'、fontSize: 20–24 — 細いタイトルは使用しません
  • グリッド線:不透明度を低く(0.06~0.10)し、データより目立たないようにします
  • 棒:barMaxWidth: 60、itemStyle.borderRadius: [4,4,0,0] で角を丸めます
  • 折れ線:自然な曲線には smooth: true、ポイントには symbolSize: 8 を指定します
  • 円グラフ/ドーナツグラフ:組み込みのスライス上ラベルには label.formatter: '{b}\n{d}%' を指定します
  • 暗いプリセット:グリッドには rgba(255,255,255,0.07)、軸線/目盛りの色には rgba(255,255,255,0.15) を指定します
  • ツールチップ:静的 PNG ではホバー操作がないため、show: false を指定します
  • タイトルが指定されていない場合:.chart-header を省略し、ECharts のオプションからタイトルを省きます

ステップ 4:セルフ QA(ステップ 5 の前にすべての不備を修正します)

構造:

  • コンテナが <canvas> ではなく <div> である
  • document.fonts.ready の前に window.__chartReady = false が宣言されている
  • chart.on('finished', ...) が chart.setOption() より前に登録されている
  • chart.on('rendered', ...) のデバウンスフォールバックが chart.setOption() より前に登録されている
  • オプションオブジェクトに animation: false がある
  • 初期化ブロック内で chart.setOption(option) が最後の呼び出しである

種類ごとの確認:

  • エリア:type: 'line' + areaStyle: {} — type: 'area' は使用しない
  • ドーナツ:type: 'pie' + radius: ['40%', '70%'] — type: 'doughnut' は使用しない
  • 棒グラフ:xAxis.type: 'category' が明示的に設定されている
  • カテゴリデータが data.labels ではなく xAxis.data にある
  • 円グラフ/ドーナツグラフ:本文の padding: 64px 80px + .chart-container { max-height: 860px }
  • 強調:データ配列内で、項目ごとに { value: N, itemStyle: { color } } を指定している

デザイン:

  • パレットの色がすべて references/style-presets.md から選ばれている
  • タイトルが単なる題材ではなく、洞察を示している
  • tooltip: { show: false } が指定されているか、省略されている(静的 PNG ではホバー操作なし)
  • 暗いプリセット:グリッド/軸の色に rgba(255,255,255,...) を使用している
  • source パラメーターが指定されている場合、フッターに出典がある
  • データラベルが表示されている(系列に組み込みの label: { show: true } を指定)

ステップ 5:エクスポート

タイトル、またはグラフの種類とデータの文脈からスラッグを決定します(ケバブケース、30 文字以内):

mkdir -p chart/[slug]

HTML を保存します:chart/[slug]/chart.html

ブラウザーで簡易確認します:

open chart/[slug]/chart.html

エクスポートを実行します([skill-root] をこのスキルのディレクトリの実際のパスに置き換えます):

bash [skill-root]/scripts/export-chart.sh \
  chart/[slug]/chart.html \
  chart/[slug]/chart.png \
  --width [W] \
  --height [H]

初回実行時にスクリプトが Playwright をインストールし(Chromium を約 200MB ダウンロード)、その後 deviceScaleFactor: 2 でグラフをキャプチャします。


ステップ 6:出力の概要

## Chart: [title]
Date: [YYYY-MM-DD] | Type: [chart_type] | Style: [style]
Dimensions: [W×H]px → PNG: [2W×2H]px @2× retina

Files
  Source:   chart/[slug]/chart.html
  Output:   chart/[slug]/chart.png
  Size:     [X] KB

Checklist
- [ ] Title states the insight clearly
- [ ] Data labels legible at display size
- [ ] Highlight visible on correct data point
- [ ] Source attribution present in footer

プロンプトのヒント(ユーザーがガイダンスを求めたときに表示)

「説明文ではなく、JSON や CSV などの構造化データを指定してください。」

「グラフの種類を明示してください。『四半期を示すグラフ』ではなく、『第1四半期〜第4四半期を比較する棒グラフ』のように指定してください。」

「データが伝えるストーリーを指定してください。『他のすべてを上回った第4四半期を強調する』と指定すれば、注釈の文脈が明確になります。」

✅ 良い例:「折れ線グラフを作成してください。タイトル:『12か月でARRが1.2万ドルから9.5万ドルに』。データ:[12, 18, 22, 25, 31, 38, 44, 52, 61, 68, 78, 95](2024年1月〜12月)。12月を強調してください。出典:社内CRM。スタイル:electric-burst。」

❌ 悪い例:「当社の成長についてグラフを作成して」

コメント