iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
Modern Web

三十天成為D3.js v7 好手系列 第 13

Day13-D3 的 Drag 拖曳

本篇大綱:selection.call( )、drag.on( )、範例

今天要來看另一個d3有趣的互動事件:Drag 拖曳!

我們先來看看官方文件關於 d3.drags 有多少 API 可以使用,接著再來講解要怎麼使用這些 API

https://ithelp.ithome.com.tw/upload/images/20210925/201349304JwZXX87ic.jpg

d3.drag( )

直接先看到 d3.drag() 這個API,它是用來建立drag事件的方法。當我們使用d3.drag()時,它會返還一個drag方法,接著我們要用selection.call( )這個API把返還的drag方法綁定到 selection 上
https://ithelp.ithome.com.tw/upload/images/20210925/20134930UydvOLkTsI.jpg

selection.call( )

這個 API 是在選定的DOM元素上呼叫並執行特定方法,但這個方法只會被執行一次。由於 d3.drag() 會返還一個方法,因此我們要用selection.call( )來執行這個方法
https://ithelp.ithome.com.tw/upload/images/20210925/20134930H1xYY8YLPF.jpg

drag.on(事件, 方法)

使用 d3.drag( ) 建立拖曳事件後,還能使用 drag.on('事件', 方法) 把拖曳事件細分成三個階段,分別是

  • .on('start') ⇒ 拖曳開始
  • .on('dragged') ⇒ 拖曳期間
  • .on('end) ⇒ 拖曳結束

https://ithelp.ithome.com.tw/upload/images/20210925/20134930kgXQ4XvDnU.jpg


Drag 範例

看完這幾個方法並了解怎麼使用後,我們現在來實際看範例跟程式碼吧!首先,一樣先把拿到的資料綁定到DOM元素上:

// html 
<div class="chartContainer"></div>

//js
// 資料
const data = [{name:'A', x:200, y:340},
              {name:'B', x:220, y:300},
              {name:'C', x:250, y:198},
              {name:'D', x:360,y:296},
              {name:'E', x:160, y:150},
              {name:'F', x:370, y:360},
              {name:'G', x:187, y:250}]

const svg = d3.select('.chartContainer')
                  .append('svg')
                  .attr('width', 500)
                  .attr('height', 500);
    
// 建立圓點
const dots = svg.append('g')
                .selectAll('circle')
                .data(data)
                .enter()
                .append('circle')
                .attr('r', 25)
                .attr('cx', d=>d.x)
                .attr('cy', d=>d.y)
                .style("fill", "#19d3a2")
                .style("fill-opacity", 0.3)
                .attr("stroke", "#b3a2c8")
                .style("stroke-width", 4)
                .style('cursor', 'pointer')

完成後我們的畫面上就會有幾個圓點點
https://ithelp.ithome.com.tw/upload/images/20210925/20134930BsMfsgaa3O.jpg

接著,我們來建立拖曳事件:

  1. 我們先使用d3.drag( ) 建立拖曳事件
  2. 接著使用drag.on( ) 設定拖曳不同階段DOM元素的變化
    • start ⇒ 拖曳事件一開始時,讓選定的圓點邊框變成藍色
    • drag ⇒ 拖曳期間,使用 d3.pointer 去計算目前滑鼠的XY座標,並把這個座標的位置設定給此圓點
    • end ⇒ 拖曳結束後,選定的圓點邊框變回原本的顏色
// 建立拖曳方法
const drag = d3.drag()
               .on('start', function(){
                  d3.select(this)
                    .style('stroke', 'blue')
                 })
               .on('drag', function(){
                  let pt = d3.pointer(event, this)
                  d3.select(this)
                    .attr('cx', pt[0])
                    .attr('cy', pt[1])
                 })
                .on('end', function(){
                  d3.select(this)
                    .style('stroke', '#b3a2c8')
                 });

最後,只要選定想操作的DOM元素,並使用 d3.call( )呼叫drag事件就可以啦!

dots.call(drag);

這樣拖曳的互動就完成啦!現在我們可以隨心所欲把圓點拖曳到任何地方囉~
https://i.imgur.com/ZMQ9YSd.gif

以上就是 d3.js 的拖曳事件~明天要來講講大魔王 Force 啦!


Github Page 圖表與 Github 程式碼

這邊附上本章的程式碼與圖表 GithubGithub Page,需要的人請自行取用~


上一篇
Day12-D3 的 Tooltips
下一篇
Day14-D3 的 Force 原力
系列文
三十天成為D3.js v7 好手30

尚未有邦友留言

立即登入留言