是的,所以我有一个很好的图表。它在中心有工具提示,标签和总价值: 但是,当我将鼠标悬停在其中一个弧上以激活工具提示时,指针从其中出来的小点会保持不变,如下所示: 这是我的鼠标移动代码
path.on('mouseenter', function(d){
d3.select(this)
.transition()
.duration(500)
.attr("d", arcOver);
});
path.on('mouseleave', function(d){
d3.select(this).transition()
.duration(500)
.attr("d", arc);
});
path.on('mouseover', function(d) {
var percent = Math.round(1000 * d.data.value / sum) / 10;
tooltip.style('opacity', 0);
tooltip.select('.label').html(d.data.label);
tooltip.select('.value').html(d3.format("$,.2f")(d.data.value));
tooltip.select('.percent').html(percent + '%');
tooltip.style('display', 'block');
tooltip.transition()
.duration(600)
.style("opacity",1);
});
path.on('mouseout', function() {
tooltip.transition()
.duration(600)
.style("opacity",0)
.style('pointer-events', 'none')
});
以下是创建标签的代码:
svg.selectAll("text").data(pieData)
.enter()
.append("text")
.attr("class", "stickLabels")
.attr("text-anchor", "middle")
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (radius - 37.5);
return d.x = Math.cos(a) * (radius + 40);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (radius - 37.5);
return d.y = Math.sin(a) * (radius + 40);
})
.text(function(d) { return d3.format("s")(d.value); })
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
svg.append("defs").append("marker")
.attr("id", "circ")
.attr("markerWidth", 6)
.attr("markerHeight", 6)
.attr("refX", 3)
.attr("refY", 3)
.append("circle")
.attr("cx", 3)
.attr("cy", 3)
.attr("r", 3);
svg.selectAll("path.pointer").data(pieData).enter()
.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
});
这是整个代码的小提琴:http://jsfiddle.net/18L6u5xf/
我的问题是:如何用圆弧移动点。
PS我知道我需要改变它,我只是不知道如何使用鼠标悬停。这就是最终需要的东西:
d.cx = Math.cos(a) * (radius - 17.5);
PPS我的造型比小提琴好看,只跟我一起。
答案 0 :(得分:2)
A slightly cleaner way of doing this is to wrap the arc, path and text in g and then just transition that on mouseenter
and mouseout
. This way you aren't repeating the same data binding and calculations 3 separate times:
// create a group
var gs = svg.selectAll('.slice')
.data(pieData)
.enter()
.append('g')
.attr('class', 'slice');
// add arcs to it
gs.append('path')
.attr('d', arc)
.attr('id', function(d){return d.data.id;})
.attr('class', 'arcPath')
.attr('fill', function(d, i) {
return color(d.data.label);
});
// add text to it
gs.append("text")
.attr("class", "stickLabels")
.attr("text-anchor", "middle")
.attr("x", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (radius - 37.5);
return d.x = Math.cos(a) * (radius + 40);
})
.attr("y", function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (radius - 37.5);
return d.y = Math.sin(a) * (radius + 40);
})
.text(function(d) { return d3.format("s")(d.value); })
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
});
// add connection paths
gs.append("path")
.attr("class", "pointer")
.style("fill", "none")
.style("stroke", "black")
.attr("marker-end", "url(#circ)")
.attr("d", function(d) {
if(d.cx > d.ox) {
return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
} else {
return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
}
});
// mouseenter of group
gs.on('mouseenter', function(d){
d3.select(this)
.transition()
.duration(500)
.attr("transform",function(d){
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
var x = Math.cos(a) * 20;
var y = Math.sin(a) * 20;
return 'translate(' + x + ',' + y + ')';
});
});
// on mouse leave
gs.on('mouseleave', function(d){
d3.select(this)
.transition()
.duration(500)
.attr("transform",function(d){
return 'translate(0,0)';
});
});
Example here.