更换标签底座D3的位置 [英] Changing position of label base D3

查看:67
本文介绍了更换标签底座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中,然后在mouseentermouseout上进行过渡.这样,您不会在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆