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

时间:2015-12-10 16:24:44

标签: javascript d3.js hover tooltip

我的目标是建立一个交互式图表,显示图表旁边弧线的其他信息。下面的代码不干净,但功能齐全,几乎可以实现我想要的一切。

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

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

我没有打算复制的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 个答案:

答案 0 :(得分:0)

问题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 DOM时,您无需设置text

 .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