如何避免多系列折线图的重叠工具提示d3.js [英] How to avoid overlapping tooltips of multi-series line chart d3.js

查看:1747
本文介绍了如何避免多系列折线图的重叠工具提示d3.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已在



工具提示重叠。我想要的是当工具提示重叠,移动任何一个更高或更低。我试图通过更改下面的代码这样做。

  var beginning = 0,
end = lines ] .getTotalLength(),
target = null;
//console.log(lines.i)
//console.log (end)
while(true){
target = Math.floor((beginning + end )/ 2);
pos = lines [i] .getPointAtLength(target);
if((target === end || target === beginning)&& pos.x!== mouse [0]){
break;
}
console.log(pos)
if(pos.x> mouse [0])end = target;
else if(pos.x< mouse [0])begin = target;
else break; // position found
}

我的想法是重新计算 end 。如果 lines [0] .getTotalLength() lines [1] .getTotalLength()的减法小于或大于一个值,然后更新end的值(例如。end = end + 20)。但我没有得到代码在这里工作。



有人知道如何做到这一点吗?

解决方案

查看更改:



https://jsfiddle.net/fk6gfwjr/1/



基本上,工具提示需要按y位置排序,然后我们确保以该排序顺序相邻的工具提示以最小距离(我选择15px)分隔。然后将与先前计算的y位置的偏移量添加到工具提示文本。我也为文本着色,使他们更容易分辨哪个是。

  var ypos = [] 

d3.selectAll(。mouse-per-line)
.attr(transform,function(d,i){
// same code as before b $ b // ...
//向数组添加位置
ypos.push({ind:i,y:pos.y,off:0});

returntranslate(+ mouse [0] +,+ pos.y +);
})
//按y位置对数组进行排序,最少15个像素分开
//从最后,计算一个偏移量从它们当前的y值,
//然后通过索引
.call(function(sel){
ypos .sort(function(a,b){return ay-by;});
ypos.forEach(function(p,i){
if(i> 0){
var last = ypos [i-1] .y;
ypos [i] .off = Math.max(0,(last + 15)-ypos [i] .y);
ypos [i] .y + = ypos [i] .off;
}
})
ypos.sort(function(a,b){return a.ind - b.ind;});
})
//使用偏移从它的g元素移动提示文本
//不想移动圆形
.select(text)
.attr(transform,function(d,i){
returntranslate(10,+(3 + ypos [i] .off)+)
}
;


I' ve created tooltips on multi-series line chart following the answer here. If I mouse over the last date as you can see in this picture:

the tooltips are overlapping. What I want is when tooltips are overlapping, move any of them a little higher or lower. I was trying to do this by changing the code below.

   var beginning = 0,
        end = lines[i].getTotalLength(),
        target = null;
    //console.log(lines[i])             
    //console.log(end)
    while (true){
      target = Math.floor((beginning + end) / 2);
      pos = lines[i].getPointAtLength(target);
      if ((target === end || target === beginning) && pos.x !== mouse[0]) {
          break;
      }
      console.log(pos)
      if (pos.x > mouse[0])      end = target;
      else if (pos.x < mouse[0]) beginning = target;
      else break; //position found
    } 

My thought was recalculating the end. If the substraction of lines[0].getTotalLength() and lines[1].getTotalLength() is less than or larger than a value, then update the value of end(eg. end = end + 20).But I didn't get the code work here.

Does anybody know how to do this? Or is there an easier way to avoid tooltips overlapping?

解决方案

See changes here:

https://jsfiddle.net/fk6gfwjr/1/

Basically the tooltips need to be sorted by y position, and then we make sure neighbouring tooltips in that sort order are separated by a minimum distance (i picked 15px). The offset to the previously calculated y position is then added to the tooltip text. I also coloured the text to make them easier to tell which is which.

    var ypos = [];

    d3.selectAll(".mouse-per-line")
      .attr("transform", function(d, i) {
        // same code as before
        // ...
          // add position to an array
          ypos.push ({ind: i, y: pos.y, off: 0});

        return "translate(" + mouse[0] + "," + pos.y +")";
      })
      // sort this array by y positions, and make sure each is at least 15 pixels separated
      // from the last, calculate an offset from their current y value,
      // then resort by index
      .call(function(sel) {
        ypos.sort (function(a,b) { return a.y - b.y; });
        ypos.forEach (function(p,i) {
            if (i > 0) {
            var last = ypos[i-1].y;
           ypos[i].off = Math.max (0, (last + 15) - ypos[i].y);
            ypos[i].y += ypos[i].off;
          }
        })
        ypos.sort (function(a,b) { return a.ind - b.ind; });
      })
      // Use the offset to move the tip text from it's g element
      // don't want to move the circle too
      .select("text")
        .attr("transform", function(d,i) {
            return "translate (10,"+(3+ypos[i].off)+")";
        }
      ;

这篇关于如何避免多系列折线图的重叠工具提示d3.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆