Power BI カスタムビジュアル開発 : 積み上げ棒グラフの開発 : X、Y 軸および凡例の描画


前回まででメインのグラフは描画できました。今回は X 軸などグラフに必要な他の要素を描写します。

X 軸

d3 の機能を使って X 軸が簡単に描写できます。

1. まず X 軸の描写領域用の入れ物を定義。Visual クラスのプロパティに以下コードを追加。

private xAxis: d3.Selection<d3.BaseType, any, any, any>;

2. コンストラクタ内で初期化。ルートの SVC に対して g 要素を追加。

constructor(options: VisualConstructorOptions) {
    this.svg = d3.select<SVGElement, any>(<any> options.element)
        .append('svg');
    this.stackBarContainer = this.svg
        .append('g');
    this.xAxis = this.svg
        .append('g');
}

3. X 軸を表示できるようグラフ領域のマージンを変更。

let margin = { top: 0, bottom: 30, left: 0, right: 0 }

4. update 関数の一番下に以下コードを追加。

  • transform 要素を使って表示場所を下に移動
  • d3.axisBottom に、定義した x 関数を渡して X 軸を作成
let xAxis = g => g
    .attr("transform", `translate(0,${height - margin.bottom})`)
    .call(d3.axisBottom(x).tickSizeOuter(0))
    .call(g => g.selectAll(".domain").remove());
this.xAxis.call(xAxis);

5. カスタムビジュアルを確認。

Y 軸

ほぼ X 軸と同じように実装できます。

1. Y 軸の描写領域用の入れ物を定義。Visual クラスのプロパティに以下コードを追加。

private yAxis: d3.Selection<d3.BaseType, any, any, any>;

2. コンストラクタ内で初期化。ルートの SVC に対して g 要素を追加。

this.yAxis = this.svg
    .append('g');

3. Y 軸を表示できるようグラフ領域のマージンを変更。

let margin = { top: 0, bottom: 30, left: 40, right: 0 }

4. update 関数の一番下に以下コードを追加。

  • transform 要素を使って表示場所を左に移動
  • d3.axisLeft に、定義した y 関数を渡して Y 軸を作成
let yAxis = g => g
    .attr("transform", `translate(${margin.left},0)`)
    .call(d3.axisLeft(y).ticks(null, "s"))
    .call(g => g.selectAll(".domain").remove());
this.yAxis.call(yAxis);

5. カスタムビジュアルを確認。

凡例

基本的な考え方は同じですが、凡例は通常、四角や丸などと文字列を一緒に表示するため、要素が増えます。

1. 凡例描写領域用の入れ物を定義。Visual クラスのプロパティに以下コードを追加。

private legend: d3.Selection<d3.BaseType, any, any, any>;

2. コンストラクタ内で初期化。ルートの SVC に対して g 要素を追加。

this.legend = this.svg
    .append("g");

3. 凡例を表示できるようグラフ領域のマージンを変更。

let margin = { top: 0, bottom: 30, left: 40, right: 130 }

4. update 関数の一番下に以下コードを追加。

  • circle と text 要素で構成するため、要素を一段階追加
  • transform で画面右側に表示
  • 凡例の順番とグラフの順番が逆のため、reverse() で入れ替え
  • 各凡例が重ならないよう data 関数後に 20 ピクセルずつずれるよう transform を実行
let legend = svg => {
    let g = svg
        .attr("transform", `translate(${width - margin.right}, 0)`)
        .selectAll("g")
        .data(legends.reverse())
        .join("g")
        .attr("transform", (d, i) => `translate(0,${i * 20})`)

    g.call(g => g.selectAll("circle").remove());
    g.call(g => g.selectAll("text").remove());

    g.append("circle")
        .attr("cx", 20)
        .attr("cy", 10)
        .attr("r", 5)
        .attr("fill", d => color(d));

    g.append("text")
        .attr("x", 30)
        .attr("y", 9.5)
        .attr("dy", "0.35em")
        .text(d => d);
}
this.legend.call(legend);

5. カスタムビジュアルを確認。

まとめ

今回はメインのグラフ以外の要素を描写しました。うまく表示されているように見えますが、凡例の文字列が長くなったり、短くなったりすると動的に対応できないため、次回は提供されている Utility を使って動的に計算してみます。また書式も設定してみます。

次の記事へ
目次へ戻る