2013-07-22 13 views
7

Gibt es in d3 eine Möglichkeit, überlappende Hilfsstrichbeschriftungen nicht zu zeichnen? Zum Beispiel, wenn ich ein Balkendiagramm habe, aber die Balken nur 5 Pixel breit sind und die Etiketten 10 Pixel breit sind, lande ich mit einem Durcheinander. Ich arbeite gerade an einer Implementierung, um die Etiketten nur zu zeichnen, wenn sie sich nicht überlappen. Ich kann keinen existierenden Weg finden, war mir aber nicht sicher, ob jemand anderes dieses Problem gelöst hat.d3 automatisch überlappende Hilfsstrichbeschriftungen

Antwort

6

Es gibt keine Möglichkeit, dies automatisch in D3 zu tun. Sie können die Anzahl der Ticks oder der Tick-Werte explizit festlegen (siehe the documentation), aber Sie müssen die entsprechenden Zahlen/Werte selbst herausfinden. Eine andere Option wäre, die Etiketten so zu rotieren, dass die Wahrscheinlichkeit einer Überlappung geringer ist.

Alternativ können Sie, wie in der anderen Antwort vorgeschlagen, ein Force-Layout verwenden, um die Beschriftungen zu platzieren. Um dies zu verdeutlichen, würden Sie das Force-Layout nur auf den Beschriftungen verwenden - dies ist völlig unabhängig vom Typ des Diagramms. Ich habe dies in this example getan, das ist etwas relevanter als das in der anderen Antwort verlinkte.

Beachten Sie, dass Sie die Position der Beschriftungen nicht animieren müssen, wenn Sie mit der Force-Layout-Lösung arbeiten. Sie können das Kraft-Layout einfach berechnen, bis es konvergiert und dann die Beschriftungen plotten.

1

könnten Sie versuchen, etwas in this Thread, insbesondere this example genannten, so dass die Etiketten nach oben/unten/aus dem Weg geschoben werden, so dass sie alle eingepasst werden können. Dies erfordert eine separate Kräfte, eine für die Knoten und ein anderes für die Etiketten selbst.

+0

Ich bin nicht eine Kraft Layout. Ich habe ein Balkendiagramm. –

2

Ich hatte ein ähnliches Problem mit mehreren (Sub-) Achsen, wo der letzte Tick in einigen Situationen meine vertikale Achse überlappt (abhängig von der Bildschirmbreite), also habe ich nur eine kleine Funktion geschrieben, die das vergleicht Position des Endes des Textlabels mit der Position der nächsten Achse. Dieser Code ist in meine Anwendungsfall sehr spezifisch, könnte aber leicht an Ihre Bedürfnisse angepasst:

var $svg = $('#svg'); 

// get the last tick of each of my sub-axis 
$('.tick-axis').find('.tick:last-of-type').each(function() { 

    // get position of the end of this text field 
    var endOfTextField = $(this).offset().left + $(this).find('text').width(); 

    // get the next vertical axis 
    var $nextAxis = $('line[data-axis="' + $(this).closest('.tick-axis').attr('data-axis') + '"]'); 

    // there is no axis on the very right, so just use the svg width 
    var positionOfAxis = ($nextAxis.length > 0) ? $nextAxis.offset().left : $svg.offset().left + $svg.width(); 

    // hide the ugly ones! 
    if (endOfTextField > positionOfAxis) { 
    $(this).attr('class', 'tick hide'); 
    } 

}); 

Die Zecken mit color: aqua sind die ausgeblendete:

enter image description here