D3.js を使用してデータを色分けしてプロットする場合、グラフの右上などに凡例(色の意味)を表示したくなります。
ここでは、色を管理するために d3.scaleOrdinal()
を使用していると仮定し、凡例を表示する方法を説明します。
d3.scaleOrdinal()
関数についての詳細は、以下の記事をご参照ください。
カラースケールから凡例に並べる項目を取り出す
d3.scaleOrdinal()
関数で作成したスケール関数(下記例では color
)に何らかのデータを引数で渡すと、そのデータに対応する色情報を返してくれます。
import * as d3 from 'd3';
// D3.js 組み込みのカラースケール
const color = d3.scaleOrdinal(d3.schemeCategory10);
const c1 = color('A'); //=> '#1f77b4'
const c2 = color('B'); //=> '#ff7f0e'
const c3 = color('C'); //=> '#2ca02c'
const c4 = color('A'); //=> '#1f77b4'
const c5 = color('B'); //=> '#ff7f0e'
上記の例の場合、A
、B
、C
という 3 種類のデータに対して、3 種類の色が割り当てられています。
このとき、カラースケール (color
) の内部では、これまで入力された A
、B
、C
というキー情報が管理されており、domain()
メソッドを引数なしで呼び出すことで取り出すことができます。
console.log(color.domain()); //=> ['A', 'B', 'C']
つまり、この配列データを凡例の項目として表示すればよいことになります。
実装例
下記の関数は、与えられた D3.js セレクションに対して、凡例を描画するための描画要素を追加します。
ポイントは、カラースケールの domain()
メソッドを使って、凡例に表示すべき項目のリストを取り出しているところです。
凡例自体の色指定にもカラースケールを利用しています。
あとは、何らかのデータをプロットした後に、この凡例描画関数を呼び出せば OK です。 カラースケールから表示項目を取り出しているので、先にカラースケールを使ってデータのプロットを済ませておく必要があります。
// 適当なデータを用意(同じキーのデータには同じ色が付く想定)
const data = Array.from({ length: 10 }, () => ['A', 'B', 'C']).flat();
// 組み込みのカラースケールを使用
const color = d3.scaleOrdinal(d3.schemeCategory10);
// データを円でプロット(座標はランダム)
const svg = d3.select('#svg-u25y');
svg.selectAll('circle')
.data(data)
.join('circle')
.attr('cx', () => Math.random() * 200 + 15)
.attr('cy', () => Math.random() * 70 + 10)
.attr('r', (_d, i) => (i % 4) + 3)
.attr('fill', (d) => color(d))
.attr('opacity', 0.7);
// 凡例を描画
drawLegend(svg, color);