d3折线图标签重叠

时间:2013-04-01 17:33:22

标签: d3.js overlap labels linechart

我根据此处的示例创建了一个折线图:

http://bl.ocks.org/mbostock/3884955

但是,对于我的数据,线条标签(城市)最终会重叠,因为不同线条的y轴上的最终值经常靠近在一起。我知道我需要比较每一行的最后一个值,并在值相差12个或更少时向上或向下移动标签。我的想法是查看由这段代码写的文本标签

city.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," +  y(d.value.temperature) + ")"; })
.attr("x", 3)
.attr("dy", ".35em")
.text(function(d) { return d.name; });

如果y(d.value.temperature)值相差12或更小,则将值移开,直到它们之间至少有12个单位。有关如何完成这项工作的任何想法?这是我的第一个d3项目,语法仍然适合我!

2 个答案:

答案 0 :(得分:2)

你可能最好立刻传递所有标签 - 这也更符合一般d3的想法。然后你可以得到类似这样的代码:

svg.selectAll("text.label").data(data)
   .enter()
   .append("text")
   .attr("transform", function(d, i) {
       var currenty = y(d.value.temperature);
       if(i > 0) {
           var previousy = y(data[i-1].value.temperature),
           if(currenty - previousy < 12) { currenty = previousy + 12; }
       }
       return "translate(" + x(d.value.date) + "," +  currenty + ")";
   })
   .attr("x", 3)
   .attr("dy", ".35em")
   .text(function(d) { return d.name; });

这并未考虑到之前的标签可能已被移动的事实。您可以明确获取上一个标签的位置,并根据该位置移动当前标签。代码几乎相同,只是您需要保存对当前元素(this)的引用,以便以后可以访问它。

所有这些都不会阻止标签与最终标记的线条相距很远。如果你需要移动每个标签,最后一个标签将相当遥远。更好的做法可能是单独创建一个图例,您可以根据需要对标签和行进行空格分隔。

答案 1 :(得分:1)

考虑使用D3力布局来放置标签。请在此处查看示例:https://bl.ocks.org/wdickerson/bd654e61f536dcef3736f41e0ad87786

假设您有一个data数组,其中包含value属性和比例y的对象:

// Create some nodes
const labels = data.map(d => {
  return {
    fx: 0,
    targetY: y(d.value)
  };
});

// Set up the force simulation
const force = d3.forceSimulation()
  .nodes(labels)
  .force('collide', d3.forceCollide(10))
  .force('y', d3.forceY(d => d.targetY).strength(1))    
  .stop();

// Execute thte simulation
for (let i = 0; i < 300; i++) force.tick();

// Assign values to the appropriate marker
labels.sort((a, b) => a.y - b.y);
data.sort((a, b) => b.value - a.value);
data.forEach((d, i) => d.y = labels[i].y);

现在,您的data数组将具有代表其最佳位置的y属性。

示例使用D3 4.0,请在此处阅读更多内容:https://github.com/d3/d3-force