Desenvolvimento

13 abr, 2018

Gráficos divertidos em JS com o D3.js

Publicidade

Se você já se interessou por representação de dados e se questionou em como fazer isso usando JavaScript, provavelmente você já deu as caras com a biblioteca D3.js. Em termos bem simples, ele é uma biblioteca JavaScript para manipulação de documentos baseada  em dados (o que é chamado de Data-Driven Documents, por isso D3). Como descreve o próprio site oficial, o D3.js nos ajuda a dar vida aos dados usando tecnologias web, tais como HTML, CSS e SVG.

Neste artigo, daremos uma olhada no básico do funcionamento do D3.js através de exemplos bem fáceis e divertidos (inspirado no artigo que está nas referências).

Instalação

Assim como a maioria das bibliotecas JavaScript, para utilizarmos em nosso site, precisamos importá-la. Há duas maneiras de se fazer isso:

  1. Você pode baixar o pacote no site (clicando aqui) e importar os arquivos para dentro da sua página manualmente (com a tag <script>).
  2. Importar diretamente a última versão (5.0) usando o site da própria biblioteca, através deste link:
<script src="https://d3js.org/d3.v5.min.js"></script>

Estas são as principais alternativas. No repositório oficial, há algumas outras opções, caso você queira explorar e ver o código fonte.

Os seletores do D3

Para manipularmos o DOM (Document Object Model), precisamos aprender a utilizar os seletores do D3. Para entender como eles funcionam, vamos fazer um exemplo bem simples e trocar as propriedades do header de uma página HTML utilizando o método select() do D3. Veja:

<html>
<head>
    <title>Artigo para o iMasters</title>
</head>
<body>
<h3>O portal iMasters é demais!</h3>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
	d3.select('h3').style('color', 'darkblue');
	d3.select('h3').style('font-size', '24px');
</script>
</body>
</html>

E temos o seguinte resultado (aqui, utilizarei o CodePen*, então parte das tags não são necessárias. O código JavaScript pode ser movido para o quadro correspondente).

Alteração de propriedades do H3 através do D3.js

Essa sintaxe parece familiar, não é mesmo? Os seletores do D3.js lembram bastante os dos jQuery (e tantas outras bibliotecas) e são definidos pela API de seletores da W3C. Note que aqui utilizamos o nome da tag para fazer a seleção, mas podemos utilizar ids, classes, valores de atributos e afins.

Repare que, feito a seleção, usamos o método style() para alterar as suas propriedades. Bem tranquilo, certo? Experimente alterar mais algumas propriedades e quando estiver preparado, parta para o próximo tópico, onde veremos algo mais avançado.

Conectando dados com elementos do DOM

Este processo, também chamado de Data Binding, é o principal fator de funcionamento do D3.js. A ideia aqui é que utilizemos dados para modelar como devem ser os elementos. Como, por exemplo: imagine que temos em um objeto Array do JavaScript uma série de nomes:

var nomes = ['diego', 'joão', 'bruna', 'luana', 'marília'];

Agora queremos colocar estes nomes em uma lista dentro do nosso HTML. Então vamos trocar o <h3> do exemplo anterior por uma lista <ul></ul>. Com o D3.js, podemos manipular esta lista para inserir os nomes de uma forma bem fácil, veja:

var nomes = ['diego', 'joão', 'bruna', 'luana', 'marília'];
d3.select('ul')
  .selectAll('li')
  .data(nomes)
  .enter()
  .append('li')
  .text(function(nome) { return nome; });

Vamos entender o que este código está fazendo. Primeiramente, estamos selecionando o elemento <ul> e então usamos um selectAll() para buscar por todos os elementos <li>. No momento eles não existem, mas precisamos fazer isso para que o D3.js saiba quais elementos manipular. Feito isso, usamos o método data() e passamos o nosso Array como parâmetro. Em seguida, usamos o método enter().

Esse cara é bem importante, porque é ele quem nos permite inserir novos nós na DOM de acordo com os dados recebidos no método anterior. A partir deste ponto, o método append() e text() são executados para cada um dos nossos itens, sendo que esta última função recebe uma função anônima que trabalha com cada um dos itens do nosso Array.

Ao final, temos o resultado esperado: uma lista <ul> com uma tag <li> para cada item da lista, ou seja, cinco tags <li>.

<ul>
    <li>diego</li>
    <li>joão</li>
    <li>bruna</li>
    <li>luana</li>
    <li>marília</li>
</ul>

Esse código gera o seguinte resultado:

Lista gerada através do D3

Hora do SVG entrar em cena

O D3.js não seria tão famoso quanto é se apenas trabalhasse com o que vimos acima. A biblioteca fica realmente interessante quando começamos a trabalhar com os SVG (Scalable Vector Graphics) para fazer a representação visual dos dados. Como o SVG é um formato extremamente leve e escalável, o D3.js usa e abusa dele.

Então agora vamos remover a lista no nosso HTML e inserir uma tag <svg>. Feito isso, vamos manipulá-lo com o seguinte código:

var svg = d3.select('svg');
svg.append('rect')
   .attr('x', 50)
   .attr('y', 50)
   .attr('width', 200)
   .attr('height', 100)
   .attr('fill', 'green');

Veja que de forma semelhante ao que fizemos no exemplo anterior, aqui manipulamos os atributos do elemento com o método attr(). Aqui definimos a posição, altura, comprimento e cor de um retângulo. Realmente bem simples e sem segredo, certo? E o resultado é bem legal.

Retângulo criado com o D3 através de manipulação do svg

Agora vamos ver como unir o que aprendemos até agora.

Criando o nosso primeiro gráfico

Vamos aplicar o que aprendemos até o momento para criar um gráfico de barras bem simples. Comece colando o seguinte svg no seu HTML:

<svg width='200' height='500'></svg>

Feito isso, vamos definir que dados utilizaremos. Para este caso, criarei um array de idades:

var idades = [20, 35, 15, 40, 80];

Agora utilizaremos o seguinte código para gerar o gráfico:

var alturaBarra = 20;
var grafico = d3.select('svg')
  .selectAll('rect')
  .data(idades)
  .enter()
  .append('rect')
  .attr('width', function(idade) {  return idade; })
  .attr('height', alturaBarra - 1)
  .attr('transform', function(d, i) {
    return "translate(0," + i * alturaBarra + ")";
  });

Parece confuso? Vamos entender o que este código está fazendo. Até o trecho do append() acredito que não há dúvidas, certo? É o mesmo comportamento que o do exemplo da lista de nomes. A partir da disso, usamos o método attr() para mexer nas propriedades width, height e transform (como fizemos no exemplo anterior). Para cada idade, mexemos na altura para que fique um em baixo do outro. Ao final, temos o seguinte resultado:

Gráficos gerados usando Data-Driven Document

Conclusão

Esta foi só uma pequena demonstração do poder do D3.js. No site oficial, você encontrará muito mais informações sobre o seu funcionamento e como gerar gráficos insanos de forma muito simples. Se vocês sinalizarem interesse, podemos criar juntos uma série de artigos sobre o tema, mostrando técnicas mais avançadas de manipulação.

Por hora, fica aqui a oportunidade de você usar o seu conhecimento técnico para impressionar o seu gerente/superior com gráficos lindíssimos feitos com JavaScript e ganhar um aumento.

* Quem quiser acompanhar os exemplos no CodePen, utilize este link.

Referências