gpt4 book ai didi

javascript - 如何在拖放 d3 v4 中获取目标元素?

转载 作者:行者123 更新时间:2023-11-30 14:30:17 25 4
gpt4 key购买 nike

我正在尝试 d3 v4 中的拖放功能。我正在努力获取目标元素。考虑在拖放时拖动小圆圈的示例,我想确定圆圈被拖放到哪条路径上。

提前感谢您的帮助

d3.selection.prototype.moveToFront = function() {  
return this.each(function(){
this.parentNode.appendChild(this);
});
};

// Feel free to change or delete any of the code you see in this editor!
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 960)


const svgp = svg.append("g")
.attr("transform", "translate(400,300)")
// set constants
var PI = Math.PI;
var arcMin = 0; // inner radius of the first arc
var arcWidth = 25; // width
var arcPad = 0; // padding between arcs
var pieces = 4;

var arcPieces = [{start:0,end:90},{start:90,end:180},{start:180,end:270},{start:270,end:360}];

var drawArc = d3.arc()
.innerRadius(function(d, i) {
return d.ir;
})
.outerRadius(function(d, i) {
return d.or;
})
.startAngle(function(d, i) {
//console.log(d);
return d.start * Math.PI/180;
})
.endAngle(function(d, i) {
return (d.end * Math.PI/180);
});

var q = ["q1","q2","q3","q4"];
var p = [1,2,3,4,5,6,7,8,9,10];
var step = 360/q.length;
var objData = []
var drawData = q.forEach((q,i)=>{
p.forEach((p,j)=>{
objData.push({
q:q,
p:p,
start:(i*step),
end:((i+1)*step),
ir : j*25,
or : (j+1) *25
})
})
});



//console.log(objData);


// bind the data
var arcs = svgp.selectAll("path.arc-path").data(objData);

arcs.enter().append("svg:path")
.attr("class", "arc-path") // assigns a class for easier selecting
.attr("id",(d)=>d.q+"-"+d.p)
// sets position--easier than setting x's and y's
.attr("fill", function(d,i){
// fill is an rgb value with the green value determined by the data
// smaller numbers result in a higher green value (1 - d/60)
// you should also look into using d3 scales to create gradients
//var grn = Math.floor((1 - d/60)*255);
//console.log((d.q.replace("q",'')*10));
return "rgb(0, 0,"+ (d.q.replace("q",'')*20) +")";
})
.attr("d", drawArc) // draw the arc
.on('click',function(d){
//console.log(d);
})
.on('mouseover',function(){
//d3.select(this).attr("fill","#ffffff");
})
.on('dragover',function(){
alert("on arc")
})


var circleC = svg.append("circle").attr("cx",25).attr("cy",25).attr("r",10)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

function dragstarted(d,e){
//console.log("s",d,e);
d3.select(this).raise().classed("active", true);
}

function dragged(d,e){
//console.log(d3.event,event,this);
circleC.attr("cx",d3.event.x)
circleC.attr("cy",d3.event.y)
}

function dragended(d,e){
//I want to get on which path is is dropped
//console.log("e",d,e)
}
<script src="https://d3js.org/d3.v4.min.js"></script>

最佳答案

最直接和直接的解决方案可能是使用 elementFromPoint .

例如,获取 id<path> :

d3.select(document.elementFromPoint(d3.event.sourceEvent.clientX, d3.event.sourceEvent.clientY))
.attr("id");

为此,我们必须 lower圆圈在前,所以它不会在路径之上。

这是您更新后的代码:

d3.selection.prototype.moveToFront = function() {
return this.each(function() {
this.parentNode.appendChild(this);
});
};

// Feel free to change or delete any of the code you see in this editor!
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 960)


const svgp = svg.append("g")
.attr("transform", "translate(400,300)")
// set constants
var PI = Math.PI;
var arcMin = 0; // inner radius of the first arc
var arcWidth = 25; // width
var arcPad = 0; // padding between arcs
var pieces = 4;

var arcPieces = [{
start: 0,
end: 90
}, {
start: 90,
end: 180
}, {
start: 180,
end: 270
}, {
start: 270,
end: 360
}];

var drawArc = d3.arc()
.innerRadius(function(d, i) {
return d.ir;
})
.outerRadius(function(d, i) {
return d.or;
})
.startAngle(function(d, i) {
//console.log(d);
return d.start * Math.PI / 180;
})
.endAngle(function(d, i) {
return (d.end * Math.PI / 180);
});

var q = ["q1", "q2", "q3", "q4"];
var p = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var step = 360 / q.length;
var objData = []
var drawData = q.forEach((q, i) => {
p.forEach((p, j) => {
objData.push({
q: q,
p: p,
start: (i * step),
end: ((i + 1) * step),
ir: j * 25,
or: (j + 1) * 25
})
})
});



//console.log(objData);


// bind the data
var arcs = svgp.selectAll("path.arc-path").data(objData);

arcs.enter().append("svg:path")
.attr("class", "arc-path") // assigns a class for easier selecting
.attr("id", (d) => d.q + "-" + d.p)
// sets position--easier than setting x's and y's
.attr("fill", function(d, i) {
// fill is an rgb value with the green value determined by the data
// smaller numbers result in a higher green value (1 - d/60)
// you should also look into using d3 scales to create gradients
//var grn = Math.floor((1 - d/60)*255);
//console.log((d.q.replace("q",'')*10));
return "rgb(0, 0," + (d.q.replace("q", '') * 20) + ")";
})
.attr("d", drawArc) // draw the arc
.on('click', function(d) {
//console.log(d);
})
.on('mouseover', function() {
//d3.select(this).attr("fill","#ffffff");
})
.on('dragover', function() {
alert("on arc")
})


var circleC = svg.append("circle").attr("cx", 25).attr("cy", 25).attr("r", 10)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));

function dragstarted(d, e) {
//console.log("s",d,e);
d3.select(this).raise().classed("active", true);
}

function dragged(d, e) {
//console.log(d3.event,event,this);
circleC.attr("cx", d3.event.x)
circleC.attr("cy", d3.event.y)
}

function dragended(d, e) {
//I want to get on which path is is dropped
d3.select(this).lower();
console.log(d3.select(document.elementFromPoint(d3.event.sourceEvent.clientX, d3.event.sourceEvent.clientY)).attr("id"));
d3.select(this).raise();
}
<script src="https://d3js.org/d3.v4.min.js"></script>

因为没有 id对于 SVG 本身,如果您将圆圈放在路径之外,您将获得 null .

关于javascript - 如何在拖放 d3 v4 中获取目标元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51304266/

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