Categorias
Introdução à Programação Web para Bioinformática: HTML, CSS, PHP & JavaScript

D3.js

Capítulo 14

Este conteúdo faz parte do livro “Introdução à programação Web para a Bioinformática: HTML, CSS, PHP & JavaScript“. Você pode adquirir a versão impressa desse livro aqui ou a versão para Kindle aqui. Para nos citar, consulte este link.

D3 (Data-Driven Documents ou na tradução literal “documentos orientados a dados”) é uma biblioteca JavaScript para construção de visualizações de dados criada por Mike Bostock.

D3 permite que visualizações sejam criadas diretamente em páginas HTML através de gráficos vetorizados SVG (Scalable Vector Graphics).

D3 pode ser baixado em: <http://d3js.org>. Ou você pode executar diretamente pela internet apenas declarando no seu código:

<script src="https://d3js.org/d3.v4.min.js"></script>

c14_s1.html | https://goo.gl/EDNR5R

Nos exemplos a seguir aprenderemos a fazer dois tipos básicos de gráficos com d3: gráfico de pizza (pie chart) e gráfico de barras (bar chart).

Gráfico de pizza (pie chart)

O gráfico de pizza ou pie chart (na verdade uma melhor tradução seria “gráfico de torta”) é uma representação circular de visualizações a qual cada “fatia” representa uma determinada proporção. Seu uso deve ser evitado em grandes quantidades de dados, pois a determinação visual de uma fatia na área de um gráfico circular é complicada. Lembre-se que a área de um gráfico é obtida por πr² (~3,14 vezes raio ao quadrado).

No exemplo a seguir, demonstraremos o uso do gráfico de pizza para diferenciar dois grupos de dados. Os chamaremos apenas de grupo 1 (65% dos dados) e grupo 2 (35% dos dados).

Primeiro crie um arquivo chamado “index.html”:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="estilo.css" rel="stylesheet">
</head>
<body>
  <svg width="600" height="480"></svg>
  <footer>
    <!-- Meus scripts -->
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="script.js"></script>
  </footer>
</body>
</html>

c14_s2.html | https://goo.gl/Szd65G

No arquivo de estilos, criaremos uma única classe chamada “.arc”. Aplicaremos estilos a elementos text e path presentes nessa classe. Crie o arquivo “estilo.css”:

/* Estilo.css */
.arc text { font: 12px sans-serif; text-anchor: middle; }
.arc path { stroke: #fff; }

c14_s3.css | https://goo.gl/p0Do5k

Agora crie um arquivo chamado “data.csv”. Um arquivo csv consiste um arquivo de texto cujas características de cada linha são separadas por vírgulas. A primeira linha, em geral, representa o título representativo para cada coluna.

grupo,dados
Grupo 1,65
Grupo 2,35

c14_s4.csv | https://goo.gl/7uT3qm

E por fim um arquivo chamado “script.js”. Neste arquivo iremos declarar o elemento SVG, que receberá os dados e gerará o gráfico usando a base do D3.

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = Math.min(width, height) / 2,
    g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal(["#98abc5", "#d0743c"]);
var pie = d3.pie()
    .sort(null)
    .value(function(d) { return d.dados; });
var path = d3.arc()
    .outerRadius(radius - 10)
    .innerRadius(0);
var label = d3.arc()
    .outerRadius(radius - 70)
    .innerRadius(radius - 70);
d3.csv("data.csv", function(d) {
  d.dados = +d.dados;
  return d;
}, function(error, data) {
  if (error) throw error;
  var arc = g.selectAll(".arc")
    .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");
  arc.append("path")
      .attr("d", path)
      .attr("fill", function(d) { return color(d.data.grupo); });
  arc.append("text")
      .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
      .attr("dy", "0.35em")
      .text(function(d) { return d.data.grupo; });
});

c14_s5.js | https://goo.gl/6TJVlP

Agora vamos tentar entender um pouco do que foi feito. Inicialmente criamos uma variável chamada svg que chama um elemento de tag <svg>. Essa variável deve ter altura, largura e raio. A função d3 será responsável por organizar tudo. O elemento g tem a função de agrupar elementos no d3.

Definimos as cores que poderão ser aplicadas a visualização e apenas no trecho “var pie = d3.pie()” é que definimos que se trata de um gráfico de pizza. A seguir são feitas algumas definições em relação a posição dos rótulos.

Em “d3.csv(“data.csv”, function(d) { … });” começamos a ler o conteúdo do arquivo CSV e assim formar o gráfico de pizza. Observe o uso da função append para adicionar novos elementos no svg. Tente analisar agora as outras linhas.

Gráfico de barras

O gráfico de barras é uma representação visual na qual cada barra representa proporcionalmente os valores de um determinado atributo. No exemplo a seguir, demonstraremos um gráfico com a origem de alunos do curso de pós-graduação em Bioinformática da Universidade Federal de Minas Gerais.

Primeiro crie um arquivo chamado “index.html”:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="estilo.css" rel="stylesheet">
</head>
<body>
  <svg width="600" height="480"></svg>
  <footer>
    <!-- Meus scripts -->
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="script.js"></script>
  </footer>
</body>
</html>

c14_s6.html | https://goo.gl/UqLswQ

Observe que no arquivo HTML temos que definir o tamanho de nossa visualização. Ela terá 600 pixels de largura por 480 pixels de altura. Todo conteúdo criado no arquivo JavaScript será gravado na svg.

<svg width="600" height="480"></svg>

c14_s7.html | https://goo.gl/m7Itep

A seguir crie um arquivo “estilo.css”:

/* Estilo.css */
.bar { fill: steelblue; }
.bar:hover { fill: brown; }
.axis--x path { display: none; }

c14_s8.css | https://goo.gl/lbBfpR

Observe que estamos apenas definindo as cores que serão adotadas pelas barras, além das cores que adotarão quando forem sobrepostas.

Agora, crie um arquivo chamado “data.tsv”. Um arquivo tsv consiste em um arquivo de texto cujas características de cada linha são separadas por tabulações. Assim como o arquivo csv, a primeira linha, em geral, representa o título representativo para cada coluna.

estado  frequencia
BA  .063
CE  .016
GO  .031
MT  .016
MG  .563
PA  .016
PB  .016
PR  .078
PE  .016
RJ  .016
RN  .016
RS  .047
SC  .031
SP  .031
Nd* .047

c14_s9.tsv | https://goo.gl/Ka53Ml

Os dados exibidos acima foram coletados da página do programa de pós-graduação em Bioinformática da UFMG (http://pgbioinfo.icb.ufmg.br).

E por fim, crie um arquivo chamado “script.js”:

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
    y = d3.scaleLinear().rangeRound([height, 0]);

var g = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.tsv("data.tsv", function(d) {
  d.frequencia = +d.frequencia;
  return d;
}, function(error, data) {
  if (error) throw error;

  x.domain(data.map(function(d) { return d.estado; }));
  y.domain([0, d3.max(data, function(d) { return d.frequencia; })]);

  g.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

  g.append("g")
      .attr("class", "axis axis--y")
      .call(d3.axisLeft(y).ticks(10, "%"))
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Frequência");

  g.selectAll(".bar")
    .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.estado); })
      .attr("y", function(d) { return y(d.frequencia); })
      .attr("width", x.bandwidth())
      .attr("height", function(d) { return height - y(d.frequencia); });
});

c14_s10.js | https://goo.gl/DN1R40

Vamos dividir a explicação por partes:

var svg = d3.select("svg"),
    margin = {top: 20, right: 20, bottom: 30, left: 40},
    width = +svg.attr("width") - margin.left - margin.right,
    height = +svg.attr("height") - margin.top - margin.bottom;

c14_s11.js | https://goo.gl/gvCpfc

Aqui criamos uma variável chamada svg, que selecionará a tag svg presente na página pela árvore DOM. As linhas posteriores aplicam algumas margens na visualização ainda não criada.

var x = d3.scaleBand().rangeRound([0, width]).padding(0.1),
    y = d3.scaleLinear().rangeRound([height, 0]);
var g = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

c14_s12.js | https://goo.gl/KusHjn

A seguir criamos variáveis para os eixos x e y. Os códigos criam escalas para esses eixos. Além disso uma variável chamada g posiciona corretamente alguns elementos.

d3.tsv("data.tsv", function(d) {
  d.frequencia = +d.frequencia;
  return d;
}, function(error, data) {
  if (error) throw error;
  x.domain(data.map(function(d) { return d.estado; }));
  y.domain([0, d3.max(data, function(d) { return d.frequencia; })]);

c14_s13.js | https://goo.gl/kn6nJ6

Aqui o arquivo tsv com os dados brutos começa a ser lido. Definimos que os dados virão da coluna “frequencia” e os domínios x e y são definidos. Eles serão responsáveis por definir por exemplo qual será a altura máxima adotada no eixo y do gráfico.

g.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));
g.append("g")
      .attr("class", "axis axis--y")
      .call(d3.axisLeft(y).ticks(10, "%"))
    .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", "0.71em")
      .attr("text-anchor", "end")
      .text("Frequência");

c14_s14.js | https://goo.gl/6BeN4p

Adicionamos o eixo x e o eixo y. Definimos informações relativas as fontes e de onde virão as informações que irão os preencher.

g.selectAll(".bar")
    .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.estado); })
      .attr("y", function(d) { return y(d.frequencia); })
      .attr("width", x.bandwidth())
      .attr("height", function(d) { return height - y(d.frequencia); });
});

c14_s15.js | https://goo.gl/lecQYb

Aqui cada barra é criada. Observe que primeiro é feita uma seleção da classe “.bar”. Os dados carregados. O comando enter() é usando. E por ficam cada retângulo que corresponda a uma frequência específica é adicionado.

Para saber mais sobre o D3js visite a página oficial: <http://d3js.org>.

Quer aprender mais? Conheça nossos cursos profissionalizantes à partir de R$19,99:

Livro Introdução à Programação para Web para Bioinformática: HTML, CSS, PHP & JavaScript

Capítulo 1
Introdução ao HTML

Capítulo 2
Fundamentos do HTML

Capítulo 3
Estrutura de páginas

Capítulo 4
Folhas de Estilo em Cascata (CSS)

Capítulo 5
Bootstrap

Capítulo 6
Iniciando a construção de um Website

Capítulo 7
Introdução ao PHP

Capítulo 8
Fundamentos do PHP

Capítulo 9
Transformando um Website em dinâmico

Capítulo 10
Introdução ao JavaScript

Capítulo 11
Fundamentos do JavaScript

Capítulo 12
jQuery

Capítulo 13
Bootstrap JavaScript

Capítulo 14
D3.js

Capítulo 15
3Dmol

Capítulo 16
Projeto Final

Epílogo
Referências Bibliográficas

Cite:

MARIANO, DIEGO; de MELO-MINARDI, R. C. . Introdução à Programação Web para Bioinformática: HTML, CSS, PHP & JavaScript. 1. ed. North Charleston, SC (EUA): CreateSpace Independent Publishing Platform, 2017. v. 3. ISBN: 978-1520895154; 403p .

Por Diego Mariano

Doutor em Bioinformática pela Universidade Federal de Minas Gerais com atuação na área de ciência de dados e aprendizado de máquina aplicados ao aperfeiçoamento de enzimas usadas na produção de biocombustíveis. Mestre em Bioinformática, também pela UFMG, atuando na área de desenvolvimento de sistemas Web para montagem de genomas. Atualmente realiza estágio pós-doutoral no Departamento de Ciência da Computação da UFMG com foco em desenvolvimento de sistemas Web para Bioinformática, análise exploratória e visualização de dados. Tem conhecimentos nas linguagens: PHP, JavaScript, Python, R, Perl, HTML, CSS e SQL.