2015-08-15 5 views
7

Ich versuche, ein Rect-Element hinter Text mit D3 hinzuzufügen, um Hintergrundfarbe zu simulieren, die für Textelemente d3 nicht existiert. Ich möchte, dass das Rechteck genau die gleiche Größe wie der Text selbst hat.Wie füge ich d3 Textelementen eine Hintergrundfarbe hinzu?

node.append("text") 
    .attr("class", "text") 
    .attr("text-anchor", "middle") 
    .attr("dx", 0) 
    .attr("dy", ".35em") 
    .text(function(d) { 
      var bbox = this.getBBox(); 
      node.insert("rect",":first-child") 
      .attr("x", bbox.x) 
      .attr("y", bbox.y) 
      .attr("width", bbox.width) 
      .attr("height", bbox.height) 
      .style("fill", "yellow"); 
     return d.name; 
    }); 

this.getBBox() gibt 0 für x und y zurück.

Der folgende Code zeigt die Box, aber es ist nicht sehr groß mit Textgröße, und die Box wird gezeichnet, auch wenn Text nicht (wenn ein Bild existiert).

node.filter(function(d) {return (!d.image)}).append("text") 
    .attr("class", function(d) { return "text "+d.type; }) 
    .attr("text-anchor", "middle") 
    .attr("dx", 0) 
    .attr("dy", ".35em") 
    //.text(function(d) { if (!d.imgB64) { return d.label; } 
    .text(function(d) { 
     return d.name; 
    }) 
    .each(function(d) { 
     var bbox = this.getBBox(); 
      node.insert("rect", "text") 
      .style("fill", "#FFE6F0") 
      .attr("x", bbox.x) 
      .attr("y", bbox.y) 
      .attr("width", bbox.width) 
      .attr("height", bbox.height); 
    }); 

SOLUTION

Dank jetzt Blau, den folgenden Code kühlen richtig funktioniert: eine rect hinter dem Text angezeigt werden, so dass sie lesbar, wenn größer als der Knoten Kreis ist. Im futur könnte es mit einer Kugel Bogen verbessert werden anstatt der rect nur das Kreisfeld hinter dem Text zu verbergen ...

enter image description here

// only display node labels if node has no image 
node.filter(function(d) {return (!d.image)}).append("text") 
    .attr("class", function(d) { return "text "+d.type; }) 
    .attr("text-anchor", "middle") 
    .attr("dx", 0) 
    .attr("dy", ".35em") 
    .text(function(d) { 
     return d.name; 
    }) 
    .call(getTextBox); 

// only display a rect behind labels if node has no image 
node.filter(function(d) {return (!d.image)}).insert("rect","text") 
    .attr("x", function(d){return d.bbox.x}) 
    .attr("y", function(d){return d.bbox.y}) 
    .attr("width", function(d){return d.bbox.width}) 
    .attr("height", function(d){return d.bbox.height}) 
    .style("fill", "#FFE6F0"); 

function getTextBox(selection) { 
    selection.each(function(d) { d.bbox = this.getBBox(); }) 
} 
+0

Was passiert, wenn Sie 'box.x' durch' d3.select (this) .attr ("x") 'ersetzen? –

+0

Wie auch immer, die Bounding Box hat keine Breite und Höhe, da noch kein Text hinzugefügt wurde. Ich würde es anders machen ... Siehe [dieses Beispiel] (http://bl.ocks.org/cool-Blue/9f49525e782491c8b68a) –

+0

Ich schaffte es, es teilweise durch Verschieben des Codes in einer .each (Funktion (d) {...}) aber es gibt immer noch Probleme: die Box hat immer die gleiche Größe, während ich möchte, dass die Größe mit der Textgröße variiert und es eine Box für jeden Knoten zeichnet, auch wenn sie keine Beschriftung (Text) haben . Siehe Code oben. – Pierre

Antwort

3

Wie in den Kommentaren erwähnt, verwenden diese Muster und fügen Welche Details auch immer Sie brauchen ...

var textNode = node.filter(function(d) {return (!d.image)}) 

textNode.append("text") 
    .attr("class", "text") 
    .attr("text-anchor", "middle") 
    .attr("dx", 0) 
    .attr("dy", ".35em") 
    .text(function(d) { 
     return d.name; 
    }).call(getBB); 
textNode.insert("rect","text") 
    .attr("width", function(d){return d.bbox.width}) 
    .attr("height", function(d){return d.bbox.height}) 
    .style("fill", "yellow"); 

function getBB(selection) { 
    selection.each(function(d){d.bbox = this.getBBox();}) 
} 
+0

Dies tut nicht arbeite für mich, keine fehlermeldung aber immer noch kein rechteck. Nach den vorherigen Empfehlungen habe ich mit .call (getBB) die richtige Boxgröße bekommen, jetzt muss ich die rect einfügen. – Pierre

+1

Sie müssen möglicherweise x und y Attribute hinzufügen. Ich dachte, sie könnten null sein. Ist Knoten ein Element mit Daten, die übrigens gebunden sind? Ach ja, ich sehe das Problem ... Der Text ist noch nicht da, ja, der separate Anruf ist der richtige Weg. Ich habe versucht, zu knapp zu sein. –

+0

Mit .call (getTextBox) direkt nach dem .text() und dann wie unten Knoten einfügen, erhalte ich eine Fehlermeldung d.bbox.width \t node.insert ("rect", "text") \t \t auswertet. attr ("Breite", Funktion (d) {return d.bbox.width}) \t \t .attr ("Höhe", Funktion (d) {return d.bbox.height}) \t \t.Stil ("füllen", "gelb"); – Pierre

Verwandte Themen