クモのようにコツコツと

Webデザイナー イイダリョウのブログです。

SVGの方のチャートライブラリ「C3.js」をGettingしてStartedする

以前、JSで図(チャート)を作るライブラリとしてCanvasベースの「Chart.js」をGettingしてStartedしました。そのときにもう一つSVGベースのライブラリ「D3.js」も候補で考えていたのですがChart.jsと比べて少し敷居が高く感じてました。
その後、D3.jsベースでチャート機能に特化して作られた「C3.js」の存在を知りました。SVGがどんなものなのかも気になっていたので、さっそくGettingしてStartedしたいと思います!

※目次:

※参考:JSライブラリとは?
【卒jQueryへの道】生JSとライブラリとフレームワークの理解 - クモのようにコツコツと

※参考:Canvasベースのチャートライブラリ
Chart.jsをGettingしてStartedする - クモのようにコツコツと

SVGCanvasの違い

SVGCanvasの違いは下記のようなものです。

  • Canvascanvas要素という四角い枠の内部にパーツを配置し、ビットマップ形式で描画する。
  • SVGはパーツごとに様々な種類のsvg要素をHTMLに配置し、ベクター形式で描画する。

Canvasは四角い枠の中に完全にパッケージングされており、three.jsなどの3Dアニメまで作れる。

※参考:Three.js入門サイトに私も入門する!! - クモのようにコツコツと

一方SVGはパーツごとにCSSやJSで操作ができる。どちらも良し悪しがありそう。 しかしそのパーツを形作るSVG要素たちの種類が膨大で敷居が高く感じるんだよなー。

※参考:SVG 要素リファレンス - SVG | MDN

C3.jsの公式サイト

兎にも角にも公式サイトに行ってみる。うむ、英語。安定的に英語。ふぅ。。
お、Chart.jsのサイトと同様に「Getting Started」のボタンがあります。ポチッとな。

※参考:C3.js | D3-based reusable chart library

CSSとJSファイルの読み込む

お、Chart.jsは本体ファイルが1ファイルだったけど、C3.jsはc3.cssというCSSファイル、D3.jsおよびc3.jsと3ファイル読み込むわけですな。D3ベースなのでD3を先に読むのがポイント。

<!-- Load c3.css -->
<link href="/path/to/c3.css" rel="stylesheet">

<!-- Load d3.js and c3.js -->
<script src="/path/to/d3.v5.min.js" charset="utf-8"></script>
<script src="/path/to/c3.min.js"></script>

これ、またCodePenでやりたいのでCDN、ないかねー… ありました!

<!-- Load c3.css -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.7/c3.css" rel="stylesheet">

<!-- Load d3.js and c3.js -->
<script src="https://d3js.org/d3.v5.min.js" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.7/c3.js"></script>

さあ、準備完了でっす。

コードを貼ってみる

Getting Startedの最初にあるコードを貼ってみましょう。

おお!いきなりでたぁ(感激) 貼ったコードはこんなです。まずHTML。

<div id="chart"></div>

おや?#chartというid名を付けたdiv要素だ。何の変哲もない標準タグでいいんですね。SVGの特殊なタグを書かなくてええか?ええのんか!?

JSの方はどうでしょう。

var chart = c3.generate({
    bindto: '#chart',
    data: {
      columns: [
        ['data1', 30, 200, 100, 400, 150, 250],
        ['data2', 50, 20, 10, 40, 15, 25]
      ]
    }
});

おお、Chart.jsよりさらに簡潔ですな。

JSを読み解く

JSを見ていきます。
まず、冒頭は、変数chartの定義です。

var chart = c3.generate(引数) ;
  • 変数chartc3オブジェクトのgenerate()メソッドを代入する。

C3.jsにあらかじめ定義されているc3オブジェクトとgenerate()メソッドがここに読み込まれるんですな。
generateは「生成する」という意味です。チャートを生成するんだね。

次に、引数の中を見ていきましょう。

var chart =c3.generate({
//連想配列
キー: 値,
キー: 値,
キー: 値,
}) ;

引数の中にはすぐブロックの波括弧{ }があり、中にはキーと値が。これは連想配列ですね。
generate()メソッドの中に設定されている連想配列をここで上書きするわけです。

では、その中身を見ていきましょう。まず一行目。

    bindto: '#chart',

bindto=bind to。bindは縛る、くくるという意味。バインダーとかね。
id名'#chart'の要素とC3.jsを紐づけているわけです。

次はこちら。

    data: {
      columns: [
        ['data1', 30, 200, 100, 400, 150, 250],
        ['data2', 50, 20, 10, 40, 15, 25]
      ]
    }
  • dataキーの値が入れ子構造になっている。
  • dataキーの中に連想配列clumnsキーがある。
  • clumnsキーの値は配列になっている。
  • 配列の中はさらに2つの配列。1つ目は'data1', 30, 200, 100, 400, 150, 250という7つの値。
  • 2つ目の配列も'data2', 50, 20, 10, 40, 15, 25という7つの値。

data1data2の折れ線グラフを見ると後ろに続く6つの値と一致している。 今回上書きした値にはチャートの形を指定する記述がないので、C3.jsのデフォルトの図は「折れ線グラフ」ということがわかる。
あと、data1data2をポチポチ押すと、デフォルトでアニメーション設定されてる!

CSSを変えてみる。

SVGCanvasとちがってパーツごとに要素が別れているので、CSSでも操作ができそうだ。ちょっと設定してみる。

おお!変わった!

.c3 svg ,
.c3-legend-item {
  font-size: 15px;
}

.c3 path {
  stroke: #ccc;
  stroke-width:  2;
}
  • class名.c3の中のsvg要素と、class名.c3-legend-itemの文字サイズを15pxに。
  • class名.c3の中のpath要素のstrokeプロパティを#cccstroke-widthプロパティを2に。

文字サイズを大きく、黒線の色を薄くして、線を太くしました。
SVG独自の要素もCSSで変えられるんですね!しかもstrokeとか見慣れない独自のプロパティがある。

※参考:SVGでアウトラインをカスタマイズしてみよう | Webクリエイターボックス

SVG要素が書き出されていた

ちなみにデベロッパーツールで見ると、最初に自分で書いたHTMLの#chartdiv要素の中にはsvgdefsclipPathrectgtextcircleなどSVG独自のタグが整形されていました。

<div id="chart">
<svg width="1568" height="320" style="overflow: hidden;">
  <defs>
    <clipPath id="c3-1534079080787-clip">
      <rect width="1526" height="266"></rect>
    </clipPath>
    <!--(中略)-->
  </defs>
  <g transform="translate(40.5,4.5)">
    <text class="c3-text c3-empty" text-anchor="middle" dominant-baseline="middle" x="763" y="133" style="opacity: 0;"></text>
    <g clip-path="url(https://s.codepen.io/boomerang/iFrameKey-10254586-52f4-8d20-e6e2-5f11ba3bb0bd/index.html#c3-1534079080787-clip)" class="c3-regions" style="visibility: visible;"></g>
    <!--(中略)-->
          <g class=" c3-shapes c3-shapes-data1 c3-circles c3-circles-data1" style="cursor: pointer;">
            <circle class=" c3-shape c3-shape-0 c3-circle c3-circle-0" cx="15" cy="232.59188034188034" r="2.5" style="fill: rgb(31, 119, 180); opacity: 1;"></circle>
            <circle class=" c3-shape c3-shape-1 c3-circle c3-circle-1" cx="315" cy="136.3311965811966" r="2.5" style="fill: rgb(31, 119, 180); opacity: 1;"></circle>
            <circle class=" c3-shape c3-shape-2 c3-circle c3-circle-2" cx="614" cy="192.9551282051282" r="2.5" style="fill: rgb(31, 119, 180); opacity: 1;"></circle>
            <circle class=" c3-shape c3-shape-3 c3-circle c3-circle-3" cx="913" cy="23.083333333333343" r="2.5" style="fill: rgb(31, 119, 180); opacity: 1;"></circle>
            <circle class=" c3-shape c3-shape-4 c3-circle c3-circle-4" cx="1212" cy="164.6431623931624" r="2.5" style="fill: rgb(31, 119, 180); opacity: 1;"></circle>
            <circle class=" c3-shape c3-shape-5 c3-circle c3-circle-5" cx="1512" cy="108.01923076923077" r="2.5" style="fill: rgb(31, 119, 180); opacity: 1;"></circle>
          </g>
    <!--(中略)-->
  </g>
  <text class="c3-title" x="784" y="0"></text>
</svg>
</div>

最後に

C3.js思ってたより簡単で、SVG独自のタグを書かずにSVG初体験できちゃいましたー。 Chart.jsともよく似ていると感じたので、共に引き続き触っていきたいと思いました。それではまた!!