以前、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する - クモのようにコツコツと
SVGとCanvasの違い
SVGとCanvasの違いは下記のようなものです。
- Canvasは
canvas
要素という四角い枠の内部にパーツを配置し、ビットマップ形式で描画する。 - SVGはパーツごとに様々な種類の
svg
要素をHTMLに配置し、ベクター形式で描画する。
Canvasは四角い枠の中に完全にパッケージングされており、three.jsなどの3Dアニメまで作れる。
※参考:Three.js入門サイトに私も入門する!! - クモのようにコツコツと
一方SVGはパーツごとにCSSやJSで操作ができる。どちらも良し悪しがありそう。 しかしそのパーツを形作るSVG要素たちの種類が膨大で敷居が高く感じるんだよなー。
※参考:SVG 要素リファレンス - SVG: Scalable Vector Graphics | 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(引数) ;
- 変数
chart
にc3
オブジェクトの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つの値。
data1
、data2
の折れ線グラフを見ると後ろに続く6つの値と一致している。
今回上書きした値にはチャートの形を指定する記述がないので、C3.jsのデフォルトの図は「折れ線グラフ」ということがわかる。
あと、data1
、data2
をポチポチ押すと、デフォルトでアニメーション設定されてる!
CSSを変えてみる。
SVGはCanvasとちがってパーツごとに要素が別れているので、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
プロパティを#ccc
、stroke-width
プロパティを2
に。
文字サイズを大きく、黒線の色を薄くして、線を太くしました。
SVG独自の要素もCSSで変えられるんですね!しかもstroke
とか見慣れない独自のプロパティがある。
※参考:SVGでアウトラインをカスタマイズしてみよう | Webクリエイターボックス
SVG要素が書き出されていた
ちなみにデベロッパーツールで見ると、最初に自分で書いたHTMLの#chart
のdiv
要素の中にはsvg
、defs
、clipPath
、rect
、g
、text
、circle
など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ともよく似ていると感じたので、共に引き続き触っていきたいと思いました。それではまた!!