dynamischen tree erzeugen

worst_case

Grünschnabel
Hallo,

um mein Programm noch zu optimieren möchte ich gerne eine CSV Datei einlesen und ein tree damit erzeugen.
Datei öffnen und Inhalt auf Variable einlesen habe ich schon.
Das auswerten der Datei und das schreiben mit dokument.write sollte auch kein Problem sein.
Meine Fragen
- wie erstelle ich ein tree an einer bestimmten Stelle im aktuell geöffnetem Dokument.
- wie kann ich das "alte" (vorher geschriebene) tree löschen um ein neues zu erzeugen
(Datei öffnen -> tree erzeugen. wieder Datei öffnen -> tree löschen -> tree erzeuegen)
- gibt es eine einfache Möglichkeit (ohne Schleife) um einen bestimmten Container zu finden. So nach dem Motto ->
Code:
if (exist.container("M1") then

Fragen über Fragen :D

Gruß
worst_case
 
Hi worst_case,
hier gibt es auch wieder ein paar Ansätze. Schau Dir auf jedenfall das Template Guide auf MDN an.
Nachteil der Templates ist, dass nur RDF, XML und SQLite als "datasource" verwenden, das heisst du müsstest dein CSV in z.b. RDF umwandeln. SQLite als datasource wäre angebracht, allerdings kann man damit keine hierarchische Trees erstellen. Hierarchische Trees sind afaik nur mit RDF möglich.

Zu deinen eigentlichen Fragen:
  • Einen tree kannst Du mit var t = document.createElement('tree') erstellen. Der erstellte tree ist aber erst sichtbar, wenn das Element auch "eingefügt" wurde, z.b. mit .appendChild(t).
  • Siehe .removeChild um Elemente/trees zu löschen. Es sind auch Beispiele dabei. Unter anderem auch eines, welches nur den Inhalt eines Elements löscht. Das wäre vielleicht besser als den ganzen tree zu löschen?
  • Um einen bestimmten Container zu finden musst Du wohl selbst eine Funktion erstellen. Entweder mit Schleife und .childNodes oder Du erstellst parrallel zum tree ein Array, in welchem die Container eingetragen sind. Dann einfach mit if (containersArray.indexOf("M1")!= -1) { ... } prüfen, ob der Container zuvor im tree erstellt wurde.
Am besten ist Du liest einige Kapitel im XUL Tutorial durch. Z.b. Modifying a XUL Interface.

Viele Grüße
 
Hallo und Danke für die schnelle Antwort,

ich habe mir einmal "createElement" angesehen. Das wären schon einige Zeilen Code um den tree mit allen Attributen zu erstellen. Nebenbei weiß ich nicht wo der tree genau im Dokument plaziert/erzeugt wird ?

Ich habe nun etwas rumgespielt und bin auf innerHTML gestoßen. Hier weiß ich nicht ob dies überhaupt auch in XML funktioniert.
Meine Idee/Test wären nun
Code:
<tree id="my-tree" flex="1" hidecolumnpicker="false" seltype="single" class="tree" rows="5" onselect="treeRowClicked()">
<treecols>
<treecol primary="true" flex="2" label="Anlage" persist="width" ordinal="1"/>
<splitter class="tree-splitter" ordinal="2"/>
</treecols>
<treechildren id="insert">

</treechildren>
</tree>

und dann mit
Code:
 document.getElementById("insert").innerHTML = ""<treeitem container='true' open='true'>.....";
die passenden zeilen einfügen. Diese könnte ich auch leicht löschen. (Ich muss immer alles löschen, bevor eine neue Datei eingelesen wird)

Mein Vorteil wäre die bessere Übersicht, sowie das einfache ändern/hinzufügen von Code für z.B. Attribute im Tree, sowie das positionieren des tree schon zur Entwicklungszeit. Das Grundgerüst wird in die XUL schon eingetragen.

Wie denkt Ihr/Du darüber
worst_case
 
Abend,

ich habe nun "createElement" probiert.
Hier komme ich aber nicht auf meinen Tree bzw. Verschachtelung.
Ich bin einfach der Reihe nach meinen statischen Baum durchgegangen.

Vermutlich geht es nicht so einfach wie ich gedacht habe.
Code:
function tree_erzeugen()
{
var adiv = document.getElementById("treepos");
var tree = document.createElement("tree");
    tree.setAttribute("id","my-tree");
    tree.setAttribute("flex","1");
    tree.setAttribute("hidecolumnpicker","false");
    tree.setAttribute("seltype","single");
    tree.setAttribute("class","tree");
    tree.setAttribute("rows","5");
    tree.setAttribute("onselect","treeRowClicked()");
    adiv.appendChild(tree);

var atree = document.getElementById("my-tree");
    atree.appendChild(document.createElement("treecols"));

var treecol = document.createElement("treecol");
    treecol.setAttribute("primary","true");
    treecol.setAttribute("flex","2");
    treecol.setAttribute("label","Anlage");
    treecol.setAttribute("persist","width");
    treecol.setAttribute("ordinal","1");
    atree.appendChild(treecol);

var splitter = document.createElement("splitter");
    splitter.setAttribute("primary","true");
    splitter.setAttribute("class","tree-splitter");
    splitter.setAttribute("ordinal","2");
    atree.appendChild(splitter);

var treechild = document.createElement("treechildren");
    treechild.setAttribute("idprimary","true");
    atree.appendChild(treechild);

    atree.appendChild(document.createElement("treechildren"));

/* hier wiederholen sich die Anlagen */
var treeitem = document.createElement("treeitem");
    treeitem.setAttribute("container","true");
    treeitem.setAttribute("open","true");
    atree.appendChild(treeitem);

    atree.appendChild(document.createElement("treerow"));

var treecell = document.createElement("treecell");
    treecell.setAttribute("label","Z");
    atree.appendChild(treecell);

    atree.appendChild(document.createElement("treechildren"));

/* Hier pro Unterpunkt wiederholen (Varname) */
    atree.appendChild(document.createElement("treeitem"));
    atree.appendChild(document.createElement("treerow"));

    treecell = document.createElement("treecell");
    treecell.setAttribute("label","stoerung_1");
    atree.appendChild(treecell);

    atree.appendChild(document.createElement("treeitem"));
    atree.appendChild(document.createElement("treerow"));

    treecell = document.createElement("treecell");
    treecell.setAttribute("label","stoerung_2");
    atree.appendChild(treecell);

/* hier wiederholen sich die Anlagen */
    treeitem = document.createElement("treeitem");
    treeitem.setAttribute("container","true");
    treeitem.setAttribute("open","true");
    atree.appendChild(treeitem);

    atree.appendChild(document.createElement("treerow"));

    treecell = document.createElement("treecell");
    treecell.setAttribute("label","M1");
    atree.appendChild(treecell);

    atree.appendChild(document.createElement("treechildren"));

/*----------------------------------------*/
    atree.appendChild(document.createElement("treeitem"));
    atree.appendChild(document.createElement("treerow"));

    treecell = document.createElement("treecell");
    treecell.setAttribute("label","stoerung_3");
    atree.appendChild(treecell);

    atree.appendChild(document.createElement("treeitem"));
    atree.appendChild(document.createElement("treerow"));

    treecell = document.createElement("treecell");
    treecell.setAttribute("label","stoerung_4");
    atree.appendChild(treecell);

}

Rauskommen sollte
http://http://www.tutorials.de/xml-technologien/370622-tree-auslesen.html

Danke
worst_case
 
Zuletzt bearbeitet:
Es spricht nichts dagegen das Grundgerüst in dein XUL file zu hinterlegen, es gehört meiner Meinung da sogar hin.

Die Methode innerHTML würde ich nicht verwenden, da es ja createElement, appendChild, ... gibt. Finde es ist übersichtlicher damit einen tree zu erstellen.

Was du also schon teilweise hast / noch benötigst ist eine Funktion fillTree welche die ganzen Einträge aus deiner CSV Datei in den tree einfügt. Hierfür wirst du sicher auf Schleifen zurückgreifen müssen.
Ich vermute mal deine Daten sind ungefähr so aufgebaut:
Code:
Anlage | Störung    | Beschreibung, ...
M1     | stoerung_1 | xyz
Z      | stoerung_2 | asf
Z      | stoerung_3 | asdfff
M1     | stoerung_4 |affff
Vermutlich lädst du die Daten in einen Array/Object, welches du an die fillTree Funktion übergeben kannst, die dann in etwa so aufgebaut werden kann:
Javascript:
function fillTree (stoerungen) {
    var childrenNode = document.getElementById('insert'); // Referenz auf das children Element innerhalb des Baumes.
    var anlagenNodes = []; // Referenzen auf die treechildren Elemente der einzelnen Anlagen

    for (var i = 0; i < stoerungen.length; i++) {
        var stoerung = stoerungen[i];
        var anlage = anlagenNodes[stoerungen['Anlage']];

        if (!anlage) { // Hier das Container Object erstellen, wenn es für diese Anlage noch nicht vorhanden ist
            var item = document.createElement("treeitem");
            item.setAttribute("container","true");
            item.setAttribute("open","true");
            item.setAttribute("label",stoerung['Anlage']);
            childrenNode.appendChild(item ); // An den Baum "hängen"
              
            var treechild = document.createElement("treechildren"); // An dieses Element kommen die ganzen Einträge für die Störungen rein
            treechild.setAttribute("idprimary","true");
            item.appendChild(treechild);
              
            anlageNodes[stoerung['Anlage']] = treechild; // Festhalten, dass die Anlage in den Baum eingefügt wurde
            anlage = treechild;
        }
    
    
        // Ab hier die Einträge der Störungen erstellen
        var item = document.createElement("treeitem");
        item.setAttribute("label",stoerung['Störung']);
        anlage.appendChild(item); // Störung anhängen
    }
}

Schreib den Code besser neu, damit es mit deinen Daten funktioniert.
Viele Grüße
 
Abend Bullja,

vielen Dank, ich habe es soweit hingebogen und ... es läuft genau so wie gewünscht.
Ein Fehler noch.
Die Funktion "treeRowClicked" die vom tree-event onselect="treeRowClicked()" aufgerufen wird.
funktioniert nun nicht mehr.

Im Venkman Debugger stürtzt dieser bei der 1. Zeile
Code:
var tree = document.getElementById ("my-tree");
ab.
d.h. als ich die Tabelle komplett manuell/komplett erzeugt habe funktionierte es.
jetzt beim dynamischen erzeugen des tree bzw. teilweisen erzeugen des tree funktioniert
das "id" nicht mehr.

Das ist mir unerklärlich, was hier das Problem sein könnte. Der Rumpf mit dem Event-Aufruf ist eigentlich gleich geblieben.

Gruß
worst_case
 
Das dürfte so eigentlich nicht passieren. Poste mal deine Funktionen und dein XUL-File, damit man den Fehler rekonstruieren kann.
Gibt Venkman dir noch irgendwelche Meldung zurück, ausser dass es bei der 1. Zeile abstürzt?
 
Hallo,
hier einmal mein XML-Vorlage
Code:
 <tree id="my-tree" flex="1" hidecolumnpicker="false" seltype="single" class="tree" rows="5" onselect="treeRowClicked()">
<treecols>
<treecol primary="true" flex="2" label="Anlage" persist="width" ordinal="1"/>
<splitter class="tree-splitter" ordinal="2"/>
</treecols>
<treechildren id="insert">

</treechildren>
</tree>

zum testen hier mein Array

Code:
var daten = new Array("Z;10;stoerung_32_1;0","Z;10;stoerung_64_33;0","Z;10;meldung_32_1;0","Z;10;meldung_64_33;0",
	    "M1;11;stoerung_32_1;0","M1;11;stoerung_64_33;0","M1;11;meldung_32_1;0","M1;11;meldung_64_33;0",
	    "M2;12;stoerung_32_1;0","M2;12;stoerung_64_33;0","M2;12;meldung_32_1;0","M2;12;meldung_64_33;0");
hier mein Code zum erzeugen des tree
Code:
function tree_erzeugen(zeilenarray)
{
  var childrenNode = document.getElementById('insert'); // Referenz auf das children Element innerhalb des Baumes.
  var anlagenNodes = []; // Referenzen auf die treechildren Elemente der einzelnen Anlagen

    for (var i = 0; i < zeilenarray.length; i++)
    {
        var akt_zeile = zeilenarray[i];

/* wenn die Zeile leer ist oder ein # am Anfang dann nächste Zeile */
	if (akt_zeile.length <= 5 || akt_zeile[0] == '#') 
	continue;

	var zeile_split = akt_zeile.split(";");
        var anlage = anlagenNodes[zeile_split[0]];
 
        if (!anlage)  // Hier das Container Object erstellen, wenn es für diese Anlage noch nicht vorhanden ist
	{
            var item = document.createElement("treeitem");
            item.setAttribute("container","true");
            item.setAttribute("open","true");
            item.setAttribute("label",zeile_split[0]);
            childrenNode.appendChild(item ); // An den Baum "hängen"
              
            var treechild = document.createElement("treechildren"); // An dieses Element kommen die ganzen Einträge für die Störungen rein
            treechild.setAttribute("idprimary","true");
            item.appendChild(treechild);
              
            anlagenNodes[zeile_split[0]] = treechild; // Festhalten, dass die Anlage in den Baum eingefügt wurde
            anlage = treechild;
        }
    
        // Ab hier die Einträge der Störungen erstellen
        var item = document.createElement("treeitem");
        item.setAttribute("label",zeile_split[2]);
        anlage.appendChild(item); // Störung anhängen
    }
}
//----------------------------------------------------------------------------------------------

Wie gesagt, beim dynamischen erzeugen des Array funktioniert das event "onselect" nicht mehr
Es kann nicht mehr mit
Code:
 var tree = document.getElementById ("my-tree");
auf das tree zugegriffen werden.

Danke
worst_case

PS: Venkman stürzt nur Inklusive Firefox ab... keine Meldung
 
Zuletzt bearbeitet:
Wie ich es vermutet hatte, ist der Fehler nicht in Zeile 1, sondern bei "var container = selectedCell.parentNode.parentNode.parentNode.parentNode;".
Du musst diese Funktion natürlich auch anpassen. Erstmals hattest Du diese Elemente:
treeitem -> treerow -> treecell (mit Attribut label). Ich hatte dir dein Javascript Code ohne zu kommentieren abgeändert, so dass nur noch das treeitem erstellt wurde und diesem das Attribute label gegeben wurde. Treerow und treecell benötigt man in deinem Fall nicht, und sind überflüssiger Code.

Da wir einige Element weniger haben, muss .parentNode / .childNodes in deiner Funktion treeRowClicked einige male weniger Male auferufen werden. Einfach abzählen/probieren.
 
Zuletzt bearbeitet:
Hallo,

ich habe nun alles ausser
Code:
 var tree = document.getElementById ("my-tree");
kommentiert leider stürzt Venkman immer noch ab, wenn ich diese Zeile
im Debugger laufen lasse.
Deine Erklärung verstehe ich auch nicht. Wo solle ich .parentNode / .childNodes abzählen ?

Danke
worst_case
 

Neue Beiträge

Zurück