mcpField
V
visx

visx

github.com/cericoデータ・データベース037 回インストール28 週間前に更新
リポジトリ

visx について

visxは、D3のプリミティブを使ってカスタムデータビジュアライゼーションを構築するReactライブラリです。このスターター向けスキルは、ダッシュボードや個別のデザイン要件に合わせたインタラクティブでレスポンシブな可視化のパターンを提供します。

主な機能

  1. 01D3プリミティブを使うReactコンポーネント
  2. 02折れ線・棒グラフのパターン
  3. 03レスポンシブなチャートコンテナ
  4. 04ツールチップの操作パターン
  5. 05SVGのスタイリングガイド

活用シーン

  1. 01カスタムのインタラクティブチャート作成
  2. 02ダッシュボードの可視化構築
  3. 03コンテナに応じたチャートの作成

インストール

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

$npx skills add https://github.com/cerico/macfair --skill visx

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

詳細

visx

visx(Airbnb の React + D3 ライブラリ)を使って、React でデータビジュアライゼーションを構築します。

ステータス:スターター

パターンは利用を重ねるなかで進化していきます。

使用する場面

  • 基本的なチャートライブラリでは対応できないカスタムチャート
  • インタラクティブなデータ探索
  • 特定のデザイン要件があるダッシュボード
  • React のパターンを使いながら、D3 のパワーを活用したい場合

他の選択肢より visx を選ぶ理由

ライブラリ適した用途
visxカスタム性、インタラクティブ性、デザイン要件を重視したチャート
Recharts手早く作成する標準的なチャート
Chart.jsシンプルなキャンバスベースのチャート
D3 directReact を使わず、最大限の制御が必要な場合

visx は、D3 のプリミティブを React コンポーネントとして提供します。完全な制御が可能で、React との相性にも優れています。

セットアップ

# Core
pnpm add @visx/group @visx/scale @visx/shape @visx/axis @visx/grid

# Common additions
pnpm add @visx/tooltip @visx/responsive @visx/gradient @visx/curve

# All of visx (larger bundle)
pnpm add @visx/visx

基本パターン

折れ線グラフ
import { LinePath } from '@visx/shape'
import { scaleLinear, scaleTime } from '@visx/scale'
import { AxisBottom, AxisLeft } from '@visx/axis'
import { Group } from '@visx/group'

interface DataPoint {
  date: Date
  value: number
}

const data: DataPoint[] = [
  { date: new Date('2024-01'), value: 10 },
  { date: new Date('2024-02'), value: 25 },
  { date: new Date('2024-03'), value: 15 },
]

const width = 600
const height = 400
const margin = { top: 20, right: 20, bottom: 40, left: 40 }

const innerWidth = width - margin.left - margin.right
const innerHeight = height - margin.top - margin.bottom

const xScale = scaleTime({
  domain: [Math.min(...data.map(d => d.date)), Math.max(...data.map(d => d.date))],
  range: [0, innerWidth],
})

const yScale = scaleLinear({
  domain: [0, Math.max(...data.map(d => d.value))],
  range: [innerHeight, 0],
})

export function LineChart() {
  return (
    <svg width={width} height={height}>
      <Group left={margin.left} top={margin.top}>
        <AxisBottom scale={xScale} top={innerHeight} />
        <AxisLeft scale={yScale} />
        <LinePath
          data={data}
          x={d => xScale(d.date)}
          y={d => yScale(d.value)}
          stroke="currentColor"
          strokeWidth={2}
        />
      </Group>
    </svg>
  )
}
棒グラフ
import { Bar } from '@visx/shape'
import { scaleBand, scaleLinear } from '@visx/scale'
import { Group } from '@visx/group'

interface DataPoint {
  label: string
  value: number
}

const data: DataPoint[] = [
  { label: 'A', value: 30 },
  { label: 'B', value: 80 },
  { label: 'C', value: 45 },
]

const xScale = scaleBand({
  domain: data.map(d => d.label),
  range: [0, innerWidth],
  padding: 0.2,
})

const yScale = scaleLinear({
  domain: [0, Math.max(...data.map(d => d.value))],
  range: [innerHeight, 0],
})

export function BarChart() {
  return (
    <svg width={width} height={height}>
      <Group left={margin.left} top={margin.top}>
        {data.map(d => (
          <Bar
            key={d.label}
            x={xScale(d.label)}
            y={yScale(d.value)}
            width={xScale.bandwidth()}
            height={innerHeight - yScale(d.value)}
            fill="currentColor"
          />
        ))}
      </Group>
    </svg>
  )
}
レスポンシブコンテナー
import { ParentSize } from '@visx/responsive'

export function ResponsiveChart() {
  return (
    <ParentSize>
      {({ width, height }) => (
        <LineChart width={width} height={height} />
      )}
    </ParentSize>
  )
}
ツールチップ
import { useTooltip, TooltipWithBounds } from '@visx/tooltip'
import { localPoint } from '@visx/event'

const { showTooltip, hideTooltip, tooltipData, tooltipLeft, tooltipTop } = useTooltip()

// In your component:
<circle
  onMouseMove={(event) => {
    const point = localPoint(event)
    showTooltip({
      tooltipData: dataPoint,
      tooltipLeft: point.x,
      tooltipTop: point.y,
    })
  }}
  onMouseLeave={hideTooltip}
/>

{tooltipData && (
  <TooltipWithBounds left={tooltipLeft} top={tooltipTop}>
    {tooltipData.value}
  </TooltipWithBounds>
)}

Tailwind を使ったスタイリング

visx は SVG を描画するため、className またはインラインスタイルでスタイルを設定できます。

<LinePath
  stroke="hsl(var(--primary))"
  className="transition-all duration-200"
/>

参考資料

TODO

  • パターンを確立するための、最初の実用的なチャート
  • 面グラフのパターンを追加
  • 円グラフ/ドーナツグラフのパターンを追加
  • アニメーションのパターンを追加
  • tRPC のデータ取得と統合

コメント