JavaScriptでSVGを操りインタラクティブグラフィックを実装する手法

JavaScriptでSVGを操りインタラクティブグラフィックを実装する手法

SVG(Scalable Vector Graphics)は、解像度に依存しないグラフィックを描画するためのフォーマットです。JavaScriptを活用することで、動的かつインタラクティブなグラフィックを実現できます。本記事では、SVGを操作する基本から応用までを詳しく解説します。

SVGとは

SVGは、XMLベースのベクター画像フォーマットであり、HTMLドキュメント内で直接使用できます。

SVGをHTMLに埋め込む

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <circle cx="100" cy="100" r="50" fill="blue" />
</svg>

JavaScriptを使った基本操作

// SVG要素を取得
const svg = document.querySelector('svg');
const circle = document.querySelector('circle');

// 属性の変更
circle.setAttribute('fill', 'red');

// 新しい要素の追加
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('x', 10);
rect.setAttribute('y', 10);
rect.setAttribute('width', 50);
rect.setAttribute('height', 50);
rect.setAttribute('fill', 'green');
svg.appendChild(rect);

イベントリスナーの追加

SVG要素にイベントを追加して、インタラクティブな動作を実現します。

circle.addEventListener('click', () => {
  circle.setAttribute('fill', 'yellow');
});

SVGのアニメーション

JavaScriptを使用してSVGのアニメーションを実装します。

let angle = 0;
function animate() {
  angle += 1;
  circle.setAttribute('cx', 100 + Math.cos(angle * (Math.PI / 180)) * 50);
  circle.setAttribute('cy', 100 + Math.sin(angle * (Math.PI / 180)) * 50);
  requestAnimationFrame(animate);
}
animate();

D3.jsを使った高度な操作

D3.jsライブラリを活用することで、SVGを効率的に操作できます。

// D3.jsの基本操作
const data = [10, 20, 30, 40, 50];

const svg = d3.select('svg');
svg.selectAll('circle')
  .data(data)
  .enter()
  .append('circle')
  .attr('cx', (d, i) => 50 + i * 30)
  .attr('cy', 100)
  .attr('r', d => d)
  .attr('fill', 'blue');

ビューの変換(ズームとパン)

SVGビューを拡大縮小することで、ユーザーがよりインタラクティブに操作できるようにします。

svg.addEventListener('wheel', (event) => {
  event.preventDefault();
  const scale = Math.exp(event.deltaY * -0.01);
  svg.style.transform = `scale(${scale})`;
});

グラフィックの動的生成

データに基づいて動的にSVG要素を生成します。

const data = [
  { x: 10, y: 20, r: 10, color: 'red' },
  { x: 50, y: 70, r: 15, color: 'blue' },
  { x: 90, y: 50, r: 20, color: 'green' },
];

data.forEach(d => {
  const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
  circle.setAttribute('cx', d.x);
  circle.setAttribute('cy', d.y);
  circle.setAttribute('r', d.r);
  circle.setAttribute('fill', d.color);
  svg.appendChild(circle);
});

CSSによるスタイリング

CSSを利用してSVG要素をスタイリングできます。

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <circle cx="100" cy="100" r="50" class="animated-circle" />
</svg>

<style>
  .animated-circle {
    fill: red;
    transition: fill 0.5s ease;
  }
  .animated-circle:hover {
    fill: orange;
  }
</style>

レスポンシブデザイン

ビューのサイズに応じてSVGを調整します。

<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet">
  <circle cx="100" cy="100" r="50" fill="blue" />
</svg>

SVGと外部データの連携

外部のJSONデータを使用してSVGを生成します。

fetch('data.json')
  .then(response => response.json())
  .then(data => {
    data.forEach(item => {
      const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
      rect.setAttribute('x', item.x);
      rect.setAttribute('y', item.y);
      rect.setAttribute('width', item.width);
      rect.setAttribute('height', item.height);
      rect.setAttribute('fill', item.color);
      svg.appendChild(rect);
    });
  });

SVGフィルターの活用

フィルターを適用してSVG要素に特殊効果を追加します。

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
  <defs>
    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="5" />
    </filter>
  </defs>
  <circle cx="100" cy="100" r="50" fill="red" filter="url(#blur)" />
</svg>

まとめ

JavaScriptを使用したSVG操作は、インタラクティブなグラフィックやデータビジュアライゼーションの作成に最適です。基本的な操作からライブラリの活用までを組み合わせることで、高度なグラフィックを実現できます。