Motivation:
Ich dachte zuerst darüber nach, einen Binärbaum zu erstellen, weil ich ein Unternehmensstrukturdiagramm erstellen musste. Der bisherige Ansatz bestand darin, ein Bild direkt mit einer Grafiksoftware zu zeichnen. Es sieht großartig aus, aber Sie müssen jedes Mal, wenn es Änderungen gibt, ein neues streichen. Andererseits sind die Darstellung und Anordnung von Zeilen auf Webseiten recht eingeschränkt. Satz und Positionierung auf Basis dynamisch generierter Daten sind sehr schwierig und die Ästhetik nicht zufriedenstellend. Nachdem ich verschiedene Versuche unternommen hatte, entschied ich mich, XML+XSL für Datenoperationen zu verwenden; VML zum Verschönern von Linien und JAVASCRIPT zum Positionieren von Objekten zu verwenden.
Material:
Das Strukturbaumdiagramm des XML-Volumes enthält zwei Dateien: flow2.xml und flow2.xsl
Wirkung:
Stöbern Sie hier
erklären:
Binärbaumidee (1)
<html xmlns:v="urn:schemas-microsoft-com:vml">
<STIL>
v:* { VERHALTEN: url(#default#VML) }
</STYLE>
<v:group id="group1" name="group1" coordsize = "100,100">
…
</v:group>
Dies sind die Grundformate von VML, daher werde ich sie nicht im Detail erklären.
XML ist eine Baumstruktur, wenn wir alle Daten lesen
Der XML-Datenbaum wird durchlaufen. Rekursive Operationen sind einer der Vorteile von XSL.
Ich habe mich auch für die Verwendung von XSL entschieden, nachdem ich verschiedene andere Methoden zur Durchführung von Durchlaufoperationen verwendet hatte und fehlgeschlagen war.
<FlowRoot>
<vcTitle>Binärbaum – Strukturdiagramm</vcTitle>
<Autor>Segelfliegen</Autor>
<Email>[email protected]</Email>
<FlowNode>
<iProcess>1</iProcess>
<vcCourse>Erster Knoten</vcCourse>
<iNextYes>
<FlowNode>
<iProcess>2</iProcess>
<vcCourse>Zweiter Knoten</vcCourse>
<iNextYes>…</iNextYes>
<iNextNo>…</iNextNo>
</FlowNode>
</iNextYes>
<iNextNo>
<FlowNode>
<iProcess>3</iProcess>
<vcCourse>Der dritte Knoten</vcCourse>
<iNextYes>…</iNextYes>
<iNextNo>…</iNextNo>
</FlowNode>
</iNextNo>
</FlowNode>
</FlowRoot>
Die Logik ist sehr einfach. Unter dem aktuellen Knoten (1) befinden sich zwei untergeordnete Knoten (2, 3).
Positionieren Sie Knoten 2 und Knoten 3 einfach unten links und unten rechts von Knoten 1.
Zur einfacheren Darstellung verwende ich hier Grün und Rot für die Verbindungslinien des linken bzw. rechten Knotens.
Wir haben bereits über die rekursive Funktion von XSL gesprochen. Um jeden einzelnen Anzeigeschritt klarer zu sehen, müssen Sie nur den folgenden Code nachahmen und eine Warnanweisung hinzufügen.
<xsl:template match="FlowNode">
…
<SCRIPT language="JavaScript1.2">
…
Alert('Schritt für Schritt anzeigen');
…
</SCRIPT>
…
</xsl:template>
Können Sie meine Gedanken verstehen, nachdem Sie sich die Zeitlupe oben angesehen haben?
Binärbaumidee (2)
Meine Idee ist ganz einfach:
(1) Lesen Sie die Daten des aktuellen Knotens und generieren Sie mithilfe von VML ein neues Objekt.
Weisen Sie dem Objekt einen Anfangswert zu (z. B. Name, ID, Stil usw.).
(2) Verwenden Sie die Skriptsteuerung, um das aktuelle Objekt zu positionieren. (3) Fügen Sie Pfeile und Linien zwischen dem aktuellen Knoten und seinem übergeordneten Knoten hinzu.
(4) Suchen Sie weiterhin nach den untergeordneten Knoten des aktuellen Knotens und wiederholen Sie die Schleife bis zum Ende.
Das heißt, alle Knoten wurden durchlaufen und der Baum wurde generiert.
<xsl:template match="FlowNode">
…
<xsl:apply-templates />
…
</xsl:template>
<xsl:template match="iNextYes">
<xsl:apply-templates select="./FlowNode" />
</xsl:template>
<xsl:template match="iNextNo">
<xsl:apply-templates select="./FlowNode" />
</xsl:template>
Der gesamte rekursive Prozess wird durch die oben genannten drei Module (Vorlagen) vervollständigt.
Die erste Vorlage ruft die folgenden zwei Vorlagen auf, wenn sie mit der Vorlage jedes untergeordneten Knotens im aktuellen Knoten übereinstimmt, und die beiden letztgenannten Vorlagen rufen die erste Vorlage während der spezifischen Ausführung auf, was einer rekursiven Funktion entspricht.
Grammatik:
Um die Vorlagen jedes untergeordneten Knotens im aktuellen Knoten nacheinander abzugleichen, verwenden Sie die Basisform des Elements <xsl:apply-templates />.
Andernfalls wird der passende Knoten durch den Wert des XPath-Ausdrucks im Auswahlparameter bestimmt, z. B. <xsl:apply-templates select="./FlowNode" />
Die Funktionen von (1) und (2) bestehen darin, den Zeichenfolgenwert des durch den Auswahlparameter angegebenen Ausdrucks zurückzugeben.
Ihre Suchbedingungen sind gleich, daher sind auch die zurückgegebenen Werte gleich.
Nur sind ihre Schreibformen je nach Verwendungszweck unterschiedlich.
(1) <xsl:value-of select="./iProcess/text()" />
(2) {./iProcess/text()}
Hier werden einige Variablen definiert, und die Positionierung des Knotens basiert auf diesen Variablen, um die Berechnungsformel aufzurufen.
root_left //Der linke Rand der Wurzel = die zugewiesene Breite aller Blätter (y*10) + die Breite aller Blätter (y*50) + der Grundwert des linken Randes (10)
root_top //Der obere Rand der Wurzel = der Grundwert des oberen Randes (10)
objOval //Das aktuelle Objekt ist ein Objekt
objOval_iProcess //Schrittwert des aktuellen Objekts
objParentOval // Der übergeordnete Knoten des aktuellen Objekts ist ein Objekt
objParentOval_iProcess //Der Schrittwert des übergeordneten Knotens des aktuellen Objekts
objParent_name //Der Name des übergeordneten Knotens des aktuellen Objekts
Leaf_left //Die Anzahl der linken Blätter unter allen untergeordneten Knoten des aktuellen Objekts
Leaf_right //Die Anzahl der rechten Blätter unter allen untergeordneten Knoten des aktuellen Objekts
Leaf_sum // Die Anzahl der Blätter unter allen untergeordneten Knoten des aktuellen Objekts:
bezieht sich auf den aktuellen Knoten, der keine untergeordneten Knoten hat.
Knotenpositionierungsformel:
(1) Der aktuelle Knoten ist der Wurzelknoten
//Die Position der Wurzel
SobjOval.style.left=parseInt(root_left);
SobjOval.style.top=parseInt(root_top);
//Die Funktion der Funktion parseInt() besteht darin, den ganzzahligen Wert anzunehmen. Wenn nicht, ist er NAN
//Die Funktion der Funktion isNaN() besteht darin, zu bestimmen, ob der von parseInt erhaltene Wert eine Ganzzahl ist.
(2) Der aktuelle Knoten ist der linke untergeordnete Knoten des übergeordneten Knotens
1) Die Bedingungen für die Beurteilung sind: Der Name des übergeordneten Knotens des aktuellen Objekts = „iNextYes“
…
2) Wenn es ein rechtes untergeordnetes Blatt gibt, lautet die Formel:
Die linke Seite des aktuellen Knotens = die linke Seite des übergeordneten Knotens – die Gesamtbreite des rechten untergeordneten Blatts des aktuellen Knotens – die Breite des aktuellen Knotens
3) Wenn es kein rechtes untergeordnetes Blatt, aber ein linkes untergeordnetes Blatt gibt , die Formel lautet:
Die linke Seite des aktuellen Knotens = die linke Seite des übergeordneten Knotens – die Gesamtbreite des linken untergeordneten Blatts des aktuellen Knotens
4) Wenn der aktuelle Knoten selbst ein Blatt ist, lautet die Formel:
Die linke Seite des aktuellen Knotens = die linke Seite des übergeordneten Knotens – die Breite des aktuellen Knotens ...
(3) Der aktuelle Knoten ist der rechte untergeordnete Knoten des übergeordneten Knotens
1) Die Bedingungen für die Beurteilung sind: Der Name des übergeordneten Knotens des aktuellen Objekts = „iNextNo“
…
2) Wenn es ein linkes untergeordnetes Blatt gibt, lautet die Formel:
Die linke Seite des aktuellen Knotens = die linke Seite des übergeordneten Knotens + die Gesamtbreite des linken untergeordneten Blatts des aktuellen Knotens + die Breite des aktuellen Knotens.
3) Wenn es kein linkes untergeordnetes Blatt, aber ein rechtes untergeordnetes Blatt gibt , die Formel lautet:
Die linke Seite des aktuellen Knotens = die linke Seite des übergeordneten Knotens + die Gesamtbreite des rechten untergeordneten Blatts des aktuellen Knotens
4) Wenn der aktuelle Knoten selbst ein Blatt ist, lautet die Formel:
Die linke Seite des aktuellen Knotens = die linke Seite des übergeordneten Knotens + die Breite des aktuellen Knotens ...
Die Formeln (2) und (3) ermitteln beide die linke Seite des aktuellen Knotens, und wir müssen auch die Oberseite des aktuellen Knotens ermitteln.
Sehr einfache Formel: Oberseite des aktuellen Knotens = Oberseite des übergeordneten Knotens + Offset (80)
Binärbaumidee (3)
Positionierungsideen für Verbindungsleitungen:
(1) Finden Sie die Positionen des aktuellen Knotens und des übergeordneten Knotens. (2) Bestimmen Sie, ob der aktuelle Knoten der linke untergeordnete Knoten oder der rechte untergeordnete Knoten des übergeordneten Knotens ist. (3) Zeichnen Sie eine Linie
Einige Variablen werden hier definiert.
objOval //Der aktuelle Knoten ist ein Objekt
objParentOval // Der übergeordnete Knoten des aktuellen Objekts ist ein Objekt
objLine //Die aktuelle Zeile ist ein Objekt
Formel zur Zeilenpositionierung:
from="x1,y1" to="x2,y2" ist die Art und Weise, Linien in VML zu positionieren.
Der aktuelle Knoten ist der linke untergeordnete Knoten des übergeordneten Knotens. Die Formel lautet dann:
von = links vom übergeordneten Knoten + Versatz (15), oben vom übergeordneten Knoten + Versatz (32)
to = links + Offset (30) des übergeordneten Knotens, oben - Offset (2) des übergeordneten Knotens.
Der aktuelle Knoten ist der rechte untergeordnete Knoten des übergeordneten Knotens, dann lautet die Formel:
von = links vom übergeordneten Knoten + Offset (35), oben vom übergeordneten Knoten + Offset (32)
bis = links vom übergeordneten Knoten + Versatz (20), oben vom übergeordneten Knoten – Versatz (2)
Das ist alles, woran ich denken kann.
Es wäre viel einfacher, wenn wir einfach ein Unternehmensstrukturdiagramm erstellen würden.
Das Folgende ist Cy Youngs Idee, und ich gehe auf seiner Grundlage nur etwas tiefer.
Berechnen Sie zunächst die Anzahl der Knoten auf der untersten Ebene, um die Breite zu erhalten.
Die obere Knotenposition des Knotens sollte dann basierend auf seiner Zugehörigkeit rekursiv berechnet werden.
Die Knoten auf jeder Ebene sollten nach ihrer Zugehörigkeit sortiert werden. Legen Sie zunächst den „Grundwert“ fest. Der linke Wert jedes Knotens, der untergeordnete Knoten enthält, entspricht der halben Breite des Knotens besitzt plus den Grundwert.
Nachtrag:
Aus irgendeinem Grund war das Internet in letzter Zeit schlecht. Verbringen Sie mehr Zeit offline als online.
Daher wurde der Code nicht vereinfacht. Tatsächlich gibt es noch viele Funktionen, die verbessert werden müssen, wie zum Beispiel:
Sie müssen ein Rechtsklick-Menü hinzufügen. Das Rechtsklick-Menü enthält die Möglichkeit, neue Knoten zu erstellen, Knotennamen zu ändern, Zuordnungen zu ändern usw. Sie können mit der rechten Maustaste auf jeden Knoten klicken, um das Rechtsklick-Menü dieses Knotens zu öffnen .
erklären:
1) flow2.xml ist eine Datendatei, ich glaube, dass jeder kein Problem haben wird.
2) flow2.xsl ist eine Formatdatei, es gibt mehrere Dinge zu beachten.
(1) Im Skript:
(1) <xsl:value-of select="./iProcess/text()" />;
(2) {./iProcess/text()}
Die Funktionen von (1) und (2) bestehen darin, den Zeichenfolgenwert des durch den Auswahlparameter angegebenen Ausdrucks zurückzugeben.
Ihre Suchbedingungen sind gleich, daher sind auch die zurückgegebenen Werte gleich.
Nur sind ihre Schreibformen je nach Verwendungszweck unterschiedlich.
<xsl:apply-templates select="team" order-by="blue_ID"/>
Beispielsweise möchten wir den folgenden Code generieren
<div name="parameter value">Inhalt</div>
Wir gehen davon aus, dass der Name „name“ und der Parameterwert der Wert des untergeordneten Knotenbuchs unter dem aktuellen Knoten in den XML-Daten ist.
Die erste Möglichkeit, es zu schreiben, besteht darin, zuerst den Attributnamen und dann den Parameterwert hinzuzufügen.
<div>
<xsl:attribute name="name">
<xsl:value-of select="./book/text()"/> </xsl:attribute>
Inhalt
</div>
Die zweite Möglichkeit zum Schreiben besteht darin, den Attributnamen und den Parameterwert direkt hinzuzufügen
<div name="{./book/text()}">Inhalt</div>
Zur spezifischen Verwendung können Sie sich die Beispiele im Code ansehen, den ich geschrieben habe.
XSL ist im offiziellen Standard xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
<xsl:value-of select="./book/text()"/>
Die Funktion lautet: Schreiben Sie einfach seinen Textwert aus und
<xsl:value-of select="./book"/>
Es zeigt seinen Textwert und den Inhalt aller seiner untergeordneten Knoten an.
Sie können es ausprobieren und eines mit untergeordneten Knoten und eines ohne untergeordnete Knoten ausgeben, um zu sehen, ob die angezeigten Ergebnisse gleich sind.
(2) Hinweis:
IE5 unterstützt <tag att="{xpath}"> nicht
Möchte nutzen
<tag><xsl:attribute name="att"><xsl:value-of select="xpath"></xsl:attribute>
muss verwendet werden
xmlns:xsl=" http://www.w3.org/TR/WD-xsl "
<?xml version="1.0" binding="gb2312" ?>
Noch etwas:
Encoding="gb2312" wird dem in den meisten XML-Lehrbüchern angezeigten Code selten hinzugefügt.
Wenn wir Chinesisch in XML verwenden, wird daher ein Fehler gemeldet. Der Grund dafür ist, dass diese Erklärung nicht geschrieben wurde.
Nachwort:
Ich spreche hier von einer Denkweise. Wenn Sie eine Analogie ziehen, ist diese natürlich nützlich.