D3 js 如何获取特定于数据的工具提示以在悬停时显示?

D3 js How do I get data specific tooltips to display on-hover?

我的目标是制作一个交互式图表,在图表旁边的弧线上显示附加信息。下面的代码不干净,但可以正常工作并且(几乎)完成了我想要的一切。

具体来说,它会绘制一个圆弧饼图,当您将鼠标悬停在圆弧上时,圆弧会变亮,并从圆弧的中心到右侧的数据区域绘制一条线,其中有支出和描述已列出。

然而,代码似乎不够优雅,它显示的数据点(文本)都是同一个。它似乎没有添加额外的数据元素来显示它们,或者它只是选择第一个显示!

我懒得复制的HTML只是一个空白网页,只有一个div:<div id="pie">1,2,3</div>

 var format = d3.format(",.2f");

    var data = [
        {'spend': 15, 'description': 'Controlled'},
        {'spend': 3, 'description': 'Data Usage'},
        {'spend': 21, 'description': 'International Roaming'}
    ];
    var kulor = d3.scale.ordinal()
        .range(['#648631','#D84B4B','#A05AE0']);

    var width = 160,
        height = 80,
        radius = height / 2 - 10, // how wide is the circle within the box?
        innerRadius = radius - 10, // how thich is the donut (the -# is the thickness)
        cornerRadius = 3, // how wide are the curves of each section
        padAngle = .07, // distance between items (in angles)
        startLine = [40, -25]; // where the description line starts

    var arc = d3.svg.arc()
        .innerRadius(innerRadius)
        .outerRadius(radius)
        .cornerRadius(cornerRadius);

    var pie = d3.layout.pie()
        .padAngle(padAngle)
        .value(function (d) {
            return d.spend;
        });

    var arcs = d3.select('#pie').html('').append('svg')
        .data([data])
        .attr('width', width)
        .attr('height', height)
      .append('g')
        // keep centered but left
        .attr('transform', 'translate(' + height / 2 + ',' + height / 2 + ')');

       arcs.selectAll('path')
            .data(pie).enter()
                .append('path')
                    .style('fill', function(d, i) { return kulor(i); })
                    .attr('d', arc);

            arcs.selectAll('line')
                .data(pie).enter()
                    .append('line')
                        .classed('slice', true)
                        .attr('lineNum', function(d,i){ return 'sl'+i; })
                        .attr('x1', function(d, i) {
                            return arc.centroid(d, i)[0];
                        })
                        .attr('y1', function(d, i) {
                            return arc.centroid(d, i)[1];
                        })
                        .attr('x2', startLine[0]).attr('y2', startLine[1])
                        .attr('stroke-width', 2).attr('stroke','#333')
                        .style('visibility', 'hidden');

            // fixed line
            arcs.append('line')
                .classed('fixedLine', true)
                .attr('x1', startLine[0]).attr('y1', startLine[1])
                .attr('x2', 120).attr('y2', startLine[1])
                .attr('stroke-width', 2).attr('stroke','#333')
                .style('visibility', 'hidden');

            // Spend
            arcs.each(function(d, i) {
                console.log(d[i].spend + " " + i);
                arcs.append('text')
                        .classed('spend', true)
                        .text(function(d,i){ 
                            console.log(d);
                            return '$' + format(d[i].spend); 
                        })
                        .attr('x', 80).attr('y', startLine[1] - 4)
                        .attr('font-size',12)
                        .attr('font-family','Helvetica, sans-serif')
                        .attr('text-anchor','middle')
                        .attr('font-weigt','bold')
                        .style('visibility', 'hidden');
            })


            // Spend Description
            arcs.append('text')
                .text(function(d,i){ return d[i].description; })
                .attr('x', 80).attr('y', startLine[1] + 12)
                .attr('font-size',12)
                .attr('font-family','Helvetica, sans-serif')
                .attr('text-anchor','middle')
                .attr('font-weigt','bold')
                .style('visibility', 'hidden');;

            arcs.selectAll('path')
                .on('mouseover', function(d, i) {
                    var index = i + 1;
                    var nodeSel = d3.select(this).style({opacity:'0.8'});
                    nodeSel.select('text').style({opacity:'1.0'});
                    d3.select('.slice:nth-of-type('+index+')').style('visibility', 'visible');
                    d3.select('.spend:nth-of-type('+index+')').style('visibility', 'visible');
                    d3.select('.fixedLine').style('visibility', 'visible');
                    d3.selectAll('text').style('visibility', 'visible');
                })
               .on('mouseout', function(d, i) {
                    var nodeSel = d3.select(this).style({opacity:'1.0'});
                    nodeSel.select('text').style({opacity:'0'});
                    arcs.selectAll('.slice').style('visibility', 'hidden');
                    arcs.selectAll('.fixedLine').style('visibility', 'hidden');
                    arcs.selectAll('text').style('visibility', 'hidden');
                });

问题 1:

您不必添加与弧数一样多的文本。 所以这是错误的。

arcs.each(function(d, i) {
                console.log(d[i].spend + " " + i);
                arcs.append('text')
                        .classed('spend', true)
                        .text(function(d,i){ 
                            console.log(d);
                            return '$' + format(d[i].spend); 
                        })
                        .attr('x', 80).attr('y', startLine[1] - 4)
                        .attr('font-size',12)
                        .attr('font-family','Helvetica, sans-serif')
                        .attr('text-anchor','middle')
                        .attr('font-weigt','bold')
                        .style('visibility', 'hidden');
            })

正确的方法是像这样添加一个文本 DOM(然后 DOM 在鼠标悬停时给出描述)

        arcs.append('text')
                .classed('spend', true)
                .attr('x', 80).attr('y', startLine[1] - 4)
                .attr('font-size',12)
                .attr('font-family','Helvetica, sans-serif')
                .attr('text-anchor','middle')
                .attr('font-weigt','bold')
                .style('visibility', 'hidden');

问题 2:

您不需要像这样设置 text text DOM:

 .classed('spend', true)
                            .text(function(d,i){ 
                                console.log(d);
                                return '$' + format(d[i].spend); 
                            })

您需要像这样在鼠标上添加描述

.on('mouseover', function(d, i) {
                    var index = i + 1;
                    var nodeSel = d3.select(this).style({opacity:'0.8'});
                    nodeSel.select('text').style({opacity:'1.0'});
                    d3.select('.slice:nth-of-type('+index+')').style('visibility', 'visible');
                    d3.select('.spend:nth-of-type('+index+')').style('visibility', 'visible');
                    d3.select('.fixedLine').style('visibility', 'visible');
                    d3.selectAll('text').style('visibility', 'visible');
                    //setting the description data to the text dom
                    d3.selectAll(".description").text(d.data.description);
                    //setting the spend data to the text dom
                    d3.selectAll(".spend").text('$' + format(d.data.spend))
                });

工作代码here.