D3.js で丸角の棒グラフをつくる方法を調べました.


まず最初に,普通の棒グラフを書いてみます.

See the Pen D3.js bar chart (part 1) by Sota Hatakeyama (@chooblarin) on CodePen.

D3.js で棒グラフをつくるとき,通常は以下のようなコードを書くことになります.

svg
  .selectAll("bar")
  .data(data)
  .enter()
  .append("rect")
  .style("fill", "#E16220")
  .attr("x", d => x(d.name))
  .attr("y", d => y(d.value))
  .attr("width", x.bandwidth())
  .attr("height", d => height - y(d.value));

これは,結果として SVG 要素の <rect> で棒を表現することになります(以下のような).

...
<rect x="10" y="40" width="100" height="200"></rect>
...

<rect> にはrxryという,角を丸めるための属性があります(*).しかし,これらは全ての角に適用されてしまうので今回の目的は達成できません.

そこで,<path>で円弧を表現することにします.先ほどの棒グラフと同じものを<path>で書くには以下のようにします.(path のコマンドについてはこちらを参照して下さい.)

svg
  .selectAll("bar")
  .data(data)
  .enter()
  .append("path")
  .style("fill", "#E16220")
  .attr(
    "d",
    item => `
        M${x(item.name)},${y(item.value)}
        h${x.bandwidth()}
        v${height - y(item.value)}
        h${-x.bandwidth()}Z
      `
  );

これは,左上から時計回りに長方形を描く<path>です.

さて,この長方形の左上と右上を丸角にしたいので,“Arc curve のコマンド”を使用して以下のようにします.rxry で水平方向と鉛直方向の丸みを調整できます.

svg
  .selectAll("bar")
  .data(data)
  .enter()
  .append("path")
  .style("fill", "#E16220")
  .attr(
    "d",
    item => `
        M${x(item.name)},${y(item.value) + ry}
        a${rx},${ry} 0 0 1 ${rx},${-ry}
        h${x.bandwidth() - 2 * rx}
        a${rx},${ry} 0 0 1 ${rx},${ry}
        v${height - y(item.value) - ry}
        h${-x.bandwidth()}Z
      `
  );

完成です(以下).

See the Pen D3.js bar chart w/rounded corner by Sota Hatakeyama (@chooblarin) on CodePen.

おまけ

React + D3.js のサンプルをこちらに公開しているので良かったら見てみてください.