D3.js 拖拽功能实现 (drag)

647 阅读2分钟

D3.js drag 拖拽功能:

在使用图表呈现一些数据的交互效果时,难免会有一些需要使用拖拽效果的需求。所以是有必要了解一下drag拖拽的方法。

1.D3.drap()

方法用来创建拖拽事件, d3.drag() 会返回一个drag方法,然后在使用selection.call()这个方法将返回的拖拽事件绑定到对应的元素上。

2.selection.call( )

前面我们知道,使用select.all()可以获取到选择的元素的一个集合,selection.call(function[, arguments...]) 调用给定的函数一次,传入选集和可选的参数。返回这个选集。无论指定函数的返回值是什么,call操作符总是返回当前的选择,所以我们可以对选择的元素进行相关操作

const svg = d3.select(".qq").append("svg").attr("width", 700).attr("height", 400).style("border", "1px solid pink")

    // 模拟数据  这里采用比较简单的原点
    const dataList = [
        { 'r': 10, 'x': 80, y: 180, 'color': 'orange' },
        { 'r': 20, 'x': 150, y: 250, 'color': 'blue' },
        { 'r': 30, 'x': 85, y: 250, 'color': 'purple' },
        { 'r': 15, 'x': 323, y: 100, 'color': 'pink' },
        { 'r': 25, 'x': 500, y: 250, 'color': 'green' },
    ]

    // 绘制图形
    const circle = d3.select("svg")
        .selectAll("circle")
        .data(dataList)
        .join("circle")
        .attr("r", (d) => d.r)
        .attr("cx", (d) => d.x)
        .attr("cy", (d) => d.y)
        .attr("fill", (d) => d.color)
        .call(function (d) {
          	console.log(d)   // d代表circle元素的集合数组  可以对它进行操作
            console.log(this);   //这里的this指向是window
        })
        .call(name,'echo','john');  // 会给每一个函数添加对应的 名称
        function name(selection, first, last) {
        selection.attr("first-name", first).attr("last-name", last);
    }
        

3.拖拽事件的步骤:开始拖拽 drag.on('start') ; 拖拽中 drag.on('dragged') ; 拖拽结束 drag.on('end')

下面直接看一个例子:

![22](C:\Users\user\Desktop\22.gif)// 创建svg和原点数据
const svg = d3.select(".qq").append("svg").attr("width", 700).attr("height", 400).style("border", "1px solid pink")

    // 模拟数据  这里采用比较简单的原点
    const dataList = [
        { 'r': 10, 'x': 80, y: 180, 'color': 'orange' },
        { 'r': 20, 'x': 150, y: 250, 'color': 'blue' },
        { 'r': 30, 'x': 85, y: 250, 'color': 'purple' },
        { 'r': 15, 'x': 323, y: 100, 'color': 'pink' },
        { 'r': 25, 'x': 500, y: 250, 'color': 'green' },
    ]

    // 绘制图形
    const circle = d3.select("svg")
        .selectAll("circle")
        .data(dataList)
        .join("circle")
        .attr("r", (d) => d.r)
        .attr("cx", (d) => d.x)
        .attr("cy", (d) => d.y)
        .attr("fill", (d) => d.color)
    
    // 拖拽事件
	  /* 
    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', 'black')
        })
        .on('drag', function () {
            let pt = d3.pointer(event, this) // 这里pointer事件是获取到当前点击元素,并可以得到对应的坐标
            d3.select(this)
                .attr('cx', pt[0])
                .attr('cy', pt[1])
        })
        .on('end', function () {
            d3.select(this)
                .style('stroke', 'purple')
        });

    circle.call(drag)
    

效果如下:

22.gif