質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
D3.js

D3.jsとは、データに基づいてHTMLやSVGドキュメントを編集するために作られた、小規模なオープンソースのJavaScript可視化ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

5715閲覧

D3.jsで各ノードをクリックした際のメニュー表示について

tarner

総合スコア14

D3.js

D3.jsとは、データに基づいてHTMLやSVGドキュメントを編集するために作られた、小規模なオープンソースのJavaScript可視化ライブラリです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/05/30 09:02

D3.js v4で以下のページを参考にツリーレイアウトを作成しています。
https://bl.ocks.org/d3noob/43a860bc0024792f8803bba8ca0d5ecd

各ノードに画像を配置し、画像をクリックするとクリックされた画像の下にポップアップメニューが出てくる、ということをやりたいです。
ツリー構造に画像を表示するまではできたのですが、メニュー表示の処理ができません。
まずは画像を押したらその下に単純にrect要素を表示するよう以下のコードを書きました。

JavaScript

1 nodeEnter.append('image') 2 .attr('class', 'menu') 3 .attr('xlink:href', () => { return 'https://cdn3.iconfinder.com/data/icons/users/100/user_male_1-512.png'; }) 4 .attr('x', 58px) 5 .attr('y', -47px) 6 .attr('width', 32px) 7 .attr('height', 32px) 8 .on('click', () => this.showMenu(d3.select(this))); 9

JavaScript

1showMenu(self) { 2 self.append('rect') 3 .attr('x', 20) 4 .attr('y', -8) 5 .attr('width', 100) 6 .attr('height', 30) 7 .attr('fill', 'blue') 8 .attr('stroke', '#F2F2F2') 9 .attr('stroke-width', 1); 10 }

しかし、self.append('rect')のところで以下のエラーがブラウザのコンソールに表示されてしまいます。

Uncaught TypeError: Cannot read property 'createElementNS' of undefined

何が悪いのでしょうか?当方D3.js初心者になります。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

javascript

1 nodeEnter.append('image') 2 .attr('class', 'menu') 3 .attr('xlink:href', function() { 4 return 'https://cdn3.iconfinder.com/data/icons/users/100/user_male_1-512.png';}) 5 .attr('x', '58px') 6 .attr('y', '-47px') 7 .attr('width', '32px') 8 .attr('height', '32px') 9 .on('click', function (d,idx) { 10 alert(idx); 11 var s = d3.select(this); 12 var DOMp = s.node().parentNode; 13 var p2 = d3.select(DOMp); 14 p2.append('g') 15 .append('rect') 16 .attr('x', '20') 17 .attr('y', '-8') 18 .attr('width', '100') 19 .attr('height', '30') 20 .attr('fill', 'blue') 21 .attr('stroke', 'black') 22 .attr('stroke-width', '1'); 23 d3.event.stopPropagation(); 24 }); 25 26

.attr()に渡す属性値は文字列ですので元コードのpng設定直後にエラーになります。
D3.jsのclickイベントには関数の内容を直接渡すのが簡単です。

参考元ページの全体ソースを見ると、今回追加したい画像要素の親にclickイベントが設定されていてそちらも動きますのでstopPropagationが必要です。
またsvgのrect, circleなどの要素は入れ子にできませんので、まずimageの親を経由して兄弟レベルにgを追加し、その子要素としてrectを追加します。

動作の過程で動的に生成されるHTML(DOM)の様子はfirebugやインスペクタなどのブラウザ調査ツールで確認してください。

参考URL
http://www.h2.dion.ne.jp/~defghi/svgMemo/svgMemo_02.htm

https://stackoverflow.com/questions/22941796/attaching-onclick-event-to-d3-chart-background

https://stackoverflow.com/questions/10607732/how-to-access-the-parentnode-of-a-d3-js-selection

投稿2017/06/01 13:02

t-takayama

総合スコア167

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tarner

2017/06/09 10:16

解決できました。ご丁寧な回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問