Você está na página 1de 23

06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

14.576.496 membros assinar em

Search for articles, questions,

artigos Respostas rápidas discussões recursos comunidade Socorro


Q&A forums stuff lounge ?

Criando diagramas surpreendentes usando Angular e


SVG
Michael Gledhill Classifique isto: 5.00 (14 votos)
22 nov 2019 CPOL

Um exemplo de uso de Angular e SVG para transformar seus dados em belos diagramas

Download do código fonte - 1,1 MB

Introdução
Todos nós seguimos os tutoriais angulares, e o resultado final é geralmente uma tela "Componente de lista" formatada com
precisão, mostrando uma lista de dados, talvez com um "Componente de detalhes" para ver mais detalhes sobre um objeto
escolhido. Mas não seria legal se pudéssemos pedir ao Angular para criar diagramas bonitos e responsivos? É isso que vamos criar
aqui.

Nosso resultado final ficará assim:

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 1/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Agora isso parece legal!

Obviamente, isso parece ótimo, mas não será adequado para todos os cenários ou tipos de dados, mas espero que este artigo
ensine algumas técnicas úteis e mostre o que é possível com Angular e SVG, sem muita codificação.

Leremos alguns dados JSON e usaremos o Angular para ligar aos elementos SVG para criar um diagrama usando SVG. <svg>os
elementos têm uma grande vantagem sobre os <canvas>elementos, pois têm muito menos memória e, por serem gráficos
vetoriais , você pode aumentar o zoom neles sem perder a qualidade da imagem.

Você pode ver uma versão "ao vivo" deste site clicando aqui . Você verá que, nesta versão, eu levei mais longe, permitindo que você
arraste o controle SVG e aumente e diminua o zoom, usando os ícones de zoom ou a roda do mouse. Você também pode clicar em
um funcionário para exibir seus detalhes.

Escopo
Para escrever este aplicativo, você precisará de:

uma cópia do código do Visual Studio


TypeScript, GIT, npm e a CLI angular instalada
os recursos no arquivo assets.zip , que você pode baixar na parte superior deste artigo
conhecimentos básicos de desenvolvimento angular

Meu modelo original para este projeto também incluiu um projeto de API da Web para ler os dados diretamente do SQL Server.
Substituí isso por um conjunto codificado de dados JSON para manter este artigo mais conciso, mas se você estiver interessado em
saber como criar uma API da Web usando o ASP.NET Core 2, poderá ler meu outro artigo do Code Project aqui .

Você também notará que estou trapaceando um pouco: cada um dos Employeeregistros já tem uma coordenada xey. Não vamos
escrever código para pegar um conjunto de dados hierárquicos e descobrir onde colocá-lo em um novo diagrama. Os dados de
todos terão uma aparência diferente e isso não agregaria muito valor ao artigo.

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 2/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Este artigo é mais para fornecer idéias criativas que você pode usar em seus próprios projetos, em vez de ser uma introdução passo
a passo ao Angular. E parece haver muito poucos exemplos mostrando como usar Angular e SVG juntos. Espero que você ache este
artigo interessante útil, lembre-se de deixar um comentário, se achar!

Vamos criar nosso aplicativo!

1. Crie o aplicativo Angular Barebones


Ok, na minha máquina Windows, abri um prompt de comando e entrei no diretório c: \ repos . Para criar o aplicativo Angular, agora
executarei:

Ocultar   código de cópia

ng new Southwind --routing=true --style=scss

Alguns minutos depois, tenho uma pasta c: \ repos \ Southwind , contendo 31.000 arquivos. Ok, vamos para essa pasta e inicie o
Visual Studio Code:

Ocultar   código de cópia

cd Southwind
code .

Agora, por padrão, todos os aplicativos Angular serão executados na porta 4200. Gosto de mudar isso, a cada novo projeto, apenas
para garantir que não haja conflitos. Para fazer isso, vamos abrir o package.json no Visual Studio Code, abrir o arquivo " package.json
" e alterar o startscript " " para especificar um número de porta diferente:

Ocultar   código de cópia

"scripts": {
"ng": "ng",
"start": "ng serve --port 4401",

Se agora retornarmos ao nosso prompt de comando, poderemos executar nosso novo projeto Angular:

Ocultar   código de cópia

npm start

... e poderíamos abrir http://localhost:4401em um navegador para ver a página Angular padrão.

2. Adicione o Bootstrap ao aplicativo Angular


Em seguida, vamos adicionar o Bootstrap. De volta ao prompt de comando, execute o seguinte comando:

Ocultar   código de cópia

npm install ngx-bootstrap bootstrap --save

No código do Visual Studio, abra o arquivo src \ styles.scss e adicione a seguinte linha:

Ocultar   código de cópia

@import '../node_modules/bootstrap/dist/css/bootstrap.min.css';

Ok, vamos verificar rapidamente se funcionou bem. No arquivo src \ index.html , vou agrupar a <body>tag em uma classe de
contêiner compatível com Bootstrap:

Ocultar   código de cópia

<body>
<div class="container-fluid">
<h3>Southwind</h3>
<app-root></app-root>

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 3/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

</div>
</body>

Em seguida, no src \ app \ app.component.html , vamos excluir todo o código e substituí-lo por este:

Ocultar   código de cópia

<p>Welcome to the Southwind app</p>

<div class="row">
<div class="col-md-3">1st column</div>
<div class="col-md-3">2nd column</div>
<div class="col-md-3">3rd column</div>
<div class="col-md-3">4th column</div>
</div>

Se você executasse o aplicativo agora, verá uma tela bastante opaca, mostrando quatro colunas. Quando você redimensiona a
janela do navegador para uma largura menor, as colunas empilham uma em cima da outra.

Sim, é idiota ... devemos aprender SVG aqui (!), Mas, honestamente, o Angular vem mudando tão rapidamente e dramaticamente
nos últimos anos, eu sempre gosto de criar aplicativos passo a passo e testar ao longo do caminho, para garantir que nada seja
mudado silenciosamente.

3. Adicione os recursos ao nosso aplicativo


Ok, supondo que tudo esteja funcionando bem, vamos adicionar alguns recursos ao aplicativo. Nosso pequeno aplicativo conterá
alguns dados de funcionários e fotos para cada um deles. Também incluí alguns ícones que usei na "versão completa" deste
aplicativo, que você pode encontrar online.

Na parte superior deste tutorial, você encontrará um arquivo assets.zip . Vá em frente e descompacte-o na pasta src \ assets . Você
deve ver essas 3 pastas e seus arquivos, no código do Visual Studio:

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 4/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Ok, vamos carregar alguns dados!

4. Carregando dados JSON


Na pasta assets \ SampleData , você verá um novo arquivo employee.json . Ele contém a lista de employeeregistros e toda uma
lista de relationshipregistros - quais funcionários são os gerentes ou sub-gerentes de outros funcionários? A estrutura fica
assim:

Na relationshiptabela, temos um valor employeeIde managerId, cada um dos quais são chaves estrangeiras,
vinculadas a employeeregistros. Ele também contém uma typecadeia de caracteres, que é " Manager" ou " Sub-manager",
que usaremos posteriormente, apenas para mostrar como podemos alterar facilmente a aparência das linhas do diagrama para
refletir diferentes tipos de relacionamentos.

Para carregar esses dados, substitua o conteúdo do arquivo src \ app.component.ts por estas linhas:

Ocultar   encolher   código de cópia

import { Component } from '@angular/core';


import employeeData from '../assets/SampleData/employees.json';

@Component({
selector: 'app-root',

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 5/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})

export class AppComponent {


public employees: Employee[];
public relationships: Relationship[];

constructor() {
// Populate our two arrays from our sample-data .json file
this.employees = employeeData.employees;
this.relationships = employeeData.relationships;
}
}

interface Employee {
id: number;
job: string;
firstName: string;
lastName: string;
imageUrl: string;
DOB: string;
phoneNumber: string;
xpos: number;
ypos: number;
}

interface Relationship {
employeeId: number;
managerId: number;
type: string; // "Manager" or "Sub-manager"
}

(Sim, eu sei, esses dois interfacesdevem estar em arquivos separados ... mas estou tentando manter isso conciso!)

O que estamos fazendo aqui é definir dois novos interfacesque descrevem a aparência de nossos dados json e importar os
dados json em duas variáveis, employeese relationships.

No entanto, há um aviso na parte superior deste arquivo.

Por padrão, o Angular não pode importar dados diretamente de um arquivo json. Para corrigir isso, basta abrir o arquivo
tsconfig.json (na raiz do projeto) e adicionar duas linhas, em " compilerOptions":

Ocultar   código de cópia

{
"compileOnSave": false,
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true,
. . .

Se agora você voltar ao arquivo src \ app.component.ts , verá que esse erro foi eliminado.

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 6/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Vamos substituir o conteúdo de src \ app.component.html pelo seguinte HTML, para confirmar que este código importou os dados
corretamente:

Ocultar   código de cópia

<p>Welcome to the Southwind app</p>

<div class="row">
<div class="col-md-3 card" *ngFor="let employee of employees;">
<div class="card-img-top">
<img [src]="employee.imageUrl" class="card-img-top" style="object-fit: cover;" >
</div>
<div class="card-body">
<h5 class="card-title">{{ employee.firstName }} {{ employee.lastName }}</h5>
<p class="card-text">
DOB: {{ employee.DOB | date }}<br />
Phone: {{ employee.phoneNumber }}
</p>
</div>
</div>
</div>

Se você abrir localhost:4401novamente agora , verá que ele exibe nossa lista de funcionários, juntamente com as fotos e os
valores da data de nascimento.

Observe que eu exibi esses registros usando o estilo de cartões de inicialização . Esse é um conjunto realmente útil de classes,
principalmente ao criar sites responsivos que ainda ficam bem em uma tela de tablet / smartphone. Você pode ler mais sobre os
cartões de inicialização aqui .

Vamos usar um controle <svg>!


Ok, você está pronto para ver isso em um <svg>controle? Vamos substituir o conteúdo pelo nosso arquivo .html novamente:

Ocultar   encolher   código de cópia

<p>Welcome to the Southwind app</p>

<svg width="1000" height="1000">


<g *ngFor="let employee of employees">
<!-- Image of the employee -->
<image [attr.x]="employee.xpos-4"
https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 7/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

[attr.y]="employee.ypos-4"

width="110" height="110"

[attr.xlink:href]="employee.imageUrl"/>

<!-- Employee first & last name -->


<text [attr.x]="employee.xpos+50"

[attr.y]="employee.ypos+115"

width="400" height="30"

class="cssEmployeeName"

dominant-baseline="middle"

text-anchor="middle">
{{ employee.firstName }} {{ employee.lastName }}
</text>

<!-- Employee job -->


<text [attr.x]="employee.xpos+50" [attr.y]="employee.ypos+132"

width="400" height="30"

class="cssEmployeeJob"

dominant-baseline="middle" text-anchor="middle">
{{ employee.job }}
</text>
</g>
</svg>

Assim como antes, estamos usando a *ngForpara percorrer nossa lista de funcionários e criar uma imagem e dois elementos de
texto para cada um deles, na posição correta em nossa grade.

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 8/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Quão legal é isso?

Para mim, o ponto problemático na criação desse código acima está nos detalhes. Como faço para definir o URL da imagem a ser
exibida? ( Resposta : usamos um attr.xlink.hrefatributo.) Como centralizo o texto logo abaixo da imagem? ( Resposta :
Nós usamos dominant-baselinee text-anchoratributos para lidar com a centralização para nós.) E assim por diante.

A vida teria sido muito mais fácil, se eu tivesse apenas um exemplo prático para aprender com ... ;-)

Internet Explorer 11
Oh céus. Mesmo em 2019, o querido velho IE ainda está nos dando problemas. Até o momento, o código funciona bem em todos
os navegadores modernos, mas para usá-lo no Internet Explorer 11, precisamos executar algumas etapas extras. (Na minha máquina
Windows 10, este aplicativo pendurado IE11 completamente. Eu tive que usar o Gerenciador de Tarefas para matá-lo.)

O Angular fornecerá um arquivo src \ polyfills.ts , e isso sugere a primeira alteração necessária. Diz-lhe:

Ocultar   código de cópia

/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.

Você precisa descomentar esta importlinha e executar o comando mencionado:

Ocultar   código de cópia

npm install --save classlist.js

Em seguida, pule para o arquivo tsconfig.json no diretório raiz e altere esta linha:

Ocultar   código de cópia

"target": "es2015",

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 9/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

para isso:

Ocultar   código de cópia

"target": "es5",

Por fim, no arquivo da lista de navegadores , também no diretório raiz, altere a linha de:

Ocultar   código de cópia

not IE 9-11 # For IE 9-11 support, remove 'not'.

...para...

Ocultar   código de cópia

IE 9-11 # For IE 9-11 support, remove 'not'.

Com essas alterações, a exibição SVG será mostrada em todos os navegadores. Você precisará parar de executar seu aplicativo e
executar npm startnovamente, para que essas alterações sejam ativadas.

Observe que essas dicas se aplicam a qualquer aplicativo Angular que use controles SVG ... então coloque um marcador nesta
página ... você precisará disso para seus outros aplicativos!

E lembre-se, muitas empresas grandes ainda insistem em ter apenas o Internet Explorer instalado nos laptops de seus funcionários,
e os usuários não terão direitos de administrador para instalar outros navegadores em suas máquinas. Assim, você pode querer
seguir estas dicas para todos os seus projetos, a menos que tenha certeza que todos os seus usuários que definitivamente tem um
navegador moderno instalado.

Adicionando linhas SVG


Em seguida, vamos adicionar as linhas entre as imagens, para mostrar quem é o gerente de quem. Para fazer isso, precisamos
adicionar duas funções simples ao nosso arquivo src \ app.component.ts . Cada um dos nossos registros de relacionamento faz
referência aos IDs de dois Employeeregistros, e precisamos encontrar esses Employeeregistros para obter suas coordenadas (x,
y).

Lembre-se de que, quando iterarmos pelos relationshipregistros, teremos apenas o employeevalor do ID - precisamos
procurar o employeeregistro relevante a partir daqui.

Ocultar   código de cópia

"relationships": [
{
"employeeId": 4000,
"managerId": 4001,
"type": "Manager"
},
{
"employeeId": 4000,
"managerId": 4002,
"type": "Manager"
},

A segunda função é simplesmente uma função booleana, para dizer se um relacionamento é para um " Manager" ou um " Sub-
manager". Obteremos que o Angular exiba linhas tracejadas para o último, aplicando uma SVGlineDashedclasse a essas
linhas específicas.

Portanto, no arquivo src \ app.component.ts , vamos adicionar estas duas funções:

Ocultar   código de cópia

public GetEmployee(id) {
// Search for, and return, an Employee record, with a particular id value
const employee = this.employees.filter(emp => {
return emp.id === id;
});
if (employee == null) {
return null;

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 10/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

}
return employee[0];
}

public IsSubManager(relationshipType) {
return (relationshipType === 'Sub-manager');
}

Também vou adicionar um pouco de CSS ao nosso arquivo src \ app.component.scss :

Ocultar   código de cópia

.SVGline {
/* What color line do we want, to connect each of our circular employee image photos ? */
stroke: #141;
stroke-width: 3;
}
.SVGlineDashed {
/* What type of line shall we use, to connect an employee to a Sub-Manager ? */
stroke-dasharray: 3,3;
}

Com as duas funções e CSS no lugar, vamos adicionar as seguintes linhas ao src \ app.component.html , logo após o
<svg>atributo:
Ocultar   código de cópia

<g *ngFor="let rel of relationships">


<line *ngIf="employees && rel" class="SVGline"
[ngClass]="{'SVGlineDashed':IsSubManager(rel.type)}"
[attr.x1]="GetEmployee(rel.employeeId).xpos+50"
[attr.y1]="GetEmployee(rel.employeeId).ypos+50"
[attr.x2]="GetEmployee(rel.managerId).xpos+50"
[attr.y2]="GetEmployee(rel.managerId).ypos+50">
</line>
</g>

Portanto, cada uma das imagens de nossos funcionários tem tamanho de 100x100 pixels. Vamos fazer com que o nosso SVG exiba
linhas entre certos funcionários no centro desse retângulo. E, como você pode ver, cada linha requer uma startcoordenada " " (x,
y) e uma coordenada " end" (x, y).

Com isso, nossa página da Web agora mostra bem as linhas, com nossas duas linhas de Subadministrador exibidas como
pontilhadas, graças a essa SVGlineDashedclasse CSS.

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 11/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Agora você deve entender por que, no <svg>controle, desenhamos as linhas primeiro . Se tivéssemos desenhado as imagens
primeiro, as linhas apareceriam no rosto dos funcionários.

Estilo extra
Bem, alcançamos nosso objetivo, temos um diagrama de imagens usando SVG .... mas realmente parece um pouco nefasto. A
primeira maneira de melhorar isso é cortar cada uma das imagens em um círculo. Para fazer isso, iremos:

desenhe um círculo onde a imagem aparecerá


defina uma circular clipPath, com um nome exclusivo (com base no *ngFor iteratoríndice)
desenhe a imagem, usando o clipPathque acabamos de criar

Novamente, se você nunca viu esse código antes, pode ser um pouco estranho para você, mas tente adicioná-lo ao seu próprio
código e veja como ele se parece. Pessoalmente, foram necessárias algumas tentativas (e muito Google) para descobrir como criá-
las clipPathse como usá-las adequadamente.

Para adicionar esse corte circular, basta remover as linhas que atualmente exibem a imagem de um funcionário:

Ocultar   código de cópia

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 12/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

<!-- Image of the employee -->


<image [attr.x]="employee.xpos-4" [attr.y]="employee.ypos-4"

width="110" height="110" [attr.xlink:href]="employee.imageUrl"/>

... e substitua o *ngForque itera sobre os employeeregistros com este código:

Ocultar   código de cópia

<g *ngFor="let employee of employees; let i = index" [attr.data-index]="i">


<circle [attr.cx]="employee.xpos+50"

[attr.cy]="employee.ypos+50" r="52"

class="cssEmployeeImage">
</circle>
<defs>
<clipPath id="{{'myCircle'+i}}">
<circle [attr.cx]="employee.xpos+50" [attr.cy]="employee.ypos+50" r="50" fill="#FFFFFF"
/>
</clipPath>
</defs>

<!-- Image of the employee -->


<image [attr.x]="employee.xpos-4" [attr.y]="employee.ypos-4"

width="110" height="110" [attr.xlink:href]="employee.imageUrl"

[attr.clip-path]="'url(#myCircle'+i+')'" />

Com essas mudanças, nosso diagrama parece mais profissional:

A próxima coisa que vou fazer é transformar nosso diagrama no "modo escuro". É preferência pessoal, mas acho que parece muito
mais inteligente com um fundo escuro (gradiente).

Na verdade, configurei nossos dois textelementos (para o nome e o cargo do funcionário) para usar classes CSS específicas, mas
ainda não as tínhamos definido. Faremos isso na etapa seguinte.

Primeiro, no arquivo app.component.html , agruparemos o <svg>elemento no HTML a seguir. Observe que eu também adicionei
um style.formatatributo extra ao nosso <svg>elemento. Você verá o porquê em um minuto.

Ocultar   código de cópia

<div class="MainBody" >


<div class="ZoomToolbar">
<img src="../../assets/Photos/ZoomOut.png"
https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 13/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

class="button" height="30" (click)="ZoomOut()" />


<img src="../../assets/Photos/Zoom1.png"

class="button" height="30" (click)="ZoomReset()" />


<img src="../../assets/Photos/ZoomIn.png"

class="button" height="30" (click)="ZoomIn()" />


</div>
<div class="SVGwrapper">

<svg width="1000" height="1000"

[style.transform]="'scale(' + SVGscale/10 + ')'" >

... the rest of the <svg> component goes here ....

</svg>

</div>
</div>

Em seguida, precisamos adicionar um pouco de estilo CSS no arquivo src \ app.component.scss :

Ocultar   encolher   código de cópia

.MainBody {
background: rgb(150,150,150);
background: linear-gradient(185deg, rgba(10,60,60,1) 0%, rgba(0,0,0,1) 100%);
border:1px solid #444;
height:770px;
position:relative;
text-align: left;
-ms-user-select: none;
}
.ZoomToolbar {
position: absolute;
right: 24px;
top: 5px;
z-index: 999;
padding: 10px 25px 10px 100px;
user-select: none;
background: linear-gradient(90deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 100%);
}
.ZoomToolbar img {
cursor: pointer;
margin-right: 10px;
}
.button:active {
/* When we click on the ZoomIn / ZoomOut button, briefly make the icon shrink. */
transform: scale(0.9);
}
.SVGwrapper {
position:absolute;
left:0px;
top:0px;
width:100%;
height:100%;
overflow:scroll;
}
.cssEmployeeName {
font-size:16px;
font-weight:600;
fill:white;
text-shadow:1px 1px 2px #444;
}
.cssEmployeeJob {
font-size:12px;
font-weight:400;

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 14/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

fill:#AAA;
text-shadow:2px 1px 3px #444;
}

E, finalmente, no arquivo src \ app.component.ts , vamos adicionar uma variável extra:

Ocultar   código de cópia

public SVGscale = 10;

E também precisamos de três funções, uma para cada um dos três botões "zoom".

Ocultar   código de cópia

public ZoomOut() {
if (this.SVGscale > 1) {
this.SVGscale -= 1;
}
}
public ZoomIn() {
this.SVGscale += 1;
}
public ZoomReset() {
this.SVGscale = 10;
}

Com tudo isso no lugar, sua página da Web deve ficar assim:

Oh meu Deus ... podemos realmente ampliar e reduzir o diagrama! E percebe como os círculos, linhas e texto permanecem nítidos à
medida que aumentamos o zoom?

A propósito, eu fiz um monte de CSS ao longo dos anos e, nas mudanças acima, coloquei meu truque favorito. Esses três ícones de
"zoom" possuem a classe CSS " button" e, com o seguinte CSS, quando você clica no botão, eles encolhem momentaneamente.
Ele realmente adiciona um toque profissional à página - o usuário sente que o botão está respondendo ao clique.

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 15/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Ocultar   código de cópia

.button:active {
/* When we click on the ZoomIn / ZoomOut button, briefly make the icon shrink. */
transform: scale(0.9);
}

Continuando, não seria legal se pudéssemos ampliar e reduzir isso usando a roda do mouse? Nós podemos. E é fácil demais.

Basta adicionar o seguinte atributo ao <svg>controle:

Ocultar   código de cópia

<svg width="1000" height="1000" [style.transform]="'scale(' + SVGscale/10 + ')'"


(mousewheel)="OnSVGmousewheel($event)" >

... adicione uma função para testar se estamos rolando para cima ou para baixo no mousewheel, para chamar a função relevante:

Ocultar   código de cópia

public OnSVGmousewheel(event: MouseWheelEvent) {


if (event.deltaY < 0) {
this.ZoomIn();
} else {
this.ZoomOut();
}
return false;
}

Ok, sempre aumenta e diminui o zoom no centro do <svg>controle, mas parece muito bom, não?

Hora de outro truque CSS muito legal! No momento, quando você aumenta ou diminui o zoom , ele salta para esse nível de zoom,
em vez de animar suavemente para o nível de zoom. Para corrigir isso, basta adicionar essas linhas ao arquivo src \
app.component.scss :

Ocultar   código de cópia

svg {
transition: transform 0.3s;
}

Este, novamente, é um daqueles pequenos truques que realmente fazem a diferença em um aplicativo da web.

Procurando
Em seguida, vamos adicionar uma função de pesquisa ao nosso aplicativo. Agora, teremos uma caixa de texto de pesquisa na tela,
que queremos vincular a uma propriedade em nosso componente. Portanto, a primeira coisa que precisamos fazer é adicionar
algumas linhas ao app.module.ts arquivo para dizer que estaremos usando ngModel. Primeiro, precisamos importar o
FormsModulepara o nosso aplicativo:
Ocultar   código de cópia

import { FormsModule } from '@angular/forms';

E então, precisamos adicionar isso à nossa lista de importações:

Ocultar   código de cópia

imports: [
FormsModule,
BrowserModule,
... etc ...

Ok, agora vamos adicionar o HTML para este controle de pesquisa. De volta a src \ app.component.html , adicione as seguintes
linhas, após a MainBodylinha:

Ocultar   código de cópia

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 16/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

<div class="MainBody" >


<div class="searchToolbar">
<label for="tbSearch">Search:</label>
<input type="text" class="form-control"
style="width:205px;display:inline-block;margin-left:20px;"
[(ngModel)]="searchText" autofocus (input)="FilterBySearch()"
placeholder="e.g. Smith" />
</div>
<div class="ZoomToolbar">

Em seguida, adicione CSS no nosso arquivo src \ app.component.scss :

Ocultar   código de cópia

.searchToolbar {
position: absolute;
top: 5px;
left: 5px;
width: 380px;
height: 52px;
padding: 6px 10px 5px 10px;
color: white;
z-index: 999;
background: linear-gradient(270deg, rgba(0,0,0,0) 0%,
rgba(0,0,0,0.8) 80%, rgba(0,0,0,1) 100%);
text-align: left;
}

Com isso, temos uma caixa de texto com boa aparência no canto superior esquerdo do diagrama, mas ainda não faz nada.

Em nosso arquivo src \ app.component.ts , precisamos adicionar uma nova variável à qual iremos ligar textbox:

Ocultar   código de cópia

public searchText = '';

E também adicionaremos uma nova variável em nossa employeeinterface:

Ocultar   código de cópia

interface Employee {
highlighted: boolean;
id: number;

Para realmente fazer a pesquisa, precisamos de uma FilterBySearch()função, que será chamada sempre que digitarmos
algo:

Ocultar   código de cópia

public FilterBySearch() {
if (this.employees == null || this.searchText == null) {
return;
}
const str = this.searchText.toLowerCase();
this.employees.filter(function (employee) {
if (employee.firstName.toLowerCase().indexOf(str) > -1
|| employee.lastName.toLowerCase().indexOf(str) > -1
|| str === '') {

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 17/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

employee.highlighted = true;
return employee;
} else {
employee.highlighted = false;
}
});
}

Esse código irá percorrer nossa lista de employeeregistros e definirá ou desabilitará o highlightedvalor para dizer se eles
correspondem à nossa string de pesquisa. Back in the src \ app.component.html arquivo, precisamos adicionar uma classe CSS para
a nossa imagem empregado / nome / elementos de trabalho para os funcionários que fazer corresponder a esta cadeia de
pesquisa, adicionando um ngClassao nosso existente <g>elemento de agrupamento:

Ocultar   código de cópia

<g *ngFor="let employee of employees; let i = index" [attr.data-index]="i"


[ngClass]="{'NotSearchResult': !employee.highlighted}" >

E então precisamos adicionar uma classe para "escurecer" levemente qualquer funcionário que não corresponda à nossa string de
pesquisa.

Ocultar   código de cópia

.NotSearchResult {
opacity: 0.4;
}

Com essas mudanças, temos uma função de pesquisa responsiva. À medida que você começa a digitar na caixa de texto, os
funcionários que não correspondem à sua sequência ficam mais escuros, destacando os funcionários que correspondem.
Novamente, você pode ver isso em ação na versão ao vivo deste site.

Há apenas um pequeno problema: quando entramos nesta tela, nenhum dos funcionários tem um valor destacado definido, então
estão todos escuros! Para consertar isso, precisamos lembrar de chamar nossa FilterBySearchfunção em nosso construtor.

Ocultar   código de cópia

constructor() {
// Populate our two arrays from our sample-data .json file
this.employees = employeeData.employees;
this.relationships = employeeData.relationships;

this.FilterBySearch();
}

E é isso. Agora temos uma função de pesquisa interessante e responsiva.

Adicionando um componente pop-up (modal)


O diagrama parece ótimo agora, a um mundo de distância de uma página Angular comum, mas seria bom se pudéssemos clicar em
um funcionário e ver detalhes extras sobre ele. Obviamente, a maneira mais fácil seria adicionar um link ao nosso <g>elemento
para redirecionar para uma página diferente:

Ocultar   código de cópia

<a routerLink="./customerDetails">

No entanto, vamos discutir como você adicionaria um pop Component- up ao aplicativo. Esse é um daqueles tópicos angulares
que é direto se você seguir as etapas corretas, mas o amarrará se você ainda não viu um exemplo de trabalho.

Aqui está como será o resultado final, depois que eu clicar em Monica Eichofsen :

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 18/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Primeiro, precisaremos criar um novo Componentque será exibido quando clicarmos em um funcionário. Na janela Terminal do
Visual Studio, pressione CTRL + C se você estiver executando o aplicativo no momento e adicione um novo componente usando:

Ocultar   código de cópia

ng generate component customer-details --module app --skipTests=true

Também precisamos adicionar materiais angulares ao nosso aplicativo, pois usaremos isso para fazer o componente aparecer como
um pop-up:

Ocultar   código de cópia

npm install --save @angular/material @angular/cdk @angular/animations hammerjs

Em seguida, precisamos fazer algumas alterações no arquivo app.module.ts . Primeiro, precisamos importar dois novos pacotes na
parte superior do arquivo:

Ocultar   código de cópia

import { MatDialogModule } from '@angular/material/dialog';


import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

Você precisa adicionar os pacotes de materiais angulares à nossa seção de importações:

Ocultar   código de cópia

imports: [
BrowserAnimationsModule,
MatDialogModule,
. . .
],

Também precisamos adicionar duas linhas ao nosso arquivo styles.scss , para garantir que nosso aplicativo possa estilizar o controle
Materials corretamente:

Ocultar   código de cópia

@import "../node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css";
@import 'https://fonts.googleapis.com/icon?family=Material+Icons';

Você pode ler mais sobre como usar MatDialogna página da Angular:

https://material.angular.io/components/dialog/api

Agora, precisamos garantir que nosso componente Detalhes do cliente esteja incluído na declarationsseção:

Ocultar   código de cópia

declarations: [
AppComponent,

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 19/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

CustomerDetailsComponent
],

... mas também precisamos adicioná-lo a uma nova seção entryComponents:

Ocultar   código de cópia

entryComponents: [
// Any modal components need to go in here, aswell as in the "declarations" section
CustomerDetailsComponent
],
providers: [],

(Acabei de poupar meia hora de pesquisa no Google, quando seu componente modal se recusou a ser exibido em tempo de
execução!)

OK. Nosso aplicativo agora conhece o Google Materials. Vamos pular para o nosso novo arquivo customer-details \ customer-
details.component.html e alterá-lo para exibir os detalhes de nossos funcionários como um cartão de Bootstrap:

Ocultar   código de cópia

<div class="card">
<div class="card-img-top">
<img [src]="employee.imageUrl" class="card-img-top" style="object-fit: cover;" >
</div>
<div class="card-body">
<h5 class="card-title">{{ employee.firstName }} {{ employee.lastName }}</h5>
<p class="card-text">
DOB: {{ employee.DOB | date }}<br />
Phone: {{ employee.phoneNumber }}
</p>
</div>
</div>

Em seguida, vamos alterar o arquivo customer-details.component.ts :

Ocultar   código de cópia

import { Component, Inject } from '@angular/core';


import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';

@Component({
selector: 'app-customer-details',
templateUrl: './customer-details.component.html',
styleUrls: ['./customer-details.component.scss']
})

export class CustomerDetailsComponent {

private employee: Employee;

constructor(
public dialogRef: MatDialogRef<CustomerDetailsComponent>,

@Inject(MAT_DIALOG_DATA) private data: any) {


this.employee = data.employee;
}
}

Observe como tivemos que injetar MAT_DIALOG_DATA, para permitir a transmissão de dados para esse componente, pois
queremos informar qual Employeeregistro queremos exibir.

Agora, apenas precisamos AppComponentexibir nosso novo componente quando clicamos em um funcionário.

Cabeça sobre a app.component.html , e adicionar um (click)elemento para o <g>elemento que estamos usando para cada
funcionário:

Ocultar   código de cópia

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 20/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

<g *ngFor="let employee of employees; let i = index" [attr.data-index]="i"


[ngClass]="{'NotSearchResult': !employee.highlighted}"
(click)="SelectEmployee(employee)" >

Por fim, precisamos fazer algumas alterações no app.component.ts . Primeiro, vamos adicionar as dependências na parte superior do
arquivo.

Ocultar   código de cópia

import { MatDialog } from '@angular/material';


import { CustomerDetailsComponent } from './customer-details/customer-details.component';

Precisamos modificar nosso construtor, pronto para usarmos a classe Materials:

Ocultar   código de cópia

constructor(private dialog: MatDialog) {

E com tudo isso no lugar, agora podemos adicionar nossa SelectEmployeefunção. Acabamos de conseguir que a Angular
Materials abra uma instância da nossa CustomerDetailsComponente passamos uma cópia do Employeeregistro
escolhido para ela:

Ocultar   código de cópia

public SelectEmployee(employee) {
const dialogRef = this.dialog.open(CustomerDetailsComponent, {
width: '250px',
data: { employee }
});
}

Como nossas CustomerDetailsComponentreferências são feitas na Employeeinterface, precisamos acessar o arquivo


app.component.ts e tornar esta classe exportável:

Ocultar   código de cópia

export interface Employee {

Sim, é complicado lembrar todas essas etapas, mas mantém nossa página limpa e responsiva, e isso deve lhe dar algumas
inspirações e idéias sobre como você pode implementar suas próprias páginas de diagrama / fluxo de trabalho.

Avançando
Você deve ter notado que a versão online desta página da Web também permite arrastar o diagrama, o que é realmente essencial
quando você amplia o zoom. A chave para isso é simplesmente fazer o <svg>controle position:absolutee alterar os
valores tope à leftmedida que você arrasta.

Isso é fácil de fazer, e incluirei o código fonte completo na versão de download na parte superior do artigo, mas fora do escopo
deste artigo.

O importante é que você veja como é incrivelmente fácil extrair dados reais e faça belos diagramas ou gráficos com eles, usando
Angular e SVG.

Pensamentos finais
O que não contei foi que, há muitos anos atrás, criei uma página HTML / SVG semelhante para a empresa financeira em que estava
trabalhando, para exibir um diagrama de fluxo de trabalho. Foi muito legal, você pode arrastar e soltar elementos - mas - isso foi
nos dias que antecederam o AngularJS ou o React - o código era uma bagunça longa do código JavaScript. Esqueça sempre de
executar testes contínuos nisso !

Com o Angular, como você viu, é possível dividir bem o código TypeScript do código HTML, mantendo-o sustentável e gerenciável.
E o resultado final parece muito bom.

Boa sorte com seus próprios projetos SVG e deixe-me um comentário se tiver alguma dúvida.
https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 21/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

História
nd
22 de novembro de 2019: Versão inicial

Licença
Este artigo, juntamente com qualquer código-fonte e arquivos associados, está licenciado sob a CPOL (The Code Project Open
License)

Compartilhar

Sobre o autor
Michael Gledhill
Desenvolvedor de software
Suíça

Sou desenvolvedor C #, trabalhando em finanças em Zurique, Suíça.

Autor do aplicativo PartnerReSearch para iPad, vencedor do "Business Insurance Innovation Award" em 2013 e do
TechAward2014 "Innovation of the year" em 2014. O

Objective-C é o segundo idioma mais difícil que já aprendi, depois Alemão...

Comentários e Discussões
 

Você deve entrar para usar este quadro de mensagens.

Search Comments

Primeiro Anterior Próximo

É possível colocar as tags de círculo em seus próprios componentes?

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 22/23
06/07/2020 Criando diagramas incríveis usando Angular e SVG - CodeProject

Member 14826748 9-May-20 2:02

Somente assets.zip anexado?


hondavfr801 3-May-20 21:50

Obrigado!
Member 10312131 8-Apr-20 6:46

Ótimo artigo
Joemurai2 10-Feb-20 23:06

Meu voto de 5
Member 12364390 3-Nov-19 22:00

Última Visita: 6 de julho de 20 4:26 Última atualização: 6 de julho de 20 4:26 Atualizar 1

Notícias    Gerais    Sugestão    Pergunta    Bug    Resposta    Joke    Elogio    Rant    Admin   

Use Ctrl + Esquerda / Direita para alternar mensagens, Ctrl + Cima / Baixo para alternar tópicos, Ctrl + Shift + Esquerda / Direita
para alternar páginas.

Link permanente Layout: fixo | fluido Artigo Copyright 2019 por Michael Gledhill
Anuncie Tudo o resto Copyright © CodeProject , 1999-
Privacidade 2020
Cookies
Termos de uso Web06 2.8.200704.1

https://www.codeproject.com/Articles/5249902/Creating-Amazing-Diagrams-using-Angular-and-SVG 23/23