【问题标题】:Fix d3.js v4 tooltip position修复 d3.js v4 工具提示位置
【发布时间】:2018-10-21 05:20:06
【问题描述】:

我一直在尝试使用 d3 v4 插件在我的网页中显示两个图表

我一直在关注一些关于工具提示用法的示例,但我遇到了一个问题:在第一个图表中,工具提示显示在正确的位置(在条形上方),但在底部图表中,工具提示似乎进入了底部页面。

这是一个非常简单的例子:https://jsfiddle.net/xvs98vru/

HTML

<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div id="chart1" class="c"></div>
        </div>
        <div class="col-md-12">
            <div id="chart2" class="c"></div>
        </div>
    </div>
</div>

CSS

body { padding: 20px; }

.c {
  height: 300px;
  width: 400px;
  margin-bottom: 10px;
}

.tooltipx {
    pointer-events: none;
    position: absolute;
    display: none;
    min-width: 50px;
    height: auto;
    background: none repeat scroll 0 0 #ffffff;
    padding: 4px 10px 4px 10px;
    border-radius: 4px;
    text-align: left;
    line-height: 1.3;
    color: #5B6770;
    box-shadow: 0px 3px 9px rgba(0, 0, 0, .15);
}

JS

(function() {
    var mrg = { t:10, r:20, b:30, l:20 };

    var data = [
        { id: 1, amount: 6 },
        { id: 2, amount: 5 },
        { id: 3, amount: 2 },
        { id: 4, amount: 8 }
    ];

    function loadChart(container) {
        var width = 400 - mrg.l - mrg.r;
        var height = 300 - mrg.t - mrg.b;

        var color = d3.scaleOrdinal(d3.schemeCategory10);
        var tooltip = d3.select(container).append("div")
                        .attr("class", "tooltipx")
                        .style("opacity", 0);

        var x = d3.scaleBand().range([0, width]).padding(0.1);
        var y = d3.scaleLinear().range([height, 0]);

        x.domain([1, 2, 3, 4]);
        y.domain([0, 10]);

        var svg = d3.select(container).append("svg")
                    .attr("width", width + mrg.l + mrg.r)
                    .attr("height", height + mrg.t + mrg.b)
                    .append("g")
                    .attr("transform", "translate(" + mrg.l + "," + mrg.t + ")");

        svg.selectAll(".bar")
           .data(data)
           .enter()
           .append("rect")
           .attr("class", "bar")
           .attr("x", function(n) { return x(n.id); })
           .attr("y", function(n) { return y(n.amount); })
           .attr("width", x.bandwidth())
           .attr("height", function(n) { return height - y(n.amount); })
           .attr("fill", function(n, i) { return color(i); })
           .on("mousemove", function(n) {
               tooltip
                   .style("opacity", 1)
                   .style("left", d3.event.pageX + "px")
                   .style("top", d3.event.pageY + "px")
                   .style("display", "inline-block")
                   .html("<span>Hola</span>")
           })
           .on("mouseout", function(n) { tooltip.style("opacity", 0); });

        svg.append("g")
           .attr("transform", "translate(0," + height + ")")
           .call(d3.axisBottom(x));

        svg.append("g").call(d3.axisLeft(y));
    }

    function init() {
        loadChart("#chart1");
        loadChart("#chart2");
    }

    init();

}());

感谢支持

问候

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    由于您使用pageXpageY 来定位工具提示,因此不要将它们附加到每个选定的div...而不是那样,将它们附加到&lt;body&gt;

    var tooltip = d3.select("body").append("div")
    

    这是您的代码,仅进行了更改:

    (function() {
      var mrg = {
        t: 10,
        r: 20,
        b: 30,
        l: 20
      };
    
      var data = [{
          id: 1,
          amount: 6
        },
        {
          id: 2,
          amount: 5
        },
        {
          id: 3,
          amount: 2
        },
        {
          id: 4,
          amount: 8
        }
      ];
    
      function loadChart(container) {
        var width = 400 - mrg.l - mrg.r;
        var height = 300 - mrg.t - mrg.b;
    
        var color = d3.scaleOrdinal(d3.schemeCategory10);
        var tooltip = d3.select("body").append("div")
          .attr("class", "tooltipx")
          .style("opacity", 0);
    
        var x = d3.scaleBand().range([0, width]).padding(0.1);
        var y = d3.scaleLinear().range([height, 0]);
    
        x.domain([1, 2, 3, 4]);
        y.domain([0, 10]);
    
        var svg = d3.select(container).append("svg")
          .attr("width", width + mrg.l + mrg.r)
          .attr("height", height + mrg.t + mrg.b)
          .append("g")
          .attr("transform", "translate(" + mrg.l + "," + mrg.t + ")");
    
        svg.selectAll(".bar")
          .data(data)
          .enter()
          .append("rect")
          .attr("class", "bar")
          .attr("x", function(n) {
            return x(n.id);
          })
          .attr("y", function(n) {
            return y(n.amount);
          })
          .attr("width", x.bandwidth())
          .attr("height", function(n) {
            return height - y(n.amount);
          })
          .attr("fill", function(n, i) {
            return color(i);
          })
          .on("mousemove", function(n) {
            tooltip
              .style("opacity", 1)
              .style("left", d3.event.pageX + "px")
              .style("top", d3.event.pageY + "px")
              .style("display", "inline-block")
              .html("<span>Hola</span>")
          })
          .on("mouseout", function(n) {
            tooltip.style("opacity", 0);
          });
    
        svg.append("g")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));
        svg.append("g").call(d3.axisLeft(y));
      }
    
      function init() {
        loadChart("#chart1");
        loadChart("#chart2");
      }
    
      init();
    
    }());
    body {
      padding: 20px;
    }
    
    .c {
      height: 300px;
      width: 400px;
      margin-bottom: 10px;
    }
    
    .tooltipx {
      pointer-events: none;
      position: absolute;
      display: none;
      min-width: 50px;
      height: auto;
      background: none repeat scroll 0 0 #ffffff;
      padding: 4px 10px 4px 10px;
      border-radius: 4px;
      text-align: left;
      line-height: 1.3;
      color: #5B6770;
      box-shadow: 0px 3px 9px rgba(0, 0, 0, .15);
    }
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <div class="container">
      <div class="row">
        <div class="col-md-12">
          <div id="chart1" class="c"></div>
        </div>
        <div class="col-md-12">
          <div id="chart2" class="c"></div>
        </div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-09
      • 1970-01-01
      • 2013-04-21
      • 2023-03-04
      • 2022-08-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多