无法在d3 v4中将工具提示添加到可缩放的散点图中

时间:2017-08-22 20:43:52

标签: d3.js

我正在尝试向散点图添加工具提示,这是我的代码,一切正常但不是工具提示。(双击缩小)。我需要一个显示x标签和y标签位置的工具提示。  我无法想到这样做的方法,因为当你必须使用缩放时似乎没有生成工具提示。

 <!DOCTYPE html>
<meta charset="utf-8">
<head>
    <style>
        body {
            font-family: "Helvetica Neue", Helvetica, sans-serif;
            font-size: 14px;
        }
        #tooltip {
          background-color: rgba(187,187,187, 0.7);
          border-radius: 5px;
          height: 18px;
          opacity: 0;
          pointer-events: none;
          position: absolute;
          text-align: center;
        }    
    </style>
</head>
<body>

    <script src="//d3js.org/d3.v4.min.js"></script>
    <script>

        // Create data
        function randomData(samples) {
            var data = [],
                random = d3.randomNormal();

            for (i = 0; i < samples; i++) {
                data.push({
                    x: random(),
                    y: random()
                });
            }
            return data;
        }
      var tooltip = d3.select('body').append('div')
                        .attr('id', 'tooltip');
        var data = randomData(300);

        var margin = { top: 20, right: 20, bottom: 30, left: 30 };
        width = 900 - margin.left - margin.right,
        height = 480 - margin.top - margin.bottom;

        var tooltip = d3.select("body").append("div")
            .attr("class", "tooltip")
            .style("opacity", 0);

        var x = d3.scaleLinear()          
              .range([0, width])
              .nice();

        var y = d3.scaleLinear()
            .range([height, 0]);

        var xAxis = d3.axisBottom(x).ticks(12),
            yAxis = d3.axisLeft(y).ticks(12 * height / width);

        var brush = d3.brush().extent([[0, 0], [width, height]]).on("end", brushended),
            idleTimeout,
            idleDelay = 350;

        var svg = d3.select("body").append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var clip = svg.append("defs").append("svg:clipPath")
            .attr("id", "clip")
            .append("svg:rect")
            .attr("width", width )
            .attr("height", height )
            .attr("x", 0) 
            .attr("y", 0); 

        var xExtent = d3.extent(data, function (d) { return d.x; });
        var yExtent = d3.extent(data, function (d) { return d.y; });
        x.domain(d3.extent(data, function (d) { return d.x; })).nice();
        y.domain(d3.extent(data, function (d) { return d.y; })).nice();

        var scatter = svg.append("g")
             .attr("id", "scatterplot")
             .attr("clip-path", "url(#clip)");

        scatter.selectAll(".dot")
            .data(data)
          .enter().append("circle")
            .attr("class", "dot")
            .attr("r", 4)
            .attr("cx", function (d) { return x(d.x); })
            .attr("cy", function (d) { return y(d.y); })
            .attr("opacity", 0.5)
            .style("fill", "#4292c6")
             .on('mouseover', d => {
                tooltip.transition()
                  .duration(100)        
                  .style('opacity', .9);
                tooltip.text(`text here`)
                  .style('left', `${d3.event.pageX + 2}px`) 
                  .style('top', `${d3.event.pageY - 18}px`);
              })
              .on('mouseout', () => {       
                tooltip.transition()        
                .duration(400)      
                .style('opacity', 0);   
              });

        // x axis
        svg.append("g")
           .attr("class", "x axis")
           .attr('id', "axis--x")
           .attr("transform", "translate(0," + height + ")")
           .call(xAxis);

        svg.append("text")
         .style("text-anchor", "end")
            .attr("x", width)
            .attr("y", height - 8)
         .text("X Label");

        // y axis
        svg.append("g")
            .attr("class", "y axis")
            .attr('id', "axis--y")
            .call(yAxis);

        svg.append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", "1em")
            .style("text-anchor", "end")
            .text("Y Label");

        scatter.append("g")
            .attr("class", "brush")
            .call(brush);

        function brushended() {

            var s = d3.event.selection;
            if (!s) {
                if (!idleTimeout) return idleTimeout = setTimeout(idled, idleDelay);
                x.domain(d3.extent(data, function (d) { return d.x; })).nice();
                y.domain(d3.extent(data, function (d) { return d.y; })).nice();
            } else {

                x.domain([s[0][0], s[1][0]].map(x.invert, x));
                y.domain([s[1][1], s[0][1]].map(y.invert, y));
                scatter.select(".brush").call(brush.move, null);
            }
            zoom();
        }

        function idled() {
            idleTimeout = null;
        }

        function zoom() {

            var t = scatter.transition().duration(750);
            svg.select("#axis--x").transition(t).call(xAxis);
            svg.select("#axis--y").transition(t).call(yAxis);
            scatter.selectAll("circle").transition(t)
            .attr("cx", function (d) { return x(d.x); })
            .attr("cy", function (d) { return y(d.y); });
        }

    </script>
</body>

JSFiddle:https://jsfiddle.net/mw8v3phd/

1 个答案:

答案 0 :(得分:1)

您正在覆盖tooltip变量,再次分配它:

var tooltip = d3.select('body').append('div')
    .attr('id', 'tooltip');

var tooltip = d3.select("body").append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

只保留一个tooltip变量,即CSS中的样式:

var tooltip = d3.select('body').append('div')
    .attr('id', 'tooltip')
    .style("opacity", 0);

编辑:要使工具提示有效,请更改组的顺序。这是更新的小提琴:https://jsfiddle.net/gerardofurtado/5ja2ssa1/