我正在显示svg元素 - 让它们命名为tag - 将鼠标悬停事件发送到图形节点上。显示/隐藏这些内容非常令人满意,尽管可能会有所改进。但是,我希望鼠标悬停时显示的元素是可点击的。
目前,未捕获标记上的鼠标悬停事件。如果我禁用了擦除标签的on mouseout事件,则会正确捕获标签上的事件,但显然标签会永久保留。
有没有办法让标签在父母的鼠标输出事件上可点击并消失?我想在删除标签之前添加1秒延迟,但既不知道怎么做,也不知道它是否正确。
下面的代码显示了一个函数示例 - 在这里小提琴:https://jsfiddle.net/pducrot/4eyb81kx/
// graph size
var width = 400;
var height = 400;
var nodes = [{name: 'A'}, {name: 'B'}, {name: 'C'}, {name: 'D'}];
var edges = [{source: 'A', target: 'B'}, {source: 'B', target: 'C'}, {source: 'C', target: 'A'}, {source: 'C', target: 'D'}];
var tags = [10, 35, 56, 9];
var nodeMap = {};
nodes.forEach(function (x) {nodeMap[x.name] = x;});
var links = edges.map(function (x) {
return {source: nodeMap[x.source], target: nodeMap[x.target], value: 1};
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("pointer-events", "all")
.call(d3.behavior.zoom().on("zoom", redraw))
.append('g');
var force = d3.layout.force()
.gravity(.25)
.distance(140)
.charge(-3500)
.size([width, height]);
var stdDragStart = force.drag().on("dragstart.force");
force.drag()
.on("dragstart", function (d) {
//prevent dragging on the nodes from dragging the canvas
d3.event.sourceEvent.stopPropagation();
stdDragStart.call(this, d);
});
force.nodes(nodes)
.links(links)
.friction(0.8)
.start();
var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("id", function (d) {
return d.name
})
.on("dblclick", dblclick)
.on("mouseover", function (d) {
drawTags(tags, d.name);
})
.on("mouseout", function (d) {
d3.select("#" + d.name).selectAll(".tool").remove();
})
.call(force.drag);
node.append("circle")
.attr("class", "circle")
.attr("r", 40);
d3.selectAll(node);
// display name in nodes if node structure
node.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function (d) {
return d.name;
});
force.on("tick", function () {
link.attr("x1", function (d) {return d.source.x;})
.attr("y1", function (d) {return d.source.y;})
.attr("x2", function (d) {return d.target.x;})
.attr("y2", function (d) {return d.target.y;});
node.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
// redraw after zooming
function redraw() {
svg.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
}
function dblclick(d) {
d3.select(this).classed("fixed", d.fixed = false);
}
function dragstart(d) {
d3.select(this).classed("fixed", d.fixed = true);
}
function drawTags(tags, onto) {
var rScale = d3.scale.ordinal()
.domain(tags)
.rangeBands([-Math.PI, Math.PI]);
var local = d3.select("#" + onto).selectAll(".tool")
.data(tags)
.enter()
.append("svg:g")
.attr("pointer-events", "all")
.attr("class", "tool")
.attr("transform", function (d) {
var x = Math.sin(rScale(d)) * 40;
var y = Math.cos(rScale(d)) * 40;
return "translate(" + x + "," + y + ")";
})
.on("mouseover", function (d) {
alert("mouse over tag " + d);
});
local.append("circle")
.attr("class", "circle")
.attr("r", 15);
local.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.text(function (d) {
return d
});
}
答案 0 :(得分:0)
部分答案是在删除标签之前添加延迟,如上所述。这可以在节点变量上完成:
.on("mouseout", function(d) {
d3.select("#"+d.name).selectAll(".tool")
.transition()
.delay(800)
.remove();
})
减少标记和父节点之间的重叠(在drawTags中)也更好,因为鼠标悬停仅在父节点上,标记被认为是。
var x = Math.sin(rScale(d))*50; // vs. 40px previously
var y = Math.cos(rScale(d))*50;
将标签上的鼠标悬停事件更改为单击事件,并使标签和文本仅接收带有.attr的点击指针事件("指针事件","单击")
.on("click", function(d) { alert(d); });