javascript - D3: pie labels with "horizontal ending"-lines without overlapping -
i david buezas pie chart lines, especially horizontal lines, improve readability: http://bl.ocks.org/dbuezas/9306799. labels overlap there, lines potentially too.
stumbled upon http://blog.safaribooksonline.com/2014/03/11/solving-d3-label-placement-constraint-relaxing/ (contains lot of fiddles, sorry, not enough reputation posting link), explains how avoid overlapping. tried adapt example label lines "horizontal ending", replacing <line>
<polyline>
, failed.
it appears
<line>
have different output<polyline>
, because copied attributes, it's drawn differently (pretty sure didn't mess up)i don't how lines sliced text in bueza's example. thought workaround by:
- replacing
<line>
<polyline>
- copy attributes
<line>
<polyine>
's points attributes - add attribute draws straight, horizontal line
<polyline>
doinglast x-value + 30
then adapt text somehow transform
apart fact lot less elegant bueza's example, did not mind 1 doesn't know if horizontal line needs go left or right (labels on both sides of chart).
- replacing
can please
- tell me why
<line>
has different output<polyline>
? - make "slice text"-thing buezas example little clearer newbie?
here's try: http://jsfiddle.net/hdwth/40/
thanks lot.
the approach this answer did trick, following lines (thanks lot lars hint).
/* check whether default position overlaps other labels*/ var conflicts = []; labellayout.visit(function(node, x1, y1, x2, y2){ //recurse down tree, adding overlapping labels //to conflicts array //node node in quadtree, //node.point value added tree //x1,y1,x2,y2 bounds of rectangle //this node covers if ( (x1 > d.r + maxlabelwidth/2) //left edge of node right of right edge of label ||(x2 < d.l - maxlabelwidth/2) //right edge of node left of left edge of label ||(y1 > d.b + maxlabelheight/2) //top (miny) edge of node greater bottom of label ||(y2 < d.t - maxlabelheight/2 ) ) //bottom (maxy) edge of node less top of label return true; //don't bother visiting children or checking node var p = node.point; var v = false, h = false; if ( p ) { //p defined, i.e., there value stored in 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 conflict list } }); if (conflicts.length) { console.log(d, " conflicts ", 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 ", d); /* add label quadtree, show conflict future labels. */ labellayout.add( d ); var maxlabelwidth = math.max(maxlabelwidth, bbox.width+10); var maxlabelheight = math.max(maxlabelheight, bbox.height+10);
here's fiddle working solution: http://jsfiddle.net/qh9x5/1249/
Comments
Post a Comment