d3.js
D3.jsの可視化で使用されるコアSVGの概念
サーチ…
座標系
通常の数学的座標系では、点x = 0、y = 0はグラフの左下隅にある。しかし、SVG座標系では、このキャンバスの左上隅に(0,0)点があります。これは、絶対/修正の位置を指定したときのCSSと似ています。要素の正確な点。
SVGのyが増加すると、図形が下に移動することに注意してください。
ax値とy値に対応する各点を持つ散布図を作成するとしましょう。値をスケールするには、ドメインと範囲を次のように設定する必要があります。
d3.svg.scale()
.range([0, height])
.domain([0,max])
ただし、このような設定をそのまま使用すると、ポイントは、予想通りの横の水平線ではなく、一番上の水平エッジに基づいて表示されます。
d3の素晴らしい点は、ドメイン設定の簡単な調整で簡単にこれを変更できることです。
d3.scale.linear()
.range([height, 0])
.domain([0, max])
上記のコードでは、ドメインのゼロ点は、視聴者の目の中のチャートのボトムラインであるSVGの高さに対応する一方、ソースデータの最大値は、SVGのゼロ点に対応するこれは視聴者のための最大値である。
ザ素子
<rect>
は矩形を表し、ストロークや塗りつぶしなどの美的特性を除いて、矩形は位置とサイズによって定義されます。
場所はx属性とy属性で決まります。位置は、矩形の親に対する相対位置です。また、xまたはy属性を指定しない場合、デフォルトは親要素に対して0になります。
位置を指定した後、またはrectの '開始点'を指定した後、次にサイズを指定します。これは実際にキャンバスにsthを描きたい場合、つまり、そうでない場合に必須ですサイズ属性を指定するか、値を0に設定すると、キャンバスには何も表示されません。
ケース:棒グラフ
最初のシナリオY軸を続行しますが、今回は棒グラフを描画してみましょう。
yスケールの設定が同じであれば、y軸も適切に設定されますが、散布図とこの棒グラフの唯一の違いは、幅と高さ、特に高さを指定する必要があることです。具体的には、すでに「出発点」があり、残りは高さのようなものを使用しています:
.attr("height", function(d){
return (height - yScale(d.value))
})
ザ
<svg>
要素はルート要素です。キャンバスはチャートを描画しています。
SVG要素は相互にネストすることができ、このようにSVGシェイプをグループ化することができます。一方、要素内にネストされたすべての図形は、その要素を基準に配置されます。
あるものは言及する必要があるかもしれません、私たちは別のものの中に入れ子にすることはできません、それは動作しません。
ケース:複数のグラフ
たとえば、 この複数のドーナツ・チャートは、それぞれドーナツ・チャートを含む複数の要素で構成されています。これは、要素を使用することで実現できますが、この場合は、ドーナツチャートを1つずつ隣り合わせに配置するだけで便利です。
留意すべき点の1つは、transform属性を使用することができないということですが、x、yをpositionに使用することができます。
ザ素子
SVGは現在自動改行やワードラップをサポートしていません。要素は、前のテキスト行に関連して新しいテキスト行を配置します。そして、これらのスパンのそれぞれの中でdxまたはdyを使うことによって、単語を単語の前に関連付けることができます。
ケース:軸のアノテーション
たとえば、y軸に注釈を追加する場合は次のようになります。
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Temperature (ºF)");
SVG要素を正しく追加する
これは比較的一般的な間違いです。例えば、棒グラフでrect
要素を作成し、テキストラベルを追加したいとします(その棒の値を言います)。したがって、 rect
を追加するのに使ったのと同じ変数を使ってx
とy
位置を定義すると、 text
要素が追加されます。非常に論理、あなたは思うかもしれません。しかし、これは動作しません。
このミスはどうして起こるのですか?
具体的な例を見てみましょう。棒グラフを作成するための非常に基本的なコードです( ここではフィドル )。
var data = [210, 36, 322, 59, 123, 350, 290];
var width = 400, height = 300;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var bars = svg.selectAll(".myBars")
.data(data)
.enter()
.append("rect");
bars.attr("x", 10)
.attr("y", function(d,i){ return 10 + i*40})
.attr("width", function(d){ return d})
.attr("height", 30);
これは我々にこの結果を与える:
しかし、いくつかのテキスト要素を追加したいと思うかもしれません。おそらく各バーに単純な値を追加することです。だから、これを行う:
bars.append("text")
.attr("x", 10)
.attr("y", function(d,i){ return 10 + i*40})
.text(function(d){ return d});
そして、声:何も起こらない!あなたがそれを疑っているなら、 ここはフィドルです。
"でも、私はそのタグを見ている!"
この最後のコードで作成したSVGを調べると、次のようになります。
そして、この時点で多くの人が言う: "しかし、私はテキストタグを見ている、それは追加されました!"はい、そうですが、これでうまくいくわけではありません。あなたは何かを追加することができます!例えば、これを見てください:
svg.append("crazyTag");
それはあなたにこの結果を与えるでしょう:
<svg>
<crazyTag></crazyTag>
</svg>
しかし、あなたはタグがそこにあるからといって、どんな結果も期待していないのですか?
SVG要素を正しい方法で追加する
SVG要素が子供を抱くことができることを学び、 仕様を読んでください。最後の例では、 rect
要素にはtext
要素を含めることができないため、コードは機能しません。では、テキストを表示する方法は?
別の変数を作成し、そのtext
をSVGに追加しtext
:
var texts = svg.selectAll(".myTexts")
.data(data)
.enter()
.append("text");
texts.attr("x", function(d){ return d + 16})
.attr("y", function(d,i){ return 30 + i*40})
.text(function(d){ return d});
これが結果です。
そして、 ここにはフィドルがあります。
SVG:描画命令
D3.jsを使ってビジュアライゼーションを行いますが、上に置いておきたい四角形が別の四角形の後ろに隠れていたり、ある円の後ろにいることを計画していた線が実際には終わってしまいます。 CSSのz-indexを使用してこれを解決しようとしますが、SVG 1.1では機能しません。
説明は簡単です:SVGでは、要素の順序は "絵画"の順序を定義し、絵の順序は誰が上に行くのかを定義します。
SVGドキュメントフラグメント内の要素は暗黙的な描画順序を持ち、SVGドキュメントフラグメントの最初の要素が最初に塗りつぶされます。後続の要素は、以前にペイントされた要素の上にペイントされます。
ですから、このSVGがあるとします:
<svg width="400" height=200>
<circle cy="100" cx="80" r="60" fill="blue"></circle>
<circle cy="100" cx="160" r="60" fill="yellow"></circle>
<circle cy="100" cx="240" r="60" fill="red"></circle>
<circle cy="100" cx="320" r="60" fill="green" z-index="-1"></circle>
</svg>
彼は4つのサークルを持っています。青い円は最初の "塗装された"ものなので、他のすべてのものに悩まされます。それから私たちは黄色いもの、次に赤いもの、そして最後に緑のものを持っています。緑色のものが最後のもので、それが一番上に表示されます。
これは見た目です:
D3でSVG要素の順序を変更する
それで、要素の順序を変更することは可能ですか?緑色の円の前に赤い円を描くことはできますか?
はい。あなたが念頭に置いておく必要がある最初のアプローチは、コード内の行の順序です。まず背景の要素を描画し、後でコードでは前景の要素を描画します。
しかし、要素を塗りつぶした後も要素の順序を動的に変更できます。これを行うために書くことができるいくつかのプレーンなJavaScript関数がありますが、D3には既に2つの素晴らしい機能selection.raise()
とselection.lower()
ます。
APIによると:
selection.raise():選択した各要素を親の最後の子として順番に再挿入します。 selection.lower():選択した各要素を親の最初の子として順番に再挿入します。
ですから、以前のSVGで要素の順序を操作する方法を示すために、ここには非常に小さなコードがあります:
d3.selectAll("circle").on("mouseover", function(){
d3.select(this).raise();
});
それは何をするためのものか?すべてのサークルが選択され、ユーザーが1つのサークル上にカーソルを置くと、そのサークルが選択されて前面に表示されます。非常に簡単です!