Las listas de atributos deben ser familiares para todos. Normalmente, la lista de atributos creada con HTML5 es probablemente un menú desplegable y, en muchos casos, la lista desplegable no es lo suficientemente bonita. Intenté usar HT para Web para realizar la función de hacer clic en un botón en la barra de propiedades para abrir un cuadro de selección multifunción y seleccionar los datos entrantes. Creo que la práctica general es relativamente simple y conveniente, así que la compartiré. contigo aquí.
representacioneshttp://www.hightopo.com/demo/propertyEditor/index.html
Implementación de código Mapa de topologíaEn la representación anterior, podemos ver que toda la página está dividida en 3 partes: la parte de topología GraphView a la izquierda, la parte de tabla TableView en la esquina inferior derecha y la parte del atributo PropertyView en la esquina superior derecha. Primero dividimos toda la escena y luego agregamos contenido específico a cada parte:
gv = new ht.graph.GraphView();var tablePane = new ht.widget.TablePane(gv.dm());//Componente del panel de tabla propertyView = new ht.widget.PropertyView(gv.dm());/ /formPane está en propertyView, por lo que primero debe definir var rightView = new ht.widget.SplitView(propertyView, tablePane, 'v', 0.4);// Divide el componente, v se divide en capas superior e inferior, la proporción es 0.4:0.6rightView.getView().style.borderLeft = '1px solid #000';var borderPane = new ht .widget.BorderPane( );//Componente del panel de borde borderPane.setRightView(rightView, 400);//Establecer borderPane El componente derecho es rightView con un ancho de 400borderPane.setCenterView(gv);//Establezca el componente central borderPane en gv borderPane.addToDOM();//Agregue el componente borderPane al cuerpo
Las partes nuevas en el código anterior son todos componentes encapsulados en HT, que son equivalentes a clases. Aquí hay una explicación del componente dividido SplitView. El componente dividido se usa para dividir dos subcomponentes hacia la izquierda y hacia la derecha o hacia arriba y hacia abajo. -Los componentes pueden ser componentes proporcionados por el marco HT, o pueden serlo. Es un componente nativo de HTML. El subcomponente está absolutamente posicionado con la posición como absoluta. Los parámetros en este componente son (componente izquierdo o componente superior, componente derecho o. componente inferior, h significa división izquierda y derecha v Indica la división superior e inferior. El valor predeterminado de la posición de división es 0,5. Si el valor de configuración es 0 ~ 1, se dividirá por porcentaje. Mayor que 1 representa el ancho o alto absoluto del componente izquierdo o superior. Menos de 1 representa el ancho o alto absoluto del componente derecho o del componente inferior); y el componente del panel BorderPane es un contenedor de diseño, que puede colocar subcomponentes en cinco áreas: superior, inferior, izquierda, derecha y centro. Los subcomponentes pueden ser componentes proporcionados por el marco HT o pueden ser componentes nativos HTML. Realice un posicionamiento absoluto para el modo absoluto. Aquí combino SplitView y BorderPane para dividir la escena en tres partes. Finalmente, recuerde agregar el contenedor de diseño final al cuerpo o cualquier etiqueta HTML para que pueda mostrarse en la interfaz. La definición de addToDOM es la siguiente:
addToDOM = function(){ var self = this, view = self.getView(), //Obtener el div subyacente de este componente style = view.style //Obtener el atributo de estilo del div subyacente document.body.appendChild( view) ; //Agrega el div subyacente al cuerpo style.left = '0'; //HT define de forma predeterminada los componentes para determinar el posicionamiento absoluto, por lo que la posición debe establecerse style.right = '0'; arriba = '0'; style.bottom = '0'; window.addEventListener('resize', function () { self.iv(); }, false);
Los componentes HT generalmente están integrados en contenedores como BorderPane, SplitView y TabView. El componente HT más externo requiere que el usuario agregue manualmente el elemento div subyacente devuelto por getView () al elemento DOM de la página. , Cuando cambia el tamaño del contenedor principal, si el contenedor principal son los componentes de contenedor predefinidos de HT, como BorderPane y SplitView, el contenedor HT llamará automáticamente a la función de invalidación del componente secundario de forma recursiva para notificar la actualización. Pero si el contenedor principal es un elemento html nativo, el componente HT no puede saber que necesita ser actualizado. Por lo tanto, el componente HT más externo generalmente necesita escuchar el evento de cambio de tamaño de la ventana y llamar a la función de invalidación del más externo. componente a actualizar.
Se crea la escena. Para mostrar las diferencias en los atributos correspondientes a diferentes nodos, agregamos siete nodos al mapa de topología:
function initModel(){ var nombre = dispositivo; var cuenta = 0; var raíz = createNode(nombre + cuenta++, nombre + (++cuenta));// El parámetro 1 es el nombre, el parámetro 2 es la etiqueta root.setImage('. /symbols/sala de computadoras/server.json'); root.setName('servidor'); root.s('label.position', 3); gv.sm().ss(root);//El nodo raíz se selecciona de forma predeterminada para (var i = 0; i < 2; i++) { var iNode = createNode(name + count++, name + (++count) );/ /El parámetro 1 es el nombre, el parámetro 2 es la etiqueta createEdge(root, iNode); for (var j = 0; j < 2; j++) { var jNode = createNode(name + count++, name + (++cuenta)); crearEdge(iNode, jNode);
La declaración de la función createNode es la siguiente:
función createNode(nombre, etiqueta){//Crear nodo nodo flag++; var node = new ht.Node(); node.setName(nombre); node.setTag(etiqueta); / XX subsistema.json'); nodo.a('oculto', false);// Atributos personalizados, puede controlar node.a('hidden') para controlar la visibilidad de los nodos node.a('Tipo de interfaz', 'SATA'); node.a('Tarjeta gráfica', 'Nvidia). ') ; if(flag % 2 === 0){ node.a('tipo de interfaz', 'IDE'); node.a('tarjeta gráfica', 'ATI'); posición', 11); gv.dm().add(node);//Agregar nodos al contenedor de datos DataModel node.tablePane1 = createTableView(serviceType, dataModel1);//Crear un panel de tabla node.tablePane2 = createTableView(serviceSize, dataModel2); tablePane3 = createTableView(versión, dataModel3); node.formPane1 = createFormPane(node.tablePane1);//Crear un panel de formulario node.formPane1.title = 'Type';//Para preparar el título del cuadro de diálogo posterior node.formPane2 = createFormPane(node.tablePane2); título = 'Memoria'; node.formPane3 = createFormPane(node.tablePane3.title = 'Modelo'; if(flag % 3 === 0){ node.formPane3.v('etiqueta', 'Lenovo Server X3650M5 8871'); }else{ node.formPane3.v('etiqueta', 'Lenovo IBM X3250 5458I21'); } node.a('modelo', node.formPane3.v('etiqueta')); nodo de retorno;}
Controlamos la visibilidad del nodo controlando el atributo oculto de este nodo y usando la función de filtro visual setVisibleFunc en GraphView:
gv.setVisibleFunc(function(data){ if(data.a('hidden')){ return false; } return true;});Panel de propiedades
Con los nodos, es natural mostrar atributos junto con los valores en el panel de tabla tablePane a continuación, se agregan un total de siete atributos:
function createProperty(){//Crear propiedades propertyView.addProperties([ { name: 'name',// Obtenga el atributo de nombre, combinado con el atributo accessType para finalmente lograr el acceso a los atributos del nodo. El valor predeterminado de accessType es nulo, como Como el nombre es edad, use el método get/set o is/set de getAge() y setAge(98) para acceder (el nombre aquí es el nombre, así que consígalo a través de getName()) displayName: 'Nombre'//Establece el valor del texto para mostrar del nombre del atributo}, { nombre: 'oculto',//Obtiene el atributo oculto displayName: 'Ocultar este nodo', accessType: 'attr',//Si el nombre está oculto, use getAttr('hidden') y setAttr('hidden', false) para acceder al ícono: 'images/alert.gif', //Establezca el tipo de valor del ícono que se muestra en el lado izquierdo del nombre del atributo: 'boolean', //Se utiliza para solicitar al componente que proporcione un renderizador adecuado que represente el tipo booleano, que se muestra como una casilla de verificación editable: true //Establece si la propiedad es editable}, { name: 'grade', displayName: 'Type' , accessType: 'attr', drawPropertyValue: function(g, property, value, rowIndex, x, y, w, h, data, view){// Función de representación del valor del atributo personalizado var cb = function(v) { data.a('grado', v); } return fillFormPane(data.formPane1, w, h, data.tablePane1, serviceType, cb); { nombre: 'número', displayName: 'memoria', accessType: 'attr', drawPropertyValue: función(g, propiedad, valor, índice de fila, x, y, w, h, datos, vista){ var cb = función(v) { data.a('número', v); } return fillFormPane(data.formPane2, w, h, data.tablePane2, serviceSize, cb); { nombre: 'Tipo de interfaz', tipo de acceso: 'attr', nombre de visualización); : 'Tipo de interfaz' }, { nombre: 'Tarjeta gráfica', tipo de acceso: 'atributo', nombre de visualización: 'Tarjeta gráfica' }, { nombre: 'Modelo', tipo de acceso: 'atributo', mostrarNombre: 'Modelo', } ]);}
El valor de retorno del atributo drawPropertyValue en los atributos tercero y cuarto es la función fillFormPane. Los parámetros de esta función son (componente de formulario formP, ancho del componente de formulario w, alto del componente de formulario h, haga clic en el botón del componente de formulario para generar la tabla. componente tableP en el cuadro emergente, el contenido de la matriz está en el componente de tabla, la función cb asigna el valor devuelto al hacer doble clic en la fila del componente de tabla al cuadro de texto ht.widget.TextField en el formulario).
El primer parámetro formP es la creación del componente de formulario. La creación del componente de formulario es crear un componente de formulario y agregar un cuadro de texto y un botón al componente de formulario. Este paso también es bastante simple en HT:
function createFormPane(tPane) {//Crear un panel de formulario var formPane = new ht.widget.FormPane(); formPane.setPadding(0);//Establecer el espacio alrededor del formulario y el contenido del componente var tField = new ht.widget.TextField();//Crea un cuadro de texto tField.setText('');//El contenido del cuadro de texto está vacío tField.setDisabled(true);//El cuadro de texto no está operativo formPane.addRow( [// Agregue una fila al formulario { id: 'tag', // El atributo de identificación único se puede obtener a través de formPane.getItemById (id) y agregarlo al elemento de objeto del elemento correspondiente: tField//El valor del atributo puede ser elementos nativos HTML, información de texto autodibujada dentro de FormPane y componentes integrados de HT como Button, CheckBox y ComboBox, etc.}, {botón:{//Después de configurar este atributo, HT se construirá automáticamente en función del valor del atributo ht.widget.Button objeto y se guardará en la etiqueta del atributo del elemento:'...',//El contenido del texto en el botón onClicked: function(){//Evento de clic de botón para(var yo = 0; yo < tPane.dm().size(); i++){//Establezca tablePane para seleccionar el valor correspondiente a formPane de forma predeterminada var data = tPane.dm().getDatas().get(i); 'valor' ) === formPane.v('etiqueta')){ tPane.sm().ss(data); return createDialog(tPane, formPane);// Lo que se devuelve es crear un cuadro de diálogo, cuyo contenido es el panel de tabla} } }], [0.5, 0.1]);// Establece la relación de visualización del primer elemento y el segundo elemento en el componente de la tabla. Este componente de tabla tiene solo dos elementos en total, un cuadro de texto y un botón, con proporciones de 0,5 y 0,1 respectivamente return formPane;}
El proceso de creación de la función createDialog también es simple y claro. El título, el tamaño, el contenido, etc. del cuadro de diálogo se configuran mediante el método setConfig (config). Pasé un componente de tabla tPane de parámetro a createDialog, que se utiliza como. el contenido que se muestra en el cuadro de diálogo:
función createDialog(tPane){//Crear un cuadro emergente dialog.setConfig({ title: gv.sm().ld().getName()++formPane.title,//El título del contenido del cuadro de diálogo: tPane, // Establece directamente el contenido del cuadro emergente en el ancho del panel de la tabla: 400, // Especifica el ancho del cuadro de diálogo alto: 200, arrastrable: true, // Especifica si el cuadro de diálogo se puede arrastrar y ajustar. closable: true, // Indica si se muestra el botón de cierre. maximizable: true, // Indica si el cuadro de diálogo se puede maximizar. Mueva el mouse a la derecha del cuadro de diálogo. El tamaño del cuadro de diálogo se puede cambiar en la esquina inferior, lo que significa que se pueden ajustar el ancho y el alto botones: [//Agregar dos botones {etiqueta: 'Cancelar', acción: función(){ dialog.hide() } }, { etiqueta: 'OK ', } ] }); dialog.show();//Mostrar cuadro de diálogo}
El cuarto componente de tabla de parámetros tableP no es nada especial. Simplemente crea un componente de formulario y luego agrega columnas al componente de formulario. Los pasos son simples y el código también es bastante simple:
function createTableView(arr, dm){//Crear componente de tabla var tableView = new ht.widget.TableView(dm); tableView.addColumns([//Agregar información de columna en lotes usando parámetros de matriz json{ displayName: 'ID', / /Obtener el contenido del nombre de la columna del encabezado de la tabla drawCell: function(g, data, selected, column, x, y, w, h, tableView){//Método de representación de celda personalizado var id = tableView.getRowIndex(data);//Devuelve el índice de fila donde se encuentra el objeto de datos ht.Default.drawText(g, 'row' + (id + 1), null, null, x, y, w, h, 'center');//Parámetros de texto de dibujo (g objeto de pincel, valor del contenido del texto, fuente del texto, color del texto, coordenada x cuando comienza el dibujo, coordenada y cuando el dibujo comienza en y, ancho cuando se dibuja w, alto cuando se dibuja h , alinear la alineación horizontal del texto, vAlinear la alineación vertical del texto) } }, { displayName: 'Nombre', 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, null, x, y, w, h, 'center'); }
Después de explicar los parámetros en fillFormPane, echemos un vistazo a cómo se define esta función. Básicamente, el último paso es hacer clic en el elemento en el componente de tabla tablePane y devolver este elemento al cuadro de texto textField en el componente de formulario formPane:
función fillFormPane(formP, w, h, tableP, arr, cb){//formpane a la derecha if(formP === indefinido){ return } formP.setWidth(w); setHGap (0); if(formP.v('etiqueta') === 'indefinido' || formP.v('etiqueta') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){//Devolución de llamada cuando se hace doble clic en la fila de datos del componente de la tabla var v = arr[data.a('index) ') ]; formP.v('tag', v);// Establezca el valor del elemento del elemento correspondiente según la identificación, que es la abreviatura de setValue. El elemento con la identificación de la etiqueta es el cuadro de texto dialog.hide(. ); si (cb){cb(v);} //Si se pasa el parámetro cb, establezca el valor de data.a('number')/data.a('helloName') al valor de la fila en la que se hizo doble clic en la tabla, es decir, asignado al tercer y cuarto atributo} tableP.onDataClicked = function(data){//Callback dialog.getConfig().buttons[1].action = cuando se hace clic en la fila de datos en el componente de la tabla function(){//Haga clic en Aceptar para continuar con las siguientes operaciones var v = arr[data.a('index')]; formP.v('tag', v dialog.hide(); { cb(v);} } }; devolver formularioP.getView();}
función fillFormPane(formP, w, h, tableP, arr, cb){//formpane a la derecha if(formP === indefinido){ return } formP.setWidth(w); setHGap (0); if(formP.v('etiqueta') === 'indefinido' || formP.v('etiqueta') === '') { formP.v('tag', arr[0]); } tableP.onDataDoubleClicked = function(data){//Devolución de llamada cuando se hace doble clic en la fila de datos del componente de la tabla var v = arr[data.a('index) ') ]; formP.v('tag', v);// Establezca el valor del elemento del elemento correspondiente según la identificación, que es la abreviatura de setValue. El elemento con la identificación de la etiqueta es el cuadro de texto dialog.hide(. ); si (cb){cb(v);} //Si se pasa el parámetro cb, establezca el valor de data.a('number')/data.a('helloName') al valor de la fila en la que se hizo doble clic en la tabla, es decir, asignado al tercer y cuarto atributo} tableP.onDataClicked = function(data){//Callback dialog.getConfig().buttons[1].action = cuando se hace clic en la fila de datos en el componente de la tabla function(){//Haga clic en Aceptar para continuar con las siguientes operaciones var v = arr[data.a('index')]; formP.v('tag', v dialog.hide(); { cb(v);} } }; devolver formularioP.getView();}
La visualización de la barra de propiedades en la parte superior derecha termina aquí. El panel de la tabla en la parte inferior derecha se crea de la misma manera. Puede leer el código para comprenderlo usted mismo.
diseño automáticoFinalmente, hablemos de la disposición de los nodos en toda la interfaz. El componente de diseño automático de diseño automático en HT proporciona múltiples tipos de algoritmos para organizar automáticamente las posiciones de los nodos en función de la relación entre los nodos y las conexiones. El diseño automático se utiliza a menudo en escenas donde hay muchos elementos gráficos o relaciones de conexión complejas, lo que dificulta arrastrarlos y colocarlos manualmente. Presento cada método de diseño a través de botones. Haga clic en el botón correspondiente y el método de diseño se distribuirá automáticamente de acuerdo con el método de diseño establecido por el botón presionado:
Primero, cree una nueva instancia, pase el objeto que necesita diseño automático, que puede ser DataModel, GraphView y Graph3dView, y luego configure el método de diseño predeterminado:
autoLayout = new ht.layout.AutoLayout(gv);setTimeout(function(){ layout('towardsouth', true);// Porque antes de cargar la imagen, el diseño automático se presenta de acuerdo con el tamaño predeterminado del nodo} , 200);
Luego cree un panel de formulario formPane, agréguelo al cuerpo y colóquelo en la esquina superior izquierda del cuerpo. No pegaré todo el código, solo mostraré el botón del primer diseño:
function createDirectionForm(){ var form = new ht.widget.FormPane(); form.setWidth(200);//Establece el ancho del formulario form.setHeight(80); formulario .getView().style.background = '#fff'; form.getView().style.boxShadow = '4px 16px 16px rgba(0, 0, 0, 0.1)';//Establecer el estilo de sombra form.addRow([//Esta línea se toma por separado como título {elemento: 'Auto Layout:',//Texto mostrado}] , [0.1]);// Solo hay un objeto en la matriz, simplemente establezca el ancho de un objeto form.addRow([ { botón: { icono: 'Layout/South Layout.json', onClicked: function(){ diseño('hacia el sur', verdadero); }, fondo: nulo, labelColor: '#fff', groupId: 'btn', información sobre herramientas: 'diseño sur', borderColor: nulo } }, //.. . .A continuación agregue los 6 botones restantes], [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]);//Hay siete objetos en la matriz, por lo que se debe establecer el ancho de los siete objetos return form;}
Estas son las partes más interesantes. Gracias a todos por leer. Espero que sea útil para su estudio. También espero que todos apoyen a VeVb Martial Arts Network.