改变标签底座D3的位置

时间:2015-07-28 18:58:00

标签: javascript d3.js

是的,所以我有一个很好的图表。它在中心有工具提示,标签和总价值: My Graph 但是,当我将鼠标悬停在其中一个弧上以激活工具提示时,指针从其中出来的小点会保持不变,如下所示:enter image description here 这是我的鼠标移动代码

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我的造型比小提琴好看,只跟我一起。

1 个答案:

答案 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.