gpt4 book ai didi

javascript - 如何正确使用 d3.js 拖动?

转载 作者:行者123 更新时间:2023-12-04 08:40:20 31 4
gpt4 key购买 nike

我正在使用 d3.js 和 Vue js 创建平面图。我想添加一个功能,用户单击一个按钮,该按钮创建一个矩形(门口),用户可以更改比例和 X、Y 位置。我对 vue js 和 d3.js 很陌生,所以我使用 this作为引用。该按钮起作用并为 X 次按下添加 X 个矩形。但是,当我添加第一个门口并尝试拖动矩形时,它完全脱离了用户的鼠标坐标。此外,当我添加第二个、第三个、第四个等矩形时,我无法更改这些矩形的位置,只能更改第一个矩形。我认为这是因为我在拖动功能中只选择了一个矩形。但是我更关心在矩形上拖动。有人能指出我正确的方向吗?

<template>
<div id = "app">

<header>
<Navbar />
</header>

<div class = "floor">
<div id = "tooltip"></div>
<svg width = "850" height = "800">
</svg>
</div>

<div class = "buttons">
<button v-on:click="addRec()"> Add Doorway </button>
</div>


</div>
</template>
addRec(){

console.log("Doorway Added")
var doorGroup = d3.selectAll("svg")
.append("g")

//setting attributes for doorway
var doorway = doorGroup.append("rect")
.attr("width",100)
.attr("height", 25)
.attr("x", 150)
.attr("y", 200)

//setting style attributes for doorway
.attr("fill","#F5F5F5")

.attr("stroke", "black")
.attr("stroke-width", 2.5)
.attr("cursor", "move")

//binding drag method onto rectangle
.call(d3.drag()
.on('start', dragStart)
.on('drag', dragging)
.on('end', dragEnd)
)

},
//this is to be called once used has clicked on the doorway
dragStart(d,i,nodes){
d3.select(nodes[i])
.style("stroke", "red")
},
/*
this is to be called once used has started dragging the doorway
dragging(d) upadtes the position of the doorway, from the mouse X,Y Coors
*/
dragging(d,i,nodes){
var width = 850
var height = 800
var xCoor = d3.pointer(event)[0]
var yCoor = d3.pointer(event)[1]

// d3.select(nodes[i])
// .attr("transform", "translate(" + (xCoor - 200) + "," + (yCoor - 300) + ")")

d3.select(nodes[i])
.attr("x", xCoor)
.attr("y", yCoor)
},
//this is to be called once user has clicked off the doorway
dragEnd(d,i,nodes){
d3.select(nodes[i])
.style("stroke", "black")
},

最佳答案

您的代码中有两个问题:

  • 您只能选择相同的矩形:

  • 您所有的拖动功能都使用:
    d3.select("rect")
    这将选择 DOM 中的第一个匹配元素。这将始终是同一个矩形,它不对应于被拖动的矩形。相反,您可以使用以下方法访问正确的矩形:
    function dragFunction() {
    d3.select(this);
    }
    在 d3v5 及更早版本中,如果 this不可用,您可以使用:
    dragFunction(d,i,nodes) => d3.select(nodes[i])
    如果您无法访问 this,则没有获得矩形的好方法然而在 d3v6 - migration guide显示了获取 this 的“旧”方式这涉及过滤元素以进行基准匹配。我从未见过在 d3v5 或更早版本中使用过这种方法, d3.select(nodes[i])如果 this 总是后退不可用。因此,理想情况下,您可以访问 this - 不要为监听器使用箭头函数
  • 您通过 x,y 应用变换和位置。

  • 最初附加您按 x,y 定位的矩形时。拖动时应用平移,但不要删除初始 x,y 定位。这导致 x,y 坐标被应用两次,一次是使用它们的原始值,一次是使用它们相对于原点(而不是它们的起始位置)的拖动值。您应该为初始放置和拖动修改相同的属性 - x,y 属性或变换,但不要将两者都用于放置。

    D3v5
    除了使用 d3.event.x 和 d3.event.y(d3.pointer 是在 d3v6 中添加的)之外,我还进行了上述更改,并相信我已经创建了下面的预期效果。

    var svg = d3.select("body")
    .append("svg")
    .attr("width", 500)
    .attr("height", 300);

    d3.select("button")
    .on("click", function() {

    svg.append("rect")
    .attr("width",10)
    .attr("height", 25)
    .attr("x", 150)
    .attr("y", 100)
    .attr("fill","#1b1c3b")
    .attr("opacity", ".5")
    .attr("stroke", "black")
    .attr("stroke-width", "2")
    .attr("cursor", "move")
    .call(d3.drag()
    .on('start', dragStart)
    .on('drag', dragging)
    .on('end', dragEnd)
    )

    function dragStart(d,i,nodes){
    d3.select(nodes[i])
    .style("stroke", "red")
    }

    function dragging(d,i,nodes){
    var xCoor = d3.event.x;
    var yCoor = d3.event.y;

    d3.select(nodes[i])
    .attr("x", xCoor)
    .attr("y", yCoor);
    }

    function dragEnd(d,i,nodes){
    d3.select(nodes[i])
    .style("stroke", "black")
    }



    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    <button>Add Rect</button>

    D3v6

    var svg = d3.select("body")
    .append("svg")
    .attr("width", 500)
    .attr("height", 300);

    d3.select("button")
    .on("click", function() {

    svg.append("rect")
    .attr("width",10)
    .attr("height", 25)
    .attr("x", 150)
    .attr("y", 100)
    .attr("fill","#1b1c3b")
    .attr("opacity", ".5")
    .attr("stroke", "black")
    .attr("stroke-width", "2")
    .attr("cursor", "move")
    .call(d3.drag()
    .on('start', dragStart)
    .on('drag', dragging)
    .on('end', dragEnd)
    )

    function dragStart(event,d){
    d3.select(this)
    .style("stroke", "")
    }

    function dragging(event,d){
    var xCoor = event.x;
    var yCoor = event.y;

    d3.select(this)
    .attr("x", xCoor)
    .attr("y", yCoor);
    }

    function dragEnd(event,d){
    d3.select(this)
    .style("stroke", "black")
    }

    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.1.0/d3.min.js"></script>
    <button>Add Rect</button>

    关于javascript - 如何正确使用 d3.js 拖动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64596035/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com