ChatGPT先生と一緒に学ぶフロントエンド D3.js編 その2
本記事では第1部の「第3章 SVGとは何か」を取り上げます。
SVGとは何か
SVGはScalable Vector Graphicsの頭文字を取ったものです。ベクトルベースのグラフィックを描画するためのマークアップ言語の1つです。
なるほど。
知らなかった。ちなみに先生に聞いてみると
SVGデータとは何ですか?
「SVGは、スケーラブルベクターグラフィックス(Scalable Vector Graphics)の略称です。SVGはXMLベースの画像形式で、Webページやドキュメント内で使用するために設計されたオープンスタンダードのベクター画像形式です。
SVGは、図形、テキスト、画像、アニメーション、ボタンなど、様々な種類のコンテンツを含むことができます。SVGは、コンピューターの解像度やサイズに関係なく、クリアで鮮明な画像を提供することができます。
また、SVGは、ベクター形式のため、拡大縮小しても画質が劣化しないという利点があります。SVGファイルは、テキストベースであるため、編集が容易であり、JavaScriptを使用してアニメーションやインタラクティブな機能を追加することもできます。SVGは、ウェブ開発者、グラフィックデザイナー、イラストレーターなど、多くの人々によって広く使用されています。」
よくご存知でした。
SVGの基本要素の一覧と主要なパラメータ
本章ではまず基本図形をSVGで描画する方法を学びます。書籍で提示されている図形要素は以下の8種類です。
- rect(矩形):指定された位置に矩形を描画する要素。x、y、width、height属性を使用して位置とサイズを指定できる。
- circle(円):指定された中心点を中心に、指定された半径の円を描画する要素。cx、cy、r属性を使用して中心点と半径を指定できる。
- ellipse(楕円):指定された中心点を中心に、指定されたx軸とy軸の半径を持つ楕円を描画する要素。cx、cy、rx、ry属性を使用して中心点と半径を指定できる。
- line(線):指定された始点と終点を結ぶ線を描画する要素。x1、y1、x2、y2属性を使用して始点と終点の座標を指定できる。
- polyline(ポリライン):指定された座標を結んで描画する多角線を描画する要素。points属性を使用して座標を指定できる。
- polygon(ポリゴン):指定された座標を結んで描画する多角形を描画する要素。points属性を使用して座標を指定できる。
- path(パス):線、曲線、弧、閉じた領域を描画する複合的な図形を描画するための要素。d属性を使用してパスデータを指定する。
- text(テキスト):指定された位置にテキストを描画する要素。x、y属性を使用して位置を指定し、text-anchor属性を使用して水平方向の配置を指定し、font-size属性を使用してフォントサイズを指定できる。
実際にサンプルを先生に書いてもらいました。
以下の図形要素をSVGで描画するサンプルコードをそれぞれ書いて、一つのHTMLファイルにまとめてください。
- rect
- circle
- elipse
- line
- polyline
- polygon
- path
- text
「以下は、上記のSVG要素を一つのHTMLファイルにまとめたサンプルコードです。」
<!DOCTYPE html> <html> <head> <title>SVG Sample</title> </head> <body> <svg width="300" height="300"> <rect x="20" y="20" width="100" height="100" fill="blue" /> <circle cx="200" cy="60" r="50" fill="red" /> <ellipse cx="150" cy="150" rx="80" ry="40" fill="green" /> <line x1="20" y1="200" x2="280" y2="200" stroke="black" stroke-width="2" /> <polyline points="30,250 70,250 50,290 90,290" fill="none" stroke="black" stroke-width="2" /> <polygon points="150,220 200,280 250,220" fill="yellow" stroke="black" stroke-width="2" /> <path d="M 30 150 L 150 30 L 270 150" fill="none" stroke="black" stroke-width="2" /> <text x="150" y="170" text-anchor="middle" font-size="40" fill="purple">SVG</text> </svg> </body> </html>
すごい。芸術的なサンプルを書いてくれました。ここに登場している変数の意味も尋ねました。
「以下は、上記のSVGのサンプルコードで使用されている変数の意味です。」
- width:SVGイメージの横幅を指定する属性。
- height:SVGイメージの縦幅を指定する属性。
- rect:矩形を描画する要素。
- x:矩形の左上隅のx座標を指定する属性。
- y:矩形の左上隅のy座標を指定する属性。
- width:矩形の幅を指定する属性。
- height:矩形の高さを指定する属性。
- fill:矩形の塗りつぶし色を指定する属性。
- circle:円を描画する要素。
- cx:円の中心のx座標を指定する属性。
- cy:円の中心のy座標を指定する属性。
- r:円の半径を指定する属性。
- ellipse:楕円を描画する要素。
- rx:楕円のx軸半径を指定する属性。
- ry:楕円のy軸半径を指定する属性。
- line:線を描画する要素。
- x1:線の始点のx座標を指定する属性。
- y1:線の始点のy座標を指定する属性。
- x2:線の終点のx座標を指定する属性。
- y2:線の終点のy座標を指定する属性。
- stroke:線の色を指定する属性。
- stroke-width:線の太さを指定する属性。
- polyline:多角線を描画する要素。
- points:多角線の座標を指定する属性。
- polygon:多角形を描画する要素。
- path:複合的な図形を描画する要素。
- d:パスデータを指定する属性。
- text:テキストを描画する要素。
- text-anchor:テキストの水平方向の配置を指定する属性。
- font-size:テキストのフォントサイズを指定する属性。
- fill:テキストの塗りつぶし色を指定する属性。
パスデータを指定するd属性の表記が見慣れないので、再度質問してみます。
path d="M 30 150 L 150 30 L 270 150"の"M 30 150 L 150 30 L 270 150"はどういう意味ですか?
「『M 30 150 L 150 30 L 270 150』は、パスデータと呼ばれる文字列で、要素で描画されるパスの形状を定義します。 Mは、パスの始点を表します。この場合、始点は座標 (30, 150) に設定されています。Lは、直線を描画するコマンドで、その後に続く座標を終点として直線を引きます。したがって、L 150 30は、座標 (30, 150) から座標 (150, 30) までの直線を描画することを意味します。同様に、L 270 150は、座標 (150, 30) から座標 (270, 150) までの直線を描画します。
これにより、(30, 150) を始点とし、(150, 30) と (270, 150) を結ぶ三角形の輪郭が描画されます。」
基本要素の一つの「パス」を描画する命令
d属性では他にどのような命令が可能ですか? 「d属性では、以下のような命令が可能です。
- M:指定された座標に移動する(Move to)。
- L:指定された座標まで直線を描画する(Line to)。
- H:指定されたx座標まで水平線を描画する(Horizontal line to)。
- V:指定されたy座標まで垂直線を描画する(Vertical line to)。
- A:指定された半径を持つ円弧を描画する(Arc)。
- C:3つの制御点を指定して、指定された座標までのカーブを描画する(Cubic Bezier curve)。
- S:2つの制御点と終点を指定して、指定された座標までのカーブを描画する(Smooth cubic Bezier curve)。
- Q:1つの制御点を指定して、指定された座標までのカーブを描画する(Quadratic Bezier curve)。
- T:1つの制御点と終点を指定して、指定された座標までのカーブを描画する(Smooth quadratic Bezier curve)。
- Z:現在のパスの始点までの直線を描画し、パスを閉じる(Close path)。
これらの命令を組み合わせて、複雑なパスを描画することができます。」
これらの命令を使った複雑なパスの例をそれぞれの命令について、図形名とサンプルのHTMLコードを挙げながら書いてください。 M:指定された座標に移動する(Move to) 図形名:「ドクロ」
<svg width="300" height="300"> <path d="M 100 50 A 25 25, 0, 0, 0, 150 50 A 25 25, 0, 0, 0, 100 50 M 130 75 A 20 20, 0, 0, 1, 130 125 L 160 125 A 20 20, 0, 0, 1, 160 75 Z" fill="black" /> </svg>
このSVGイメージは、ドクロを描画しています。M命令で始点を設定し、A命令で円弧を描画し、最後に同じ始点に移動していることに注意してください。図形の塗りつぶし色は黒色で、塗りつぶされた面積のみを描画するために、線は描画されていません。
L:指定された座標まで直線を描画する(Line to) 図形名:「三角形の山」
<svg width="300" height="300"> <path d="M 50 200 L 80 120 L 110 200 L 140 120 L 170 200 L 200 120 L 230 200" fill="none" stroke="black" stroke-width="2" /> </svg>
このSVGイメージは、三角形の山を描画しています。M命令で始点を設定し、L命令で複数の座標までの直線を描画します。図形の塗りつぶし色はなく、輪郭の色は黒色、幅は2です。
H:指定されたx座標まで水平線を描画する(Horizontal line to) 図形名:「曲線上を進む四角形」
<svg width="300" height="300"> <path d="M 50 100 Q 100 0, 150 100 H 50 Z" fill="red" /> <path d="M 200 100 Q 250 0, 300 100 H 200 Z" fill="green" /> </svg>
このSVGイメージは、曲線上を進む四角形を描画しています。M命令で始点を設定し、Q命令で曲線を描画します。次に、H命令で指定されたx座標まで水平線を描画し、最後Z命令でパスを閉じます。図形の塗りつぶし色は、赤色と緑色です。それぞれの四角形は、曲線上に描画されています。
V:指定されたy座標まで垂直線を描画する(Vertical line to) 図形名:「バナナ」
<svg width="300" height="300"> <path d="M 150 150 Q 250 200, 200 300 V 150 Z" fill="yellow" stroke="black" stroke-width="2" /> </svg>
このSVGイメージは、バナナを描画しています。M命令で始点を設定し、Q命令で曲線を描画します。次に、V命令で指定されたy座標まで垂直線を描画し、最後にZ命令でパスを閉じます。図形の塗りつぶし色は黄色で、輪郭の色は黒色、幅は2です。
A:指定された半径を持つ円弧を描画する(Arc) 図形名:「風車」
<svg width="300" height="300"> <path d="M 150 150 L 150 50 A 100 100, 0, 0, 0, 200 100 L 150 150" fill="none" stroke="black" stroke-width="2" /> <circle cx="150" cy="150" r="50" fill="red" /> </svg>
このSVGイメージは、風車を描画しています。M命令で始点を設定し、L命令で線を描画します。次に、A命令で指定された半径を持つ円弧を描画します。図形の塗りつぶし色はなく、風車の輪郭は黒色、幅は2です。風車の中心には、赤色の円が描画されています。
C:3つの制御点を指定して、指定された座標までのカーブを描画する(Cubic Bezier curve) 図形名:「波」
<svg width="300" height="300"> <path d="M 50 150 C 100 50, 200 250, 250 150 C 280 100, 320 50, 350 100 C 400 200, 500 50, 550 150" fill="none" stroke="blue" stroke-width="3" /> </svg>
このSVGイメージは、波を描画しています。M命令で始点を設定し、C命令で3つの制御点を指定して、指定された座標までのカーブを描画します。図形の塗りつぶし色はなく、輪郭の色は青色で、幅は3です。
S:2つの制御点と終点を指定して、指定された座標までのカーブを描画する(Smooth cubic Bezier curve) 図形名:「楕円」
<svg width="300" height="300"> <path d="M 50 150 C 50 50, 150 50, 150 150 S 250 250, 250 150 C 250 50, 350 50, 350 150 S 450 250, 450 150" fill="none" stroke="purple" stroke-width="3" /> </svg>
このSVGイメージは、楕円を描画しています。M命令で始点を設定し、最初のC命令で3つの制御点を指定して、カーブを描画します。次に、S命令で2つの制御点と終点を指定して、次のカーブを描画します。図形の塗りつぶし色はなく、輪郭の色は紫色で、幅は3です。
Q:1つの制御点を指定して、指定された座標までのカーブを描画する(Quadratic Bezier curve) 図形名:「花」
<svg width="300" height="300"> <path d="M 150 50 Q 200 100, 150 150 Q 100 200, 150 250 Q 200 200, 250 250 Q 300 200, 250 150 Q 200 100, 250 50 Q 200 0, 150 50" fill="none" stroke="pink" stroke-width="2" /> </svg>
このSVGイメージは、花を描画しています。M命令で始点を設定し、Q命令で1つの制御点を指定して、指定された座標までのカーブを描画します。図形の塗りつぶし色はなく、輪郭の色はピンク色で、幅は2です。T:1つの制御点と終点を指定して、指定された座標までのカーブを描画する(Smooth quadratic Bezier curve)
図形名:「鳥」
<svg width="300" height="300"> <path d="M 50 150 Q 150 50, 250 150 T 450 150" fill="none" stroke="orange" stroke-width="3" /> <circle cx="150" cy="125" r="25" fill="orange" /> <circle cx="250" cy="125" r="25" fill="orange" /> </svg>
このSVGイメージは、鳥を描画しています。M命令で始点を設定し、最初のQ命令で1つの制御点を指定して、カーブを描画します。次に、T命令で1つの制御点と終点を指定して、次のカーブを描画します。図形の塗りつぶし色はなく、輪郭の色はオレンジ色で、幅は3です。鳥の目は、オレンジ色の円で描画されています。
Z:現在のパスの始点までの直線を描画し、パスを閉じる(Close path) 図形名:「星」
<svg width="300" height="300"> <path d="M 150 50 L 180 120 L 250 120 L 200 170 L 220 240 L 150 200 L 80 240 L 100 170 L 50 120 L 120 120 Z" fill="gold" stroke="black" stroke-width="3" /> </svg>
このSVGイメージは、星を描画しています。M命令で始点を設定し、L命令で直線を描画します。最後に、Z命令でパスを閉じます。図形の塗りつぶし色は金色で、輪郭の色は黒色で、幅は3です。
図形の解釈には議論がありそうですが、各命令の役割がよくわかりました。
SVG要素のグループ化について
3章の最後では複数のSVG要素をまとめて扱うグループ化について説明しています。先生に要約してもらいました。
SVG要素のグループ化とは何ですか?箇条書きで要点を4つ示してください。
「SVG要素のグループ化とは、複数のSVG要素をひとつのまとまりとして扱うことです。以下は、SVG要素のグループ化の要点です。
- g要素を使用して、複数のSVG要素をグループ化することができます。
- グループ内の要素は、まとめて変換、操作、スタイル変更することができます。
- g要素には、transform属性を使用して、グループ内のすべての要素に変換を適用することができます。
- g要素には、style属性を使用して、グループ内のすべての要素にスタイルを適用することができます。 」
ChatGPT先生と一緒に学ぶフロントエンド D3.js編 その1
はじめに
ChatGPTなど大規模言語モデルを活用したサービスの登場により、プログラミング言語などを学ぶ初期コストが大きく下がりました。そこで、まず第一弾としてフロントエンドのデータ可視化を中心とした情報設計に有用なJavaScriptのD3.jsをChatGPT先生と一緒に学びます。
使う教材
メルカリで990円で購入した以下の書籍を使用します。
書籍は全体の構造として15章に分かれていますが、大きく以下の3部に分割できます。
- 1~6章 基礎的な知見、操作
- 6~14章 主要なチャートの作成方法
- 15章 地図データの可視化
本の中のサンプルコードは以下ページで公開されています。
https://www.sbcr.jp/product/4797368864/
ではさっそく2章(1章はD3.jsとは何かの読み物なので飛ばします)から学び始めます。
第2章 D3.jsの基本 D3.jsでグラフを描く
D3.jsでのデータ可視化は以下の6つのフローで構成されます。
- データ読み込み
- 表示するグラフを指定
- SVG図形を用意・生成
- 図形の属性値を変更
- アニメーション処理
- イベント処理
本章では各フローをデータを棒グラフで可視化するサンプルコードで順に追いながら学びます。章末のサンプルコードをChatGPT先生(以下では先生とします)に読ませて、上記6つのフローに対応する部分を説明してもらいました。サンプルコード自体は上記の出版社ホームページに公開されています。
データ読み込み
d3.csv("mydata.csv", function(error, data){
で、D3のcsv関数を使って、"mydata.csv"というファイルからデータを読み込んでいます。読み込みが完了したら、callback関数の中で読み込んだデータを引数として受け取っています。この場合は、受け取ったデータをdata
という名前で扱っています。表示するグラフを指定
d3.select("#myGraph")
で、HTMLの要素を指定しています。この場合は、idが"myGraph"の要素を選択しています。d3.select()
は、指定されたCSSセレクタに一致する最初の要素を選択します。SVG図形を用意・生成
d3.select("#myGraph").selectAll("rect").data(dataSet).enter().append("rect")
で、SVGの四角形要素を生成しています。ここで使われているのは、D3のデータバインディング機能です。まず、selectAll("rect")
で、idが"myGraph"の要素以下にある、すべての四角形を選択しています。その後、data()
で、dataSet
という配列をバインディングします。その後、enter()
で、データに対して四角形が不足している場合に、四角形を生成するように指示しています。最後に、append("rect")
で、新しい四角形を生成するようにしています。図形の属性値を変更
attr()
やstyle()
を用いて、四角形のX座標、Y座標、高さ、幅、塗りのスタイルなどを変更しています。たとえば、attr("x", 10)
で、四角形のX座標を10に指定しています。また、attr("height", "20px")
で、四角形の高さを20pxに指定しています。style("fill", "cyan")
では、クリック時に四角形の塗りのスタイルを水色に変更しています。アニメーション処理
transition()
や、delay()
、duration()
を用いて、グラフの描画時にアニメーションを行っています。たとえば、transition()
で、各四角形の属性値が変化する際にアニメーションを実行しています。また、delay()
で、各四角形のアニメーション開始時間をずらしています。duration()
で、各四角形のアニメーションの時間を指定しています。
- イベント処理
on()
を用いて、クリック時に四角形の塗りのスタイルを変更するイベント処理を実装しています。on()
は、指定されたイベントが発生したときに、指定された関数を実行するように設定します。たとえば、on("click", function(){})
で、クリック時に関数を実行するようにしています。この関数の中で、d3.select(this)
で、クリックされた要素を選択しています。そして、style("fill", "cyan")
で、選択された要素の塗りのスタイルを水色に変更しています。
なお、章末に「D3.jsのメソッドとその利用の流れをドラマ制作に例える」コラムがあったので、先生にも同様の例示を投げてみました。
>具体的なメソッド名を挙げながら、D3.jsのメソッドとその利用の流れをドラマ制作に例えてください。
はい、以下に具体的なメソッド名を挙げながら、D3.jsのメソッドとその利用の流れをドラマ制作に例えて説明します。
プロットの用意 「ドラマの脚本」として、D3.jsにおけるデータを用意します。これは、ストーリーの根幹をなすもので、D3.jsにおけるデータと同じように、ドラマの展開に必要な情報を格納したものと考えることができます。D3.jsでは、例えば、
d3.csv()
やd3.json()
などのメソッドを使って、外部のデータを取得することができます。シーンの指定 「シーン」を指定して、グラフや図形を生成します。これは、D3.jsにおけるグラフや図形と同じように、ドラマを構成する要素の一つで、ある時間的・空間的な場所で行われる出来事を表します。D3.jsでは、SVG要素やHTML要素を生成するためのメソッドとして、例えば
d3.select()
やd3.selectAll()
などを使うことができます。キャストの選定 「キャスト」を選定して、グラフの要素や属性の値を設定します。これは、D3.jsにおけるグラフの要素や属性の値を設定するための関数と同じように、ドラマを構成する登場人物や役割を定めるものです。D3.jsでは、例えば、以下のようなメソッドを使って、グラフの要素や属性の値を設定します。
attr()
やstyle()
などのメソッドを使って、グラフの属性値を設定する。text()
やhtml()
などのメソッドを使って、グラフのテキストを設定する。append()
やinsert()
などのメソッドを使って、グラフに要素を追加する。
- 演出の調整 「演出」を調整して、アニメーションやイベント処理を実装します。これは、D3.jsにおけるアニメーションやイベント処理と同じように、ドラマにおける動きや出来事を調整するためのものです。D3.jsでは、例えば、以下のようなメソッドを使って、演出を調整します。
transition()
やdelay()
、duration()
などのメソッドを使って、アニメーションを実装する。
on()
などのメソッドを使って、イベント処理を実装する。scale()
などのメソッドを使って、スケールや軸を設定する。
- プレゼンテーションの実施 最後に、「プレゼンテーション」を実施して、作成したグラフを表示します。これは、D3.jsにおける描画の実行と同じように、作成したグラフを実際に表現するためのものです。D3.jsでは、例えば、以下のようなメソッドを使って、グラフを表示します。
append()
やinsert()
などのメソッドを使って、要素を追加する。call()
やselect()
などのメソッドを使って、SVG要素やHTML要素を選択する。html()
やtext()
、attr()
などのメソッドを使って、要素の属性値やテキストを設定する。以上のように、D3.jsのメソッドとその利用の流れを、ドラマ制作に例えて説明しました。プロットを用意してシーンを指定し、キャストを選定して演出を調整して、最後にプレゼンテーションを実施するという流れは、D3.jsのデータ可視化でも同じです。