地理的な地域を示すSVG画像を持っています。 http://upload.wikimedia.org/wikipedia/commons/7/71/Nederland_gemeenten_2009.svg
私は、ウェブページにSVG画像を表示し、JavaScriptとCSSの組み合わせを使って画像と対話したいのです。(例えば、地域のクリックを検出したり、地域の背景色を変えたり).
私はこの質問がStackOverflowで何度も質問されていることを知っていますが、私はさらに作業するための完全なコードサンプルを見つけることができません。jQueryのようなJavaScriptパッケージ、またはプラグインに関する推奨事項があれば歓迎します。
私の理解では、解決すべき側面が異なるということです。
1.1. インタラクションのための画像をどのように準備するか 2.画像をページに埋め込む方法 3.SVGでCSSを使用する方法 4.JavaScriptを使ったインタラクションの方法
画像の準備
まず最初に、画像をきれいにすることをおすすめします。Inkscapeはあなたが必要としないあらゆるものをそこに残しています。その中にはsodipodi:
とinkscape:
名前空間の要素や属性、および繰り返しや冗長なスタイル属性が含まれます。これらを削除する必要はありませんが、帯域幅や読み込み時間を節約できますし、CSS マッチングを行う場合、スタイル属性は邪魔になります。
あなたの例のファイルでは、同じスタイル属性が472回あります。それらをすべて削除して、同等のCSSルールを一度作成してください。
また、マークアップに自治体に関する情報を追加するのもよいでしょう。例えば、自治体を表す各パスのIDを、自治体名に応じて変更することができます。この目的のために、data-*
属性を使用することもできます。後者には、スペースを使用できるという利点があります。これがどのようにインタラクション、特にCSSで有用であるかについては、以下を参照してください。
画像の埋め込み
特にCSSやJavaScriptと連動させたい場合は、SVGをインラインで使用することをお勧めします。つまり、HTMLにSVGのマークアップを追加するか、Ajaxで読み込んで挿入するのです。後者の場合、ページの読み込みが速くなり、レスポンスも良くなるという利点があります。
インライン SVG 要素の例。
<div id="svgContainer">
<!-- This is an HTML div, and inside goes the SVG -->
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
<circle r="50" cx="50" cy="50" fill="green"/>
</svg>
</div>
Ajax を用いた SVG の読み込み方法の簡略化した例。
xhr = new XMLHttpRequest();
xhr.open("GET","my.svg",false);
// Following line is just to be on the safe side;
// not needed if your server delivers SVG with correct MIME type
xhr.overrideMimeType("image/svg+xml");
xhr.send("");
document.getElementById("svgContainer")
.appendChild(xhr.responseXML.documentElement);
**CSSの使い方
SVG は HTML と同じようにスタイルを設定することができます。もちろん、SVGは fill-opacity
や stroke-dasharray
などの独自のプロパティを持ち、 margin
や position
などのような多くのHTMLのプロパティはサポートされていません。しかし、セレクタの仕組みは100%同じです。
インラインSVG用のCSSとHTML用のCSSを、<style>
要素内または外部CSSファイルで混在させることが可能です。また、SVGのコードと style
属性の内部で <style>
要素を使用することができます。
SVG要素に意味のあるIDやdata-*
属性を与えたと仮定すると、CSSを使って自治体をハイライトする方法は以下の2つが考えられます。
#Bronckhorst, #Laarbeek {fill:red}
または
*[data-gemeente=Bronckhorst], *[data-gemeente=Laarbeek] {fill:red}
あるいは、もちろん、それぞれの要素のスタイル属性を変更することもできます。プロパティは属性としてもサポートされており、例えば style="stroke-width:2"
は stroke-width="2"
のように指定することも可能です。同じプロパティを属性とCSS(style属性、style要素、外部スタイルシートのいずれか)で設定した場合、CSSが属性を上書きします。
JavaScriptとの連携。
少なくとも plain vanilla DOM を使用する限り、JavaScript とのインタラクションに関しては、基本的に HTML と SVG の間に違いはありません。つまり、 innerHTML
のようなHTML特有の機能はSVGではサポートされていません(つまり innerSVG
は存在しません)。しかし、SVG には独自のグラフィックスに特化した DOM メソッドのセットがあります (W3C specs を参照してください)。
注意しなければならないのは、名前空間を使った作業です。すべての SVG 要素は SVG 名前空間内にあるべきで、JavaScript を使ってそれらを作成する場合、createElement()
の代わりに createElementNS()
を使用しなければなりません。
var use = document.createElementNS("http://www.w3.org/2000/svg","use")
同様に、XLink 名前空間の属性 (すなわち xlink:href
) は、 setAttribute()
の代わりに setAttributeNS()
を用いて操作しなければなりません。
use.setAttributeNS("http://www.w3.org/1999/xlink","href","#foo")
jQueryのようなライブラリは、HTML固有の機能に依存している部分があるので、SVGを操作する際には避けた方が無難です。Raphaël](http://raphaeljs.com/) や D3.js のようなSVG専用のライブラリもあり、特定の目的には有用なので、一見の価値はあります。特にRaphaëlは、SVGをサポートしていないHTML5以前のInternet Explorerバージョン6〜8と互換性があるため、重宝されています。しかし、私の理解では、SVGの上の抽象化レイヤーであるため、既存のグラフィックスを扱うよりも、JavaScriptを使って完全にグラフィックスを生成することにのみ適しています。D3.jsは、もしあなたがプレーンなDOMに満足していないなら、あなたのようなアプリケーションにもっと適しているでしょう(正直なところ、私はそれを単にSVG特有のライブラリと呼ぶのは不公平だと思います。)
onclickや同様の属性、そして標準的な DOM の
addEventListener()を使用することができます。JavaScript のイベントを使用する非常に簡単な例としては、ユーザがクリックした自治体の名前を報告するイベントリスナーを
document.getElementsByTagName("svg")[0]
.addEventListener("click",function(evt){
alert(evt.target.getAttribute("data-gemeente"))
},
false)
余談: Toopltips です。
HTMLの title
属性と同じ効果をSVGの <title>
要素で得ることができます。SVG要素の中に <title>
要素を置くだけで、カーソルを合わせると <title>
要素の内容がツールチップとして表示されます。
<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
<rect width="100" height="100">
<title>test</title>
</rect>
</svg>