D3:饼式标签的“水平”尾线没有重叠
D3: pie labels with "horizontal ending"-lines without overlapping
我非常喜欢David Buezas带有线条的饼状图,尤其是那些水平线,因为它们提高了可读性:http://bl.ocks.org/dbuezas/9306799。但是标签重叠,线条也可能重叠。
偶然发现http://blog.safaribooksonline.com/2014/03/11/solving-d3-label-placement-constraint-relaxing/(包含很多麻烦,抱歉,没有足够的声誉张贴链接),它解释了如何避免重叠。试图适应这个例子,以"水平结束"标记行,基本上是用<polyline>
代替<line>
,但失败了。
-
它看起来像
<line>
会有不同的输出比<polyline>
,因为我复制了所有的属性,但它绘制不同(很确定我没有搞砸) -
我显然不明白在Bueza的例子中,这些行是如何被切成文本的。我想我可以做一个变通:
- 用
<polyline>
代替<line>
- 将
<line>
的属性复制到<polyine>
的点属性 - 添加属性,绘制一条直线,水平线
<polyline>
通过简单地做last x-value + 30
-
然后用transform
调整文本 除了这比Bueza的例子差得多之外,我也不介意人们不知道水平线是向左还是向右(标签可以在图表的两侧)。
- 用
谁能来帮我一下
- 告诉我为什么
<line>
的输出和<polyline>
不同? - 让"切片到文本"的东西从Buezas的例子对新手更清楚一点?
这是我的尝试:http://jsfiddle.net/HdwTH/40/
这个答案的方法奏效了,尤其是下面的几行(非常感谢Lars的提示)。
/* check whether the default position
overlaps any other labels*/
var conflicts = [];
labelLayout.visit(function(node, x1, y1, x2, y2){
//recurse down the tree, adding any overlapping labels
//to the conflicts array
//node is the node in the quadtree,
//node.point is the value that we added to the tree
//x1,y1,x2,y2 are the bounds of the rectangle that
//this node covers
if ( (x1 > d.r + maxLabelWidth/2)
//left edge of node is to the right of right edge of label
||(x2 < d.l - maxLabelWidth/2)
//right edge of node is to the left of left edge of label
||(y1 > d.b + maxLabelHeight/2)
//top (minY) edge of node is greater than the bottom of label
||(y2 < d.t - maxLabelHeight/2 ) )
//bottom (maxY) edge of node is less than the top of label
return true; //don't bother visiting children or checking this node
var p = node.point;
var v = false, h = false;
if ( p ) { //p is defined, i.e., there is a value stored in this node
h = ( ((p.l > d.l) && (p.l <= d.r))
|| ((p.r > d.l) && (p.r <= d.r))
|| ((p.l < d.l)&&(p.r >=d.r) ) ); //horizontal conflict
v = ( ((p.t > d.t) && (p.t <= d.b))
|| ((p.b > d.t) && (p.b <= d.b))
|| ((p.t < d.t)&&(p.b >=d.b) ) ); //vertical conflict
if (h&&v)
conflicts.push(p); //add to conflict list
}
});
if (conflicts.length) {
console.log(d, " conflicts with ", conflicts);
var rightEdge = d3.max(conflicts, function(d2) {
return d2.r;
});
d.l = rightEdge;
d.x = d.l + bbox.width / 2 + 5;
d.r = d.l + bbox.width + 10;
}
else console.log("no conflicts for ", d);
/* add this label to the quadtree, so it will show up as a conflict
for future labels. */
labelLayout.add( d );
var maxLabelWidth = Math.max(maxLabelWidth, bbox.width+10);
var maxLabelHeight = Math.max(maxLabelHeight, bbox.height+10);
下面是工作解决方案:http://jsfiddle.net/Qh9X5/1249/
相关文章:
- HighCharts长标题文本在某些元素上重叠
- 如何检测重叠元素下的单击
- 允许表单元格内容水平展开
- 停止较大单词的重叠
- 如何在c3js动态图表上进行平滑(水平)转换
- 如何创建一个具有固定左右列和水平滚动的表
- FullCalendar:事件发生时阻止重叠.标题是一样的
- 通过水平滚动将页眉固定到页面顶部
- 水平视差滚动从头开始-没有插件(jQuery)
- 在页脚处停止固定侧边栏-防止重叠
- JS图表和html表格重叠
- 具有Twitter引导程序的水平滚动表
- 如何避免鼠标水平滚动选项卡面板溢出
- Cordova AngularJS Ionic标签的内容在第一次加载时重叠
- 将多个重叠的透明图像保存为一个图像
- 使用CSS嵌入HTML中的水平居中jQuery
- 在扩展中,管理最小化了底部水平的窗口,而不是重叠
- Highcharts单行堆叠水平条:标签重叠---条形段太小而无法读取“dataLabels”---(更改“dataLa
- D3:饼式标签的“水平”尾线没有重叠
- JqPlot水平条重叠