D3.js e Vue.JS

Andre de Vries Blocked Desbloquear Seguir Seguindo 3 de janeiro

Neste blog, descreverei como você pode integrar o D3 ao Vue.js. A D3 é uma biblioteca JavaScript popular para visualizar dados usando padrões da Web (HTML, CSS, JavaScript e SVG). Vue.js é uma estrela em ascensão no front-end e recentemente ganhou muita popularidade na cena de desenvolvimento web. É uma estrutura de front-end semelhante a React e Angular e permite que você crie interfaces de usuário escalonáveis.

Eu estou aprendendo D3 como eu vou, e eu usei muito Vue.js nos últimos meses, eu pensei que seria bom praticar como eu posso combinar os dois. Eu ainda estou aprendendo e melhorando minhas habilidades D3, então acho que, se eu revisitar este post em alguns meses, vou ver erros ou coisas que eu mudaria, então, por favor, realce quaisquer problemas ou sugestões nos comentários abaixo.

Eu peguei emprestado o gráfico que estou recriando para este post de Elijah Meeks (imagem abaixo), que escreveu um excelente livro sobre o D3.js chamado 'D3.js in Action' . Se você quer aprender mais sobre esta biblioteca JavaScript, então esta deve ser sua primeira parada (então sim, definitivamente compre essa).

No Capítulo 9, ele escreve sobre a integração do D3 com o React, e eu vi muitos bons exemplos dessa combinação no GitHub e B.locks. Mas não há muitos recursos para integrar o D3 com o Vue.js. Eu encontrei alguns outros artigos sobre Medium e um sobre B.locks, mas o melhor até agora foi este repo de Shirley Wu , que é um engenheiro de software freelance e especialista em visualização de dados.

'Circle Chart' para exibir dados hierárquicos – tirados do Capítulo 6.3.1 do D3js em Ação

Como começar com o Vue

Vamos começar com o scaffolding no Vue Project – isso é semelhante ao create-react-app para aqueles que vêm de um mundo do React. Estou usando o Vue CLI versão 3. Se você não tiver instalado, execute:

 $ npm install -g @ vue / cli 

Eu sei que usar o CLI para apenas um componente do gráfico é um pouco exagerado, mas suponho que você vai integrar o D3 em um aplicativo maior para o qual você deseja usar toda a funcionalidade do Vue. O sinalizador -g significa que você está instalando globalmente em sua máquina, portanto não há necessidade de executá-lo novamente na próxima vez que usar o Vue. Depois de instalar o Vue, é hora de criar um novo projeto. Execute as seguintes linhas, uma por uma no seu terminal:

 $ vue cria um exemplo de d3-vue 
$ cd d3-vue-example
$ npm run saque

Com o npm run serve você está iniciando um servidor de desenvolvimento com o 'hot reload' ativado. Isso significa que quando você faz alterações em quase todos os arquivos, as alterações são exibidas imediatamente. Uma vez que você tenha este servidor rodando, é hora de instalar o D3. Você pode fazer isso da seguinte maneira:

 $ npm i - salve d3 

Se você abrir a pasta do d3-vue-example em seu editor favorito (eu uso o VS Code ), então você verá vários arquivos e pastas listadas. Por enquanto é importante que o arquivo package.json esteja lá. É aqui que aparecem todos os pacotes que você instala através do npm . O D3 agora também deve aparecer sob dependências neste arquivo package.json .

Crie um componente gráfico

Os arquivos e pastas mais importantes para nós estão no src pasta. App.vue é a entrada principal do seu aplicativo. Nesse arquivo, você deseja importar todos os componentes criados. Por padrão, você vê apenas um componente sendo importado aqui; o HelloWorld . Este arquivo de componente está localizado na subpasta de componentes. É uma boa prática colocar todos os seus componentes nessa pasta.

Vamos também criar um arquivo Chart.vue nesta pasta. Em seguida, volte ao seu arquivo App.vue e duplique a linha 9 e substitua HelloWorld pelo arquivo de Chart recém-criado. Depois disso, você deve adicionar o Chart à propriedade components do objeto JavaScript que está sendo exportado nesse arquivo. A próxima etapa é fazer referência a esse componente na seção de modelo do arquivo App.vue .

O componente 'PackChart' está sendo importado no App.vue e usado no modelo

Ok, isso pode ter te confundido um pouco se você é novo em frameworks front-end e trabalha com npm . Dirija-se à minha página do Github para encontrar o código-fonte, se você quiser uma visão completa.

Vá para sua porta localhost 8080 (http: // localhost: 8080) e você será recebido com o modelo padrão do Vue. Se você é novo no Vue.js então esta nova extensão de arquivo .vue pode parecer um pouco estranha. Na verdade, essa é a beleza do Vue – nesse arquivo você cria seus próprios componentes e tem todos os seus HTML (template), JavaScript e CSS juntos. Passar por cima de todo o básico do Vue é demais para este blog, então eu recomendo gastar algum tempo com este curso na Udemy da Maximilian Schwarzmüller .

Adicionando D3 ao Vue

Eu tenho a tendência de importar D3 em todos os componentes que eu crio (incluindo App.vue ), mas é provavelmente uma boa prática não fazer isso e apenas importá-lo uma vez, ou apenas importar os elementos da API que você precisa. Uma explicação da importação do módulo do D3 pode ser encontrada aqui . Você pode importar D3 em cada componente referenciando-o no topo da seção de script do arquivo vue da seguinte forma:

 import * como d3 de 'd3' 

Outra maneira seria incluir o link CDN na seção head do arquivo index.html mas é uma boa prática usar os módulos do nó. Embora com o método CDN, isso significaria que você pode usá-lo em todos os lugares em seu aplicativo.

Construa o componente gráfico

Se você voltar para o seu arquivo App.vue então configuraremos adereços de dados. Adereços são os dados que você deseja enviar de seu componente pai, o arquivo App.vue , para seus componentes filhos, neste caso Chart.vue . Vamos primeiro criar uma propriedade de dados na qual vamos enviar os dados (chamei de loadData ). Nós vamos usar o arquivo tweets.json do livro de Meeks – você pode pegar o arquivo aqui . Depois de baixado, mova o arquivo para a pasta pública na pasta do projeto.

Carregar os dados no App.vue quando o aplicativo foi montado

O Vue.js tem vários ganchos de 'ciclo de vida'. Estes correspondem aos diferentes 'estados' da sua aplicação. Na imagem acima, você vê a propriedade 'mounted' na instância do Vue. Quando o aplicativo é carregado, ele adiciona todas as propriedades que ele pode encontrar no objeto 'data' ao seu sistema Reactivity. Isso significa que, se os dados forem alterados, seu aplicativo também será atualizado (torna-se reativo). Se você é novo em frameworks de front-end, pode ser um pouco difícil no começo envolver o conceito de 'estado' e como os elementos estão sendo removidos e atualizados. Mas se você estiver familiarizado com o D3, isso pode soar um pouco. Pense nisso como o padrão 'Enter-Update-Exit'.

Adicione isto ao arquivo Chart.vue

De volta ao objeto montado. No D3 versão 5, temos que usar promessas para carregar nossos dados. Isso torna a vida muito mais fácil porque anteriormente você teria que usar retornos de chamada que muitas vezes se tornaram um pouco confusos. O que o montado faz nesse caso é carregar os dados do arquivo JSON e disponibilizá-los quando o DOM estiver sendo 'montado'. Depois disso, você precisa adicionar os dados ao Chart.vue que criamos no componente Chart.vue (veja a imagem à esquerda). Em seguida, você App.vue este prop ao componente Chart no arquivo App.vue da App.vue forma:

 <PackChart: data = loadData /> 

Isso significa que qualquer objeto que esteja em 'loadData' está sendo empurrado para o componente filho que é o arquivo Chart.vue (chamado de PackChart).

Se você é novo nesta sintaxe Async / Await de lidar com promessas, então eu sugiro que você assista a essa palestra de Wes Bos.

Crie o gráfico D3

A primeira seção da parte do script do arquivo Chart.vue contém a importação de D3, retorna o objeto de data (com uma mensagem exibida no componente e a width e a height do SVG que contém o gráfico (1)). Essa width e height são então vinculadas ao SVG no modelo (2).

Largura e Altura do SVG especificado no objeto de dados da instância do Vue

No gancho de ciclo de vida 'criado', estou definindo uma função de scale para as cores do gráfico circular. Como temos uma lista de conjuntos de bolhas aninhadas (uma lista discreta) como entrada, podemos usar a escala scaleOrdinal . Essa escala, então, retorna uma saída discreta de cores (aquelas que definimos na matriz). Se você quiser saber mais sobre as diferentes escalas de D3, então eu recomendo ir para esta página .

O próximo passo é criar uma propriedade computada na qual reestruturamos os dados para que possamos usá-los como uma hierarquia. O D3 tem várias funções úteis que podem ajudá-lo a preparar seus dados para gráficos que exibem hierarquias. Um deles é a função nest () . O que isto faz é transformar uma estrutura plana em uma aninhada (1 => 2). Você pode definir como nest lo (qual propriedade) e quão profundo é aninhá-lo. No nosso caso, eu uso o 'usuário' como a propriedade de nível superior. Isso significa que nossa nova matriz contém quatro objetos (um para cada usuário).

De um tweet por objeto para um objeto por usuário (com tweets como filhos) com nest ()

Nesta mesma propriedade computada, estou usando o módulo de hierarquia. Este módulo usa uma raiz (o novo objeto chamado packableTweets – veja a imagem abaixo) e retorna um novo layout.

Cria a estrutura hierárquica conforme a imagem anterior

Para realmente desenhar algo na tela, precisamos retornar alguns dados que podem ser vinculados ao SVG no modelo. Para isso, criei outra propriedade computada que aceita a anterior ( packData() ) e retorna uma matriz de Objetos JS com as coordenadas x & y e o raio dos círculos. Em seguida, ele também usa o colourScale definido no gancho criado (veja a imagem abaixo).

Retorna uma matriz de objetos (contendo os dados do círculo)

Podemos, então, percorrer esse array com a diretiva v-for e exibir os círculos na visualização com suas coordenadas x e y correspondentes, seu raio e cor.

Se você chegou aqui, seguiu vários passos. Se você ficou preso ao longo do caminho, recomendo ir ao meu GitHub e clonar o repositório e inspecionar o gráfico aqui . Estou aberto a comentários, pois tenho certeza de que tenho complicado demais as coisas ou ignorado elementos no meu código.