Normalerweise ist die mit HTML5 erstellte Attributliste ein Dropdown-Menü. Und in vielen Fällen ist die Dropdown-Liste nicht hübsch genug. Ich habe versucht, mit HT for Web die Funktion zu realisieren, durch Klicken auf eine Schaltfläche in der Eigenschaftsleiste ein Multifunktionsauswahlfeld aufzurufen und die eingehenden Daten auszuwählen. Ich halte die Vorgehensweise insgesamt für relativ einfach und bequem, daher werde ich sie weitergeben es bei dir hier.
Darstellungenhttp://www.hightopo.com/demo/propertyEditor/index.html
Code-Implementierung TopologiekarteAus dem obigen Rendering können wir erkennen, dass die gesamte Seite in drei Teile unterteilt ist: den GraphView-Topologieteil links, den TableView-Tabellenteil in der unteren rechten Ecke und den PropertyView-Attributteil in der oberen rechten Ecke. Wir teilen zunächst die gesamte Szene auf und fügen dann jedem Teil spezifische Inhalte hinzu:
gv = new ht.graph.GraphView();var tablePane = new ht.widget.TablePane(gv.dm());//Tabellenpanel-Komponente propertyView = new ht.widget.PropertyView(gv.dm());/ /formPane befindet sich in propertyView, daher müssen Sie zunächst var rightView = new ht.widget.SplitView(propertyView, tablePane, 'v', 0.4);//Teilen Sie die Komponente auf, v wird in obere und untere Ebenen unterteilt, das Verhältnis beträgt 0,4:0,6rightView.getView().style.borderLeft = '1px solid #000';var borderPane = new ht .widget.BorderPane( );//Randpanel-Komponente borderPane.setRightView(rightView, 400);//Setze borderPane Die rechte Komponente ist rightView mit einer Breite von 400borderPane.setCenterView(gv);//Setzen Sie die mittlere Komponente von borderPane auf gv borderPane.addToDOM();//Fügen Sie die Komponente von borderPane zum Körper hinzu
Die neuen Teile im obigen Code sind alle HT-gekapselte Komponenten, die den Klassen entsprechen. Hier ist eine Erklärung der SplitView-Split-Komponente. Die Split-Komponente wird verwendet, um zwei Unterkomponenten nach links und rechts oder nach oben und unten zu teilen -Komponenten können Komponenten sein, die vom HT-Framework bereitgestellt werden, oder sie können eine native Komponente von HTML sein. Die Unterkomponente wird absolut mit der Position als absolut positioniert. Die Parameter in dieser Komponente sind (linke Komponente oder obere Komponente, rechte Komponente oder). untere Komponente, h bedeutet linke und rechte Teilung v Gibt die obere und untere Teilung an. Der Standardwert der Teilungsposition beträgt 0 bis 1. Größer als 1 stellt die absolute Breite oder Höhe der linken Komponente dar. Kleiner als 1 stellt die absolute Breite oder Höhe der rechten Komponente oder der unteren Komponente dar; und die BorderPane-Panel-Komponente ist ein Layout-Container, der Unterkomponenten in fünf Bereichen platzieren kann: oben, unten, links, rechts und in der Mitte Die Unterkomponenten können vom HT-Framework bereitgestellte Komponenten oder HTML-native Komponenten sein Führen Sie eine absolute Positionierung für den Absolutmodus durch. Hier kombiniere ich SplitView und BorderPane, um die Szene in drei Teile zu unterteilen. Denken Sie abschließend daran, den endgültigen Layout-Container zum Textkörper oder einem beliebigen HTML-Tag hinzuzufügen, damit er auf der Schnittstelle angezeigt werden kann. Die Definition von addToDOM lautet wie folgt:
addToDOM = function(){ var self = this, view = self.getView(), //Das zugrunde liegende div dieser Komponente abrufen style = view.style //Das style-Attribut des zugrunde liegenden div abrufen document.body.appendChild( view) ; //Fügen Sie das zugrunde liegende Div zum Körper hinzu style.left = '0'; //HT definiert standardmäßig die Komponenten, um die absolute Positionierung zu bestimmen, daher muss die Position festgelegt werden style.right = '0'; oben = '0' ; style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false }
HT-Komponenten sind im Allgemeinen in Container wie BorderPane, SplitView und TabView eingebettet. Die äußerste HT-Komponente erfordert, dass der Benutzer das von getView() zurückgegebene zugrunde liegende div-Element manuell zum DOM-Element der Seite hinzufügt Wenn sich die Größe des übergeordneten Containers ändert und es sich bei dem übergeordneten Container um vordefinierte Containerkomponenten von HT wie BorderPane und SplitView handelt, ruft der HT-Container automatisch rekursiv die Invalidierungsfunktion der untergeordneten Komponente auf, um die Aktualisierung zu benachrichtigen. Wenn der übergeordnete Container jedoch ein natives HTML-Element ist, kann die HT-Komponente nicht wissen, dass er aktualisiert werden muss. Daher muss die äußerste HT-Komponente im Allgemeinen auf das Fenstergrößenänderungsereignis des Fensters hören und die Invalidierungsfunktion der äußersten aufrufen Komponente, die aktualisiert werden soll.
Die Szene ist erstellt. Um die Unterschiede in den Attributen verschiedener Knoten darzustellen, haben wir der Topologiekarte sieben Knoten hinzugefügt:
function initModel(){ var name = device; var count = 0; var root = createNode(name + count++, name + (++count));//Parameter 1 ist name, Parameter 2 ist tag root.setImage('. /symbols/computer room/server.json'); root.setName('server'); root.s('label.position', 3); gv.sm().ss(root);//Der Wurzelknoten ist standardmäßig ausgewählt für (var i = 0; i < 2; i++) { var iNode = createNode(name + count++, name + (++count) );/ /Parameter 1 ist Name, Parameter 2 ist Tag createEdge(root, iNode); for (var j = 0; j < 2; j++) { var jNode = createNode(name + count++, name + (++count)); createEdge(iNode, jNode);
Die Deklaration der Funktion createNode lautet wie folgt:
function createNode(name, tag){//Create Node node flag++; var node = new ht.Node(); node.setImage('./symbols/computer room / XX subsystem.json'); node.a('hidden', false);//Benutzerdefinierte Attribute, Sie können node.a('hidden') steuern, um die Sichtbarkeit von Knoten zu steuern node.a('Schnittstellentyp', 'SATA'); node.a('Grafikkarte', 'Nvidia ') ; if(flag % 2 === 0){ node.a('interface type', 'IDE'); Position', 11); gv.dm().add(node);//Knoten zum Datencontainer hinzufügen DataModel node.tablePane1 = createTableView(serviceType, dataModel1);//Ein Tabellenpanel erstellen node.tablePane2 = createTableView(serviceSize, dataModel2); tablePane3 = createTableView(version, dataModel3); node.formPane1 = createFormPane(node.tablePane1);//Erstellen Sie ein Formularfeld node.formPane1.title = 'Type';//Um den Titel des nachfolgenden Dialogfelds vorzubereiten node.formPane2 = createFormPane(node.tablePane2); node.formPane2. title = 'Speicher'; node.formPane3 = createFormPane(node.tablePane3); if(flag % 3 === 0){ node.formPane3.v('tag', 'Lenovo Server X3650M5 8871'); }else{ node.formPane3.v('tag', 'Lenovo IBM X3250 5458I21 '); } node.a('model', node.formPane3.v('tag')); return node;}
Wir steuern die Sichtbarkeit des Knotens, indem wir das versteckte Attribut dieses Knotens steuern und die visuelle Filterfunktion setVisibleFunc in graphView verwenden:
gv.setVisibleFunc(function(data){ if(data.a('hidden')){ return false; } return true;});Eigenschaftenbereich
Bei Knoten ist es selbstverständlich, Attribute anzuzeigen. Zusammen mit den Werten im TablePane-Tabellenpanel werden insgesamt sieben Attribute hinzugefügt:
Funktion createProperty(){//Eigenschaften erstellen propertyView.addProperties([ { name: 'name',//Rufen Sie das Namensattribut in Kombination mit dem AccessType-Attribut ab, um schließlich Zugriff auf Knotenattribute zu erhalten. Der Standardwert von AccessType ist null, z Da der Name das Alter ist, verwenden Sie die get/set- oder is/set-Methode von getAge() und setAge(98), um auf (Name ist hier Name, also erhalten Sie ihn über getName()) displayName zuzugreifen: 'Name'//Legen Sie den Anzeigetextwert des Attributnamens fest}, { name: 'hidden',//Holen Sie sich das ausgeblendete Attribut displayName: 'Hide this node', accessType: 'attr',//Wenn der Name ausgeblendet ist, Verwenden Sie getAttr( 'hidden') und setAttr('hidden', false), um auf das Symbol zuzugreifen: 'images/alert.gif', //Legen Sie den Symbolwert fest, der auf der linken Seite des Attributnamens angezeigt wird: 'boolean', //Wird verwendet, um die Komponente aufzufordern, einen geeigneten booleschen Renderer-Rendering-Typ bereitzustellen, der als Kontrollkästchen angezeigt wird editierbar: true //Legen Sie fest, ob die Eigenschaft bearbeitbar ist}, { name: 'grade', displayName: 'Type' , accessType : 'attr', drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view){//Benutzerdefinierte Attributwert-Rendering-Funktion var cb = function(v) { data.a('grade', v); } return fillFormPane(data.formPane1, w, h, data.tablePane1, serviceType, cb); 'attr', drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view){ var cb = function(v) { data.a('number', v); } return fillFormPane(data.formPane2, w, h, data.tablePane2, serviceSize, cb); : 'Schnittstellentyp' }, { name: 'Grafikkarte', accessType: 'attr', displayName: 'Grafikkarte' }, { name: 'Model', accessType: 'attr', displayName: 'Modell', } ]);}
Der Rückgabewert des Attributs drawPropertyValue im dritten und vierten Attribut ist die Funktion fillFormPane. Die Parameter dieser Funktion sind (Formularkomponente formP, Formularkomponentenbreite w, Formularkomponentenhöhe h, klicken Sie auf die Schaltfläche in der Formularkomponente, um die Tabelle zu generieren Komponente tableP in der Popup-Box, der Array-Inhalt arr in der Tabellenkomponente, die cb-Funktion weist den durch Doppelklick auf die Zeile in der Tabellenkomponente zurückgegebenen Wert dem Textfeld ht.widget.TextField im Formular zu.
Der erste Parameter formP ist die Erstellung der Formularkomponente. Die Erstellung der Formularkomponente besteht darin, eine Formularkomponente zu erstellen und der Formularkomponente ein Textfeld und eine Schaltfläche hinzuzufügen.
function createFormPane(tPane) {//Ein Formularfeld erstellen var formPane = new ht.widget.FormPane(); formPane.setPadding(0);//Legen Sie den Abstand um das Formular und den Komponenteninhalt fest var tField = new ht.widget.TextField();//Erstelle ein Textfeld tField.setText('');//Der Inhalt des Textfeldes ist leer tField.setDisabled(true);//Das Textfeld ist nicht funktionsfähig formPane.addRow( [// Fügen Sie dem Formular eine Zeile hinzu { id: 'tag', // Das eindeutige Identifikationsattribut kann über formPane.getItemById(id) abgerufen und dem entsprechenden Elementobjektelement hinzugefügt werden: tField//Der Attributwert kann aus nativen HTML-Elementen, selbstgezeichneten Textinformationen in FormPane und integrierten HT-Komponenten wie Button, CheckBox und ComboBox usw. bestehen.}, { button:{//Nach dem Festlegen dieses Attributs wird HT dies tun wird automatisch basierend auf dem Attributwert ht.widget.Button-Objekt erstellt und im Elementattribut label:'...' gespeichert,//Der Textinhalt auf der Schaltfläche onClicked: function(){//Button-Click-Ereignis für(var i = 0; i < tPane.dm().size(); i++){//Setzen Sie tablePane so ein, dass standardmäßig der Wert für formPane ausgewählt wird. var data = tPane.dm().getDatas().get(i); 'value' ) === formPane.v('tag')){ tPane.sm().ss(data } } return createDialog(tPane, formPane);//Was zurückgegeben wird, ist das Erstellen eines Dialogfelds, dessen Inhalt das Tabellenfeld ist} } }], [0,5, 0,1]);//Legen Sie das Anzeigeverhältnis des ersten Elements und des zweiten Elements fest die Tabellenkomponente. Diese Tabellenkomponente hat insgesamt nur zwei Elemente, ein Textfeld und eine Schaltfläche, mit Proportionen von 0,5 bzw. 0,1. return formPane;}
Der Prozess zum Erstellen der createDialog-Funktion ist ebenfalls einfach und klar. Der Titel, die Größe, der Inhalt usw. des Dialogfelds werden über die setConfig(config)-Methode konfiguriert. Ich habe eine Parameter-tPane-Tabellenkomponente an createDialog übergeben, die als verwendet wird Der im Dialogfeld angezeigte Inhalt:
function createDialog(tPane){//Erstellt ein Popup-Fenster. dialog.setConfig({ title: gv.sm().ld().getName()++formPane.title,//Der Titel des Dialogfeldinhalts: tPane, // Setzen Sie den Inhalt des Popup-Felds direkt auf die Breite des Tabellenfelds: 400, // Geben Sie die Breite des Dialogfelds an, Höhe: 200, ziehbar: true, // Geben Sie an, ob das Dialogfeld geschlossen und angepasst werden kann: true, // Gibt an, ob die Schaltfläche zum Schließen maximiert werden soll: true, // Gibt an, ob das Dialogfeld maximiert werden kann. Bewegen Sie die Maus nach rechts neben das Dialogfeld. In der unteren Ecke kann die Größe des Dialogfelds geändert werden. Dies bedeutet, dass die Schaltflächen Breite und Höhe angepasst werden können: [//Fügen Sie zwei Schaltflächen hinzu { Beschriftung: 'Abbrechen', Aktion: function(){ dialog.hide() } }, { label: 'OK ', } ] }); dialog.show();//Dialogfeld anzeigen}
Die Tabellenkomponente des vierten Parameters tableP ist nichts Besonderes. Sie erstellt lediglich eine Formularkomponente und fügt der Formularkomponente dann Spalten hinzu. Die Schritte sind einfach und der Code ist auch recht einfach.
function createTableView(arr, dm){//Tabellenkomponente erstellen var tableView = new ht.widget.TableView(dm); tableView.addColumns([//Spalteninformationen stapelweise mit JSON-Array-Parametern hinzufügen{ displayName: 'ID', / /Den Spaltennameninhalt des Tabellenkopfes abrufen drawCell: function(g, data, selected, columns, x, y, w, h, tableView){//Angepasste Zellrendering-Methode var id = tableView.getRowIndex(data);//Gibt den Zeilenindex zurück, in dem sich das Datenobjekt befindet ht.Default.drawText(g, 'row' + (id + 1), null, null, x, y, w, h, 'center');//Zeichnungstextparameter (g Pinselobjekt, Wert Textinhalt, Schriftart Textschriftart, Farbe Textfarbe, X-Koordinate beim Zeichnen beginnt, Y-Koordinate beim Zeichnen auf Y, Breite beim Zeichnen auf W, Höhe beim Zeichnen auf H , Text horizontal ausrichten, vText vertikal ausrichten) } }, { displayName: 'Name', drawCell: function(g, data, selected, Column, x, y, w, h, tableView){ var id = tableView.getRowIndex(data); var info = arr[id]; ht.Default.drawText(g, info, null, x, y, w, h, 'center'); }
Nachdem wir die Parameter in fillFormPane erklärt haben, schauen wir uns an, wie diese Funktion definiert ist. Im Grunde besteht der letzte Schritt darin, auf das Element in der Tabellenkomponente „tablePane“ zu klicken und dieses Element in das Textfeld „textField“ in der Formularkomponente „formPane“ zurückzugeben:
function fillFormPane(formP, w, h, tableP, arr, cb){//formpane on the right if(formP === undefiniert){ return; formP.setHeight(h); setHGap (0); if(formP.v('tag') === 'undefiniert' || formP.v('tag') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){//Rückruf, wenn auf die Datenzeile in der Tabellenkomponente doppelgeklickt wird var v = arr[data.a('index ') ]; formP.v('tag', v);//Setzen Sie den entsprechenden Elementelementwert gemäß der ID, die die Abkürzung von setValue ist. Das Element mit der ID von tag ist das Textfeld dialog.hide( ); Wenn (cb){cb(v);} //Wenn der cb-Parameter übergeben wird, setzen Sie den Wert von data.a('number')/data.a('helloName') auf den Wert der doppelt angeklickten Zeile in der Tabelle, also dem dritten und vierten Attribut zugewiesen} tableP.onDataClicked = function(data){//Callback dialog.getConfig().buttons[1].action = wenn auf die Datenzeile in der Tabellenkomponente geklickt wird function(){//Klicken Sie auf OK, um mit den folgenden Vorgängen fortzufahren var v = arr[data.a('index')]; formP.v('tag', v); { cb(v);} } }; return formP.getView();}
function fillFormPane(formP, w, h, tableP, arr, cb){//formpane on the right if(formP === undefiniert){ return; formP.setHeight(h); setHGap (0); if(formP.v('tag') === 'undefiniert' || formP.v('tag') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){//Rückruf, wenn auf die Datenzeile in der Tabellenkomponente doppelgeklickt wird var v = arr[data.a('index ') ]; formP.v('tag', v);//Setzen Sie den entsprechenden Elementelementwert gemäß der ID, die die Abkürzung von setValue ist. Das Element mit der ID von tag ist das Textfeld dialog.hide( ); Wenn (cb){cb(v);} //Wenn der cb-Parameter übergeben wird, setzen Sie den Wert von data.a('number')/data.a('helloName') auf den Wert der doppelt angeklickten Zeile in der Tabelle, also dem dritten und vierten Attribut zugewiesen} tableP.onDataClicked = function(data){//Callback dialog.getConfig().buttons[1].action = wenn auf die Datenzeile in der Tabellenkomponente geklickt wird function(){//Klicken Sie auf OK, um mit den folgenden Vorgängen fortzufahren var v = arr[data.a('index')]; formP.v('tag', v); { cb(v);} } }; return formP.getView();}
Die Anzeige der Eigenschaftsleiste oben rechts wird auf die gleiche Weise erstellt. Sie können den Code lesen, um ihn selbst zu verstehen.
AutolayoutLassen Sie uns abschließend über die Anordnung der Knoten in der gesamten Schnittstelle sprechen. Die automatische Layoutkomponente Autolayout in HT bietet mehrere Arten von Algorithmen, um Knotenpositionen basierend auf der Beziehung zwischen Knoten und Verbindungen automatisch anzuordnen. Das automatische Layout wird häufig in Szenen verwendet, in denen viele Grafikelemente oder komplexe Verbindungsbeziehungen vorhanden sind, was das manuelle Ziehen und Platzieren dieser Elemente erschwert. Ich präsentiere jede Layout-Methode über Schaltflächen. Klicken Sie auf die entsprechende Schaltfläche, und die Layout-Methode wird automatisch entsprechend der durch die gedrückte Schaltfläche festgelegten Layout-Methode angeordnet:
Erstellen Sie zunächst eine neue Instanz, übergeben Sie das Objekt, das ein automatisches Layout benötigt, das DataModel, graphView und graph3dView sein kann, und legen Sie dann die Standardlayoutmethode fest:
autoLayout = new ht.layout.AutoLayout(gv);setTimeout(function(){ layout('towardsouth', true);//Da vor dem Laden des Bildes das automatische Layout entsprechend der Standardgröße des Knotens angelegt wird} , 200);
Erstellen Sie dann ein formPane-Formularfeld, fügen Sie es dem Körper hinzu und platzieren Sie es in der oberen linken Ecke des Körpers. Ich werde nicht den gesamten Code einfügen, sondern nur die Schaltfläche des ersten Layouts anzeigen:
function createDirectionForm(){ var form = new ht.widget.FormPane(); form.setWidth(200);//Setze die Formularbreite form.setHeight(80); form .getView().style.background = '#fff'; form.getView().style.boxShadow = '4px 16px 16px rgba(0, 0, 0, 0.1)';//Setzen Sie den Schattenstil form.addRow([//Diese Zeile wird separat als Titel herausgenommen { element: 'Auto Layout:',//Angezeigter Text}] , [0.1]);//Es gibt nur ein Objekt im Array, legen Sie einfach die Breite eines Objekts fest form.addRow([ { button: { icon: 'Layout/South Layout.json', onClicked: function(){ Layout('towardsouth', true); }, Hintergrund: null, LabelColor: '#fff', GroupId: 'btn', ToolTip: 'south Layout', BorderColor: null } }, //.. . .Als nächstes fügen Sie die restlichen 6 Tasten hinzu], [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]);//Es gibt sieben Objekte im Array, daher muss die Breite der sieben Objekte festgelegt werden. return form;}
Dies sind die interessanteren Teile. Ich hoffe, dass es für Ihr Studium hilfreich ist. Ich hoffe auch, dass jeder das VeVb Martial Arts Network unterstützt.