更换标签底座D3的位置 [英] Changing position of label base D3
问题描述
对,所以我有这张效果很好的图表.它的中心有工具提示,标签和总计值: 但是,当我将鼠标悬停在其中一个弧上以激活工具提示时,指针从其中伸出的小点将保留,如下所示: 这是我的鼠标移动代码
Right, so I have this graph that works great. It has tooltips, labels, and a total value in the center: However, when I hover over one of the arcs to activate the tooltips, the little dot that has the pointer coming out of it stays put, as seen here: This is my mouse movement code
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')
});
以下是创建标签的代码:
Here's the code that creates the labels:
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/
And here's a fiddle of the whole code: http://jsfiddle.net/18L6u5xf/
我的问题是:如何用圆弧移动圆点.
My question is this: How do I move the dot with the arc.
PS我知道我需要将其更改为什么,我只是不知道如何将鼠标悬停在上面.这是最终需要的东西:
PS I know what I need to change it to, I just don't know how to do it with a mouseover. This is what it needs to end up being:
d.cx = Math.cos(a) * (radius - 17.5);
PPS与我的风格相比,与小提琴相比,它看起来更好,只要忍受我.
PPS It looks better with my styling than in the fiddle, just bear with me.
推荐答案
一种更简洁的方法是将弧线,路径和文本包装在g中,然后在mouseenter
和mouseout
上进行过渡.这样,您不会在3个不同的时间重复相同的数据绑定和计算:
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)';
});
});
示例此处.
这篇关于更换标签底座D3的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!