はじめに
この記事では、JavaScript 向けのデータ可視化ライブラリである D3 のスケール(入力値をもとにして、チャート上に表示する範囲を出力する)に関する以下の関数の使い分けについて、具体例を交えながら記載します。
開発環境
開発環境は以下の通りです。
- Windows 11
- Next.js 14.2.4
- React 18.3.1
- TypeScript 5.5.2
- D3 7.9.0
- @types/d3 7.4.3
ユースケース
以下のコードでは、Next.js でバブルチャートを実装しています。
X軸に element
、Y軸に score
を表示します。また、バブルの大きさは count
で表現します。
export const data = [
{ element: "A", score: 1, count: 2 },
{ element: "A", score: 2, count: 2 },
{ element: "A", score: 3, count: 4 },
{ element: "B", score: 1, count: 0 },
{ element: "B", score: 2, count: 5 },
{ element: "B", score: 3, count: 3 },
{ element: "C", score: 1, count: 7 },
{ element: "C", score: 2, count: 7 },
{ element: "C", score: 3, count: 1 },
];
X軸は scaleBand
、Y軸は scaleLiner
、バブルの大きさは scaleSqrt
を使っています。
"use client";
import { useEffect, useRef } from "react";
import * as d3 from "d3";
import { data } from "../data";
export default function Page() {
const svgRef = useRef<SVGSVGElement | null>(null);
const width = 600;
const height = 400;
const renderChart = () => {
// Define scales
const xScale = d3
.scaleBand()
.domain(data.map((d) => d.element))
.range([0, width]);
const yScale = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.score) || 0])
.range([height, 0]);
const sizeScale = d3
.scaleSqrt()
.domain([0, d3.max(data, (d) => d.count) || 0])
.range([0, 30]);
// Enable D3 API manipulate svg
const svg = d3.select(svgRef.current);
// Clear everything before appending new elements
svg.selectAll("*").remove();
// Bind data to bubbles
const bubbles = svg.selectAll(".bubble").data(data);
// Enter
bubbles
.enter()
.append("circle")
.attr("class", "bubble")
.attr("fill", "teal")
.attr("cx", (d) => xScale(d.element)! + xScale.bandwidth() / 2)
.attr("cy", (d) => yScale(d.score))
.attr("r", (d) => sizeScale(d.count));
};
useEffect(() => {
renderChart();
}, []);
return <svg ref={svgRef} width={width} height={height} />;
}
scaleBand
scaleBand
は離散値(カテゴリなど)を等間隔に表示します。
今回のユースケースでは、element(A、B、C)を 0 から width (600) の間に表示しています。
const xScale = d3
.scaleBand()
.domain(data.map((d) => d.element))
.range([0, width]);
scaleLiner
scaleLiner
は連続値を等間隔に表示します。
今回のユースケースでは、score(1、2、3)を 0 から height (400) の間に表示しています。
const yScale = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.score) || 0])
.range([height, 0]);
上記のサンプルコードの range の引数の配列を反対にする(range[0, hegiht]
)と、チャートの上下も反対になります。
scaleSqrt
scaleSqrt
も scaleLiner
と同じく連続値を入力値として受け取ります。ただ、表示の仕方が異なります。scaleLiner
が入力値の大小を直線の長短で表現するのに対し、scaleSqrt
では、点の大小で表現します。
今回のユースケースでは、count(0、...7)を 0 から 30 の大きさで表示しています。
const sizeScale = d3
.scaleSqrt()
.domain([0, d3.max(data, (d) => d.count) || 0])
.range([0, 30]);
まとめ
まとめると以下の通りです。
Scale | 入力 | 出力 | ユースケース |
---|---|---|---|
scaleBand |
離散値、カテゴリ | 連続値 | カテゴリの軸方向の表示位置 |
scaleLiner |
連続値 | 連続値 | 数値の軸方向の表示位置、線の表示位置 |
scaleSqrt |
連続値 | 連続値 | バブルなどの大きさ |