2013-06-14 8 views
5

Ich versuche, eine Linie zu zeichnen, zwei Kreise in SVG zu verbinden. Die Kreise sind - zusammen mit darunterliegenden Rechtecken - in einer SVG-Gruppen-Elemente() eingekapselt. Diese Gruppen werden mit den Attributen transform = "translate (x, y)" positioniert. Mein Problem ist, dass die Koordinaten der Elemente innerhalb der Gruppe relativ zu den Ursprüngen (0,0 Koordinaten) ihrer Gruppen positioniert sind. Um eine darüberliegende Linie zu platzieren, muss ich die absoluten Koordinaten kennen.Wie kann ich relativ zu einem Element definierte SVG-Koordinaten (x, y) in absolute Koordinaten/Positionen umrechnen?

Hier ist der Code der D3 mit Hilfe von JavaScript-Bibliothek:

var body = d3.select("body"); 

var svg = body.append("svg"); 

var group1 = svg.append("g") 
    .attr("transform", "translate(50,50)"); 

var rect1 = group1.append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", 100) 
    .attr("height", 100) 
    .style("fill", 'lightblue'); 

var circ1 = group1.append("svg:circle") 
    .attr("cx", 50) 
    .attr("cy", 50) 
    .attr("r", 10) 
    .style("fill", 'red') 

var group2 = svg.append("g") 
    .attr("transform", "translate(350,50)"); 

var rect2 = group2.append("svg:rect") 
    .attr("x", 0) 
    .attr("y", 0) 
    .attr("width", 100) 
    .attr("height", 100) 
    .style("fill", 'lightgreen'); 

var circ2 = group2.append("svg:circle") 
    .attr("cx", 50) 
    .attr("cy", 50) 
    .attr("r", 10) 
    .style("fill", 'red'); 

var line = svg.append("svg:line") 
    .attr("x1", parseInt(circ1.attr("cx"))) 
    .attr("y1", parseInt(circ1.attr("cy"))) 
    .attr("x2", parseInt(circ2.attr("cx"))) 
    .attr("y2", parseInt(circ2.attr("cy"))) 
    .attr("stroke", "black"); 

weiß ich, warum die Linie nicht angezeigt. Ich weiß auch, dass jedes SVG-Element mit einer Transformationsmatrix zusammenhängt. Ich bin nicht sicher, wie man auf die Matrizen der Kreiselemente zugreift und wie man die absoluten Koordinaten von ihnen erhält (die cx/cy Attribute). Eine andere Möglichkeit wäre, die absolute Entfernung der Kreise zu erhalten.

Hier ist ein jsfiddle with the above code

+0

Es wird viel einfacher, wenn Sie die Elemente in der gleichen Gruppe behalten. –

+1

Ja wird es sein. Aber dann muss ich mich um die Position der Kreise und Rechtecke kümmern. Dies ist der Grund, warum ich mich entschieden habe, den Ansatz mit mehreren Gruppen zu versuchen. – karlitos

Antwort

6

Ich glaube, ich war in der Lage, das Problem selbst zu lösen. Der Zugriff auf die Transformationsmatrix erreicht

verwendet werden könnte
circ1[0][0].getCTM() 

oder durch

Verwendung
circ1[0][0].getScreenCTM() 

, indem der Wert des e Attribut dem x Koordinate und der Wert der f Attribut an die y Koordinate konnte ich die "absolute Position" der Elemente bekommen.

Aktualisiert jsfiddle ist here

Ich fürchte, meine Lösung nicht allgemeingültig ist. Zum Beispiel bin ich mir nicht sicher, was passiert in einem Fall, den ich Umwandlung verwenden werde: Skala vor der Berechnung der Position?

+0

Sie haben mich in die richtige Richtung gehen. Ich denke, dass das Lesen und Verstehen von Kapitel 7 des SVG-Dokuments mir die ganze Geschichte geben wird. Ich nehme an, die bevorzugte Methode wäre, die Transformationsmatrix zu verwenden und verschiedene Dinge wie Matrix zu multiplizieren, um zu erreichen, was Sie (und ich) zu tun versuchen. – pedz

+1

Ich denke, Sie können die vollständige Formel für die Zuordnung zu einem neuen Koordinatensystem von hier https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform; absX = a * x + c * y + e und absY = b * x + d * y + f (was im Fall von translate transform wird zu der Lösung in Ihrer aktuellen Antwort zu vereinfachen) –

+0

Übrigens scheint nur getScreenCTM zu gib gültige Daten für mich zurück. Die Matrix von getCTM ändert die Position nach dem Anwenden nicht. –

Verwandte Themen