d3.dragモジュールがオブジェクトのドラッグ、オブジェクト移動、ドロップを管理しています
- d3.dragモジュールはドラッグ、オブジェクト移動、ドロップについて、三つのイベントがあります
- start: ドラッグ開始
- drag: ドラッグしながら、オブジェクトの移動
- end: ドラッグ終了(ドロップ)
- この三つのイベントはブラウザのマウスイベントとタブレットのタッチイベントを対応しています。
- 以下のイベントの対応一覧(本家の紹介から)
Event Listening Element Drag Event Default Prevented? mousedown⁵ selection start no¹ mousemove² window¹ drag yes mouseup² window¹ end yes dragstart² window - yes selectstart² window - yes click³ window - yes touchstart selection start no⁴ touchmove selection drag yes touchend selection end no⁴ touchcancel selection end no⁴
- 以下のイベントの対応一覧(本家の紹介から)
d3.jsのイベント(start, drag, end)のキャッチと処理ロジックを作成すればドラッグ管理ができます
- この三つのイベント(start, drag, end)をキャッチして処理すれば簡単にd3.jsのドラッグ管理ができます
- 各オブジェクト(例:描画した円)に三つのイベント(start, drag, end)リスナーを実装します
var circles = force_g.selectAll("circle") .data(data_set) .enter() .append("circle") .attr("class","test-circle") .attr("r", function(d){ return d.val/2; }) .attr("fill","lightblue") .call(d3.drag() // ドラッグイベントリスナーの実装 .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); ; // 三つのイベント(start, drag, end)リスナー実装 function dragstarted(d) { if (!d3.event.active) line_force.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { if (!d3.event.active) line_force.alphaTarget(0); d.fx = null; d.fy = null; }
- 上記コードだけで、ドラッグ/ドロップ/オブジェクト移動ができます
data_set = [ {name:"aaa", val:58, col:100}, {name:"bbb", val:88, col:200}, {name:"ccc", val:48, col:300}, {name:"ddd", val:73, col:400}, {name:"eee", val:81, col:500}, {name:"fff", val:31, col:600} ] ; var width=600, height=300; var force_g = d3.select("#content") .append("g") ; var circles = force_g.selectAll("circle") .data(data_set) .enter() .append("circle") .attr("class","test-circle") .attr("r", function(d){ return d.val/2; }) .attr("fill","lightblue") .call(d3.drag() .on("start", dragstarted) .on("drag", dragged) .on("end", dragended)); ; var line_force = d3.forceSimulation() .nodes(data_set) .on("tick", ticked) .force("center", d3.forceCenter(width/2, height/2)) .force('charge', d3.forceManyBody().strength(5)) .force("collision", d3.forceCollide(function(d){return d.val/2;})) .force("y", d3.forceY().y(150)) ; function dragstarted(d) { if (!d3.event.active) line_force.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(d) { d.fx = d3.event.x; d.fy = d3.event.y; } function dragended(d) { if (!d3.event.active) line_force.alphaTarget(0); d.fx = null; d.fy = null; } function ticked(){ circles .attr("cx", function(d){ return d.x; }) .attr("cy", function(d){ return d.y; }) ; }