javascript - D3在拖动圆圈时获取下方多边形的ID
问题描述
我正在创建一个 d3 对象,它由三角形多边形组成。
我有一个可拖动的圆形指针我如何捕获鼠标下方多边形的 id(在鼠标事件下,而圆形仍然表现得像一个视觉指针)。希望这是有道理的。
html
<div style="width:1000px;" id="triangle">
<svg height="1000" width="1000" id="ternary">
<defs>
<!--The Pointe-->
<g id="pointer" transform="scale(0.8)">
<circle cx="0" cy="0" r="20" stroke="black" stroke-width="1"/>
</g>
</defs>
</svg>
</div>
Javascript
window.addEventListener('load', function() {
var ternary = d3.select("#ternary");
var pointer = d3.select("#pointer");
var w = 50,
h = 50,
rows = 20;
b = 1000;
t = 950;
wm = 25;
var osb = 0;
for (s = 1; s <= 20; s++) {
if (!s % 2 == 0) {
rb = b - osb;
rt = t - osb;
} else {
rb = b - osb;
rt = t - osb;
}
for (i = 1; i <= rows - s; i++) {
console.log();
osl = (i - 1) * w + ((s - 1) * 25);
if (s) {
if (s % 2 == 0) {
trColor = '#3c763d';
osl = (i - 1) * w + ((s - 1) * 25);
var x1 = osl;
var x2 = osl + (w / 2);;
var x3 = osl + w;
// console.log(rt);
ternary.append('polygon')
.attr('points', osl + ' ' + (rt) + ', ' + x3 + ' ' + (rt) + ' , ' + x2 + ' ' + (rb))
.attr('class', 'r' + s + 'c' + i)
.style('fill', '#3c754d');
} else {
trColor = '#3c739d'
osl = (i - 1) * w + ((s - 1) * 25);
var x1 = osl;
var x2 = osl + (w / 2);;
var x3 = osl + w;
ternary.append('polygon')
.attr('points', osl + ' ' + rb + ', ' + x2 + ' ' + rt + ' , ' + x3 + ' ' + rb)
.attr('class', 'r' + s + 'c' + i)
.style('fill', '#3c763d');
};
}
}
if (s % 2 == 0 && s > 2) {
osb = osb + 50;
}
}
ternary.append("use")
.attr("href", "#pointer")
.attr("x", 500)
.attr("y", 875)
.attr("fill", "#039BE5")
.attr("stroke", "#039BE5")
.attr("stroke-width", "1px");
var dragHandler = d3.drag()
.on("drag", function() {
d3.select(this)
.attr("x", d3.event.x)
.attr("y", d3.event.y);
/*
How do I Get the id of underlying triangle?
*/
});
dragHandler(svg.selectAll("use"));
});
他们是实现这一目标的直接方法吗?
解决方案
有几个选项可以找到拖动元素下的内容。
一种是利用拖动的start
和end
事件,根据需要改变被拖动对象的指针事件属性。在拖动开始时,我们可以将其设置为none
,在拖动结束时,我们可以将指针事件恢复为all
。尽管将指针事件设置为无,但拖动仍在继续,但现在指针事件现在可以针对被拖动元素下方的内容触发。
如果我们只希望它们响应拖动事件,我们还可以使用开始/结束事件将事件侦听器添加到底层元素。
下面的代码片段使用了这个想法,拖动圆圈与底层矩形进行交互。当拖动开始时,指针事件从圆圈中移除,鼠标事件监听器被添加到矩形中。在拖动结束时,一切都恢复到原来的样子:
var svg = d3.select("body")
.append("svg")
.attr("width",500)
.attr("height",300);
function color(d) {
return d3.scaleLinear()
.range(["teal","steelblue","crimson","orange"])
.domain([0,30,40,60])(d);
}
var grid = svg.selectAll(null)
.data(d3.range(60))
.enter()
.append("rect")
.attr("width", 50)
.attr("height", 50)
.attr("y", function(d) { return Math.floor(d/10)*50; })
.attr("x", function(d) { return d%10*50; })
.attr("fill", color)
.attr("id", function(d){
return "rect-"+d;
})
var circle = svg.append("circle")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 10);
var drag = d3.drag()
.on("start",start)
.on("drag",dragged)
.on("end",end);
circle.call(drag);
function start() {
grid.on("mouseover", function() {
d3.select(this).attr("fill","yellow");
console.log(this.id);
})
.on("mouseout", function() {
d3.select(this).attr("fill",color);
})
d3.select(this)
.style("pointer-events","none");
}
function dragged() {
d3.select(this)
.attr("cx", d3.mouse(this)[0])
.attr("cy", d3.mouse(this)[1]);
}
function end() {
grid.on("mouseover",null)
.on("mouseout", null)
.transition()
.attr("fill",color);
d3.select(this)
.style("pointer-events","all");
}
.as-console-wrapper { max-height: 30px !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
推荐阅读
- java - 从 CardArray 中删除重复项
- python - Django 找不到 settings.py 文件
- javascript - ChartJS 多注解(竖线)
- laravel - 从 Vue 组件取回数据
- gitlab - 完成后gitlab中的作业状态
- java - Spring JPA 规范-arg-resolver
- scala - IntelliJ 工作表期间的循环定义错误
- arrays - 合并 2 个具有相似键的 JSON 对象:ReactJS
- java - 如何使用 Java 转储 MySQL 数据库?
- javascript - 如何让我的表单在用户键入时指示模式不匹配错误(自定义验证错误)?