2016-05-19 9 views
2

Ich habe ein Objekt zum Speichern von Informationen für SVG-Formen. Es hat die folgende Struktur:D3 zeichnen verschiedene SVG-Formen in einem Aufruf, keine Sichtbarkeit

Shapes = { 
     id: <Shape ID>, 
     objType: <Tag Name of Shape e.g ellipse or line>, 
     Coordinates: < Object Containing relevant data for drawing >, 
     Style: <Object Containing relevant data for styling>, 
} 

Examples for Coordinates and Style could be: 
Shapes.Coordinates = { 
    x1: 10, // for Lines 
    y1: 10, 
    x2: 100, 
    y2: 100, 
} 

Shapes.Coordinates = { 
    cx: 10 ,// for Circles 
    cy: 10, 
    r: 10, 
} 

Shapes.Style = { 
    fill: "black", 
    stroke: "red", 
    "stroke-width": 10 
} 

Jetzt habe ich ein D3 Anruf die angegebenen Daten nutzen wollen, verschiedene Formen zu zeichnen, nach den Objektdaten. Meine beste Idee wäre bisher folgender Code:

Zuerst erstelle ich jede Form ohne Attribute, nur die ID und Events.

let objectsRender = svg.selectAll("line") 
         .data(data) 
         .enter() 
         .append(function(d) { 
         return document.createElement(d.objType); 
         }) 
         .attr("id", function(d){ return prefix +d._id;}) 
         .attr("class", "no-attr") 
         .on("click",(d)=>{this.modeClick(d);}); 

Dann füge ich die Attribute in einem zweiten Aufruf, durch eine for-Schleife mit der rechten ID zu finden, die ich denke, keine gute Lösung ist. Ich kann die „leere“ svg-Tags finden, indem sie mit der Klasse für jeden Tag suchen no-attr

let objectsAttributes= svg.selectAll(".no-attr").each(function(){ 
    let id= d3.select(this).attr("id"); 
    let d = null; 
    d = data[0]; 

    for(i = 0;i < props.data.length; i++){ 
     if(id == prefix +props.data[i]._id){ 
     d = props.data[i]; 
     break; 
     } 
    } 

    if(d !== null){ 
    d3.select(this) 
     .attr(d.coordinates) 
     .attr(d.style) 
     .attr("class", null); 
    } 

Bisher diese temporäre Lösung, die alle Formen mit den relevanten Attributen erzeugt. Aber die Formen sind nicht sichtbar, es hängt mit dem Append-Aufruf zusammen.

     .append(function(d) { 
         return document.createElement(d.objType); 
         }) 

Kann mir jemand eine bessere Lösung vorschlagen oder mir sagen, warum mein svg in meinem Browser-Fenster nicht sichtbar sind, aber sichtbar durch die Entwicklungs-Tools?

Antwort

2

SVG-Elemente können nicht mit document.createElement erstellt werden, diese Methode kann nur HTML-Elemente erstellen.

SVG-Elemente müssen in dem SVG-Namespace über document.createElementNS erstellt werden ('http://www.w3.org/2000/svg', <Elementname>) so dass ich denke, in Ihrem Fall würden Sie

.append(function(d) { 
     return document.createElementNS('http://www.w3.org/2000/svg', d.objType); 
}) 

Die Browser-Tools wollen zeigen, dass Sie haben HTML-Elemente mit den gleichen Namen wie die SVG-Elemente erstellt, die Sie wirklich wollen, aber da sie HTML-Elemente sind, sind sie nicht funktionsfähig.

+0

Vielen Dank. Für mich hat es funktioniert, wenn ich die http://www.w3.org/2000/svg statt https://www.w3.org/2000/svg gewählt habe –

Verwandte Themen