motivação:
Pensei primeiro em fazer uma árvore binária porque precisava fazer um gráfico de estrutura da empresa. A abordagem anterior era desenhar uma imagem diretamente usando um software gráfico. Parece ótimo, mas você precisa pintar um novo sempre que houver alterações. Por outro lado, a exibição e o layout das linhas nas páginas da web são bastante limitados. A composição tipográfica e o posicionamento com base em dados gerados dinamicamente são muito difíceis e a estética não é satisfatória. Depois de fazer várias tentativas, decidi usar XML+XSL para operações de dados; usar VML para embelezar linhas e usar JAVASCRIPT para posicionar objetos.
Material:
O diagrama de árvore de estrutura do volume XML possui 2 arquivos: flow2.xml e flow2.xsl
Efeito:
Navegue aqui
explicar:
Ideia de árvore binária (1)
<html xmlns:v="urn:schemas-microsoft-com:vml">
<ESTILO>
v:* { COMPORTAMENTO: url(#default#VML) }
</STYLE>
<v:group id="group1" name="group1" coordsize = "100.100">
…
</v:grupo>
Esses são os formatos básicos do VML, por isso não vou explicá-los em detalhes.
XML é uma estrutura em árvore. Quando lemos cada dado, precisamos.
A árvore de dados XML é percorrida. As operações recursivas são uma das vantagens do XSL.
Também decidi usar XSL depois de usar vários outros métodos para realizar operações de travessia e falhei.
<FlowRoot>
<vcTitle>Diagrama de estrutura de árvore binária</vcTitle>
<Autor>Velando</Autor>
<E-mail>[email protected]</E-mail>
<FluxoNode>
<iProcess>1</iProcess>
<vcCourse>Primeiro nó</vcCourse>
<iPróximoSim>
<FluxoNode>
<iProcess>2</iProcess>
<vcCourse>Segundo nó</vcCourse>
<iNextSim>…</iNextSim>
<iNextNo>…</iNextNo>
</FlowNode>
</iNextSim>
<iPróximoNão>
<FluxoNode>
<iProcess>3</iProcess>
<vcCourse>O terceiro nó</vcCourse>
<iNextSim>…</iNextSim>
<iNextNo>…</iNextNo>
</FlowNode>
</iNextNo>
</FlowNode>
</FlowRoot>
A lógica é muito simples. Existem dois nós filhos (2, 3) no nó atual (1).
Basta posicionar o nó 2 e o nó 3 na parte inferior esquerda e inferior direita do nó 1.
Aqui eu uso verde e vermelho para as linhas de conexão dos nós esquerdo e direito, respectivamente, para facilitar a exibição.
Falamos sobre a função recursiva do XSL anteriormente. Para ver cada etapa de exibição detalhada com mais clareza, você só precisa imitar o código a seguir e adicionar uma instrução de alerta.
<xsl:template match="FlowNode">
…
<linguagem SCRIPT="JavaScript1.2">
…
alert('exibir passo a passo');
…
</SCRIPT>
…
</xsl:template>
Depois de assistir a câmera lenta acima, você consegue entender meus pensamentos?
Ideia de árvore binária (2)
Minha ideia é muito simples:
(1) Leia os dados do nó atual e gere um novo objeto usando VML.
Atribua um valor inicial ao objeto (como nome, id, estilo, etc.)
(2) Use o controle de script para posicionar o objeto atual (3) Adicione setas e linhas entre o nó atual e seu nó pai.
(4) Continue a encontrar os nós filhos do nó atual e faça um loop até o final.
Ou seja, todos os nós foram percorridos e a árvore foi gerada.
<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>
Todo o processo recursivo é completado pelos três módulos (modelos) acima.
O primeiro modelo chama os dois modelos a seguir ao corresponder ao modelo de cada nó filho no nó atual e os dois últimos modelos chamam o primeiro modelo durante a execução específica, o que é equivalente a uma função recursiva;
gramática:
Para corresponder os modelos de cada nó filho no nó atual, use o formato base do elemento <xsl:apply-templates />.
Caso contrário, o nó correspondente será determinado pelo valor da expressão XPath no parâmetro select, como <xsl:apply-templates select="./FlowNode" />
As funções de (1) e (2) devem retornar o valor da string da expressão dada pelo parâmetro select.
Suas condições de pesquisa são as mesmas, portanto os valores retornados também são os mesmos.
Acontece que suas formas de escrita são diferentes dependendo das ocasiões em que são usadas.
(1) <xsl:valor-de select="./iProcess/text()" />
(2) {./iProcess/text()}
Algumas variáveis são definidas aqui, e o posicionamento do nó é baseado nessas variáveis para chamar a fórmula de cálculo.
root_left //A margem esquerda da raiz = a largura alocada de todas as folhas (y*10) + a largura de todas as folhas (y*50) + o valor básico da margem esquerda (10)
root_top //A margem superior da raiz = o valor básico da margem superior (10)
objOval //O objeto atual é um objeto
objOval_iProcess //Valor do passo do objeto atual
objParentOval //O nó pai do objeto atual é um objeto
objParentOval_iProcess //O valor da etapa do nó pai do objeto atual
objParent_name //O nome do nó pai do objeto atual
Leaf_left //O número de folhas à esquerda entre todos os nós filhos do objeto atual
Leaf_right //O número de folhas à direita entre todos os nós filhos do objeto atual
Leaf_sum //O número de folhas entre todos os nós filhos do objeto atual
Leaf: refere-se ao nó atual sem nós filhos.
Fórmula de posicionamento do nó:
(1) O nó atual é o nó raiz
//A posição da raiz
SobjOval.style.left=parseInt(root_left);
SobjOval.style.top=parseInt(root_top);
//A função da função parseInt() é pegar o valor inteiro, caso contrário, será NAN
//A função da função isNaN() é determinar se o valor obtido por parseInt é um número inteiro.
(2) O nó atual é o nó filho esquerdo do nó pai
1) As condições para julgamento são: O nome do nó pai do objeto atual=’iNextYes’
…
2) Se houver uma folha filha certa, a fórmula é:
A esquerda do nó atual = a esquerda do nó pai - a largura total da folha filha direita do nó atual - a largura do nó atual
3) Se não houver nenhuma folha filha direita, mas houver uma folha filha esquerda , a fórmula é:
A esquerda do nó atual = a esquerda do nó pai - a largura total da folha filha esquerda do nó atual
4) Se o próprio nó atual for uma folha, a fórmula é:
A esquerda do nó atual = a esquerda do nó pai - a largura do nó atual...
(3) O nó atual é o nó filho direito do nó pai
1) As condições para julgamento são: O nome do nó pai do objeto atual=’iNextNo’
…
2) Se houver uma folha filha esquerda, a fórmula é:
A esquerda do nó atual = a esquerda do nó pai + a largura total da folha filha esquerda do nó atual + a largura do nó atual
3) Se não houver nenhuma folha filha esquerda, mas houver uma folha filha direita , a fórmula é:
A esquerda do nó atual = a esquerda do nó pai + a largura total da folha filha direita do nó atual
4) Se o próprio nó atual for uma folha, a fórmula é:
A esquerda do nó atual = a esquerda do nó pai + a largura do nó atual...
As fórmulas (2) e (3) ficam à esquerda do nó atual e também precisamos chegar ao topo do nó atual.
Fórmula muito simples: topo do nó atual = topo do nó pai + deslocamento (80)
Ideia de árvore binária (3)
Idéias de posicionamento para linhas de conexão:
(1) Encontre as posições do nó atual e do nó pai (2) Determine se o nó atual é o nó filho esquerdo ou o nó filho direito do nó pai (3) Desenhe uma linha
Algumas variáveis são definidas aqui.
objOval //O nó atual é um objeto
objParentOval //O nó pai do objeto atual é um objeto
objLine //A linha atual é um objeto
Fórmula de posicionamento de linha:
from="x1,y1" to="x2,y2" é a forma de posicionar as linhas no VML.
O nó atual é o nó filho esquerdo do nó pai, então a fórmula é:
de = esquerda + deslocamento do nó pai (15), topo + deslocamento do nó pai (32)
to = left + offset (30) do nó pai, top - offset (2) do nó pai
O nó atual é o nó filho direito do nó pai, então a fórmula é:
from = esquerda do nó pai + deslocamento (35), topo do nó pai + deslocamento (32)
para = esquerda do nó pai + deslocamento (20), topo do nó pai - deslocamento (2)
Isso é tudo que consigo pensar.
Seria muito mais simples se fizéssemos apenas um gráfico de estrutura da empresa.
O que se segue é a ideia de Cy Young, e estou apenas me aprofundando um pouco mais com base nele.
Primeiro calcule o número de nós no nível inferior para obter a largura,
A posição superior do nó deve então ser calculada com base em sua afiliação, recursivamente.
Os nós em cada nível devem ser classificados de acordo com sua afiliação. Primeiro, defina o "valor básico" = o nó deve ser deslocado para a direita. O valor esquerdo de cada nó contendo nós filhos é igual à metade da largura do nó. possui mais o valor básico.
Pós-escrito:
Por algum motivo, a Internet tem estado ruim recentemente. Passe mais tempo offline do que online.
Portanto, o código não foi simplificado. Na verdade, ainda existem muitas funções que precisam ser melhoradas, como:
Você precisa adicionar um menu do botão direito. O menu do botão direito contém a capacidade de criar novos nós, modificar nomes de nós, alterar associações, etc. Você pode clicar com o botão direito em cada nó para abrir o menu do botão direito deste nó. .
explicar:
1) flow2.xml é um arquivo de dados, acredito que todos não terão problemas.
2) flow2.xsl é um arquivo de formato, há várias coisas para prestar atenção.
(1) No script:
(1) <xsl:value-of select="./iProcess/text()" />;
(2) {./iProcess/text()}
As funções de (1) e (2) devem retornar o valor da string da expressão dada pelo parâmetro select.
Suas condições de pesquisa são as mesmas, portanto os valores retornados também são os mesmos.
Acontece que suas formas de escrita são diferentes dependendo das ocasiões em que são usadas.
<xsl:apply-templates select="team" order-by="blue_ID"/>
Por exemplo, queremos gerar o seguinte código
<div name="parameter value">Conteúdo</div>
Assumimos que o nome é "nome" e o valor do parâmetro é o valor do livro do nó filho no nó atual nos dados XML.
A primeira maneira de escrevê-lo é adicionar primeiro o nome do atributo e depois o valor do parâmetro.
<div>
<xsl:nome do atributo="nome">
<xsl:value-of select="./book/text()"/> </xsl:attribute>
contente
</div>
A segunda maneira de escrever é adicionar diretamente o nome do atributo e o valor do parâmetro
<div name="{./book/text()}">Conteúdo</div>
Para uso específico, você pode ver os exemplos no código que escrevi.
XSL está no padrão oficial xmlns:xsl=" http://www.w3.org/1999/XSL/Transform "
<xsl:value-of select="./book/text()"/>
A função é: basta escrever seu valor de texto e
<xsl:valor-de select="./book"/>
Ele exibe seu valor de texto e o conteúdo de todos os seus nós filhos.
Você pode experimentá-lo e gerar um com nós filhos e outro sem nós filhos para ver se os resultados exibidos são os mesmos.
(2) Nota:
IE5 não suporta <tag att="{xpath}">
Quer usar
<tag><xsl:attribute name="att"><xsl:value-of select="xpath"></xsl:attribute>
precisa ser usado
xmlns:xsl=" http://www.w3.org/TR/WD-xsl "
<?xml version="1.0" encoding="gb2312" ?>
Mais uma coisa:
Encoding="gb2312" raramente é adicionado ao código mostrado na maioria dos livros XML.
Portanto, quando usamos chinês em XML, um erro será relatado. O motivo é que esta declaração não foi escrita.
pós-escrito:
O que estou falando aqui é uma maneira de pensar. Se você fizer uma analogia, ela será naturalmente útil.