Criando um dashboard dinâmico com o ChartJS

Hoje vamos criar um dashboard com gráficos dinâmicos utilizando a solução ChartJS. ChartJS é uma poderosa biblioteca JavaScript, sem dependências, que auxilia na criação de gráficos para web através do elemento HTML canvas. E o melhor, a utilização do ChartJS é super simples até mesmo para designers. Vamos focar na parte funcional da biblioteca para criar gráficos de maneira simples e rápida. Vamos criar um dashboard responsivo do inicio ao fim.


Este post faz parte do projeto que participo de tradução dos artigos dos blogs da Envato, Webdesigntuts+, Gamedevelopmenttuts+ e Nettuts+. Todos os direitos reservados para Envato.

[su_table]


Link para artigo original: Build a Dynamic Dashboard With ChartJS
Autor do artigo original: Jonathan Cutrell

[/su_table]

Introdução

Vamos criar nossa dashboard com base no HTML5 Boilerplate. Faça download do arquivo compactado, ou clone o repositório via Git. Vamos nomear o diretório do projeto de “chartjs_dashboard”, e jogar todos os arquivos direto na pasta.

# na linha de comando / terminal
git clone git@github.com:h5bp/html5-boilerplate.git chartjs_dashboard

Agora é a vez do ChartJS. Vá a até a versão uminified (versão sem compressão, facilita a leitura de erros e deixa o código mais legível, eliminando espaços no texto para otimizar a performance de leitura e execução) do ChartJS no link raw.github.com/nnnick/Chart.js/master/Chart.js, e copie todo o conteúdo para o seu arquivo js/plugins.js.

Dica:
em produção, é recomendado utilizar a versão minified (comprimida) do arquivo JavaScript do ChartJS para otimizar a performance.

Sua estrutura de arquivos deve estar parecida com essa:

├── 404.html
├── crossdomain.xml
├── css
│ ├── main.css
│ └── normalize.css
├── favicon.ico
├── img
├── index.html
├── js
│ ├── main.js
│ ├── plugins.js
│ └── vendor
│ ├── jquery-1.10.1.min.js
│ └── modernizr-2.6.2.min.js
└── robots.txt

Nota: não incluímos os arquivos do HTML5 Boirlerplate que não vamos utilizar.

Paleta de cores

Antes de começar a programar o site, vamos começar definindo uma paleta de cores para o design. Com isso temos o inicio de uma style guide para o nosso pequeno projeto, uma prática comum de design.

Se você vai criar um dashboard com uma marca em mente, ou para empresas por exemplo, tente usar as cores da marca. No nosso exemplo vamos definir duas cores primárias e duas auxiliares. Também vamos utilizar contrastes e sombras dessas cores.

  • dark blue: #637b85
  • green: #2c9c69
  • yellow: #dbba34
  • red: #c62f29

Vamos utilizar uma camada mais clara do dark blue, #d0dde3. E por último, vamos utilizar cores na escala do cinza.

Introdução básica ao ChartJS

O ChartJS utiliza o elemento canvas. O elemento canvas junto com JavaScript permite a criação de uma interface para desenhar pixels. É muito comparado ao SVG, que oferece um elemento no DOM que permite a criação de vetores em páginas web. No entanto, desenhar pixels no elemento canvas não permite manter o elemento na memória e o mesmo não responde a eventos JavaScript.

Se deseja mais informações sobre o ChartJS, visite meu post (Thierry Rene) de introdução ao ChartJS.

Chega de conversa fiada – Como de fato começar a utilizar o ChartJS?

Por sorte, a pagina do ChartJS tem uma série de exemplos que ajudam muito na primeira utilização da biblioteca. O padrão é criar o elemento canvas no arquivo HTML, selecionar este com JavaScript, e criar o gráfico.

<canvas id="something"></canvas>
<script>
var canvas = document.getElementById("something");
var ctx = canvas.getContext("2d");
new Chart(ctx).Line(data, options);
</script>

O exemplo acima assume que você declarou como objetos os itens ‘data’ e ‘options’, para criar um gráfico em linha.


No nosso exemplo vamos utilizar o gráfico em rosca, em linha, e radar. Esses gráficos vão representar diferentes métricas, mas você pode adaptar como quiser para qualquer outro negócio sem muita dificuldade.

Marcação HTML

Vamos começar definindo algumas linhas básicas em HTML para o layout da nossa página.

<div class="wrapper">
<header>
 <div class="container clearfix">
 <h1>Overview <span>July 8-12, 2013</span><a class="button">Change Date Range</a></h1>
 </div>
</header>
<div class="container clearfix">
 <div class="third widget doughnut">
 <h3>Breakdown of Hours</h3>
 <div class="canvas-container">
 <canvas id="hours"></canvas>
 </div>
 </div>
 <div class="third widget line">
 <div class="chart-legend">
 <h3>Shipments per Day</h3>
 </div>
 <div class="canvas-container">
 <canvas id="shipments"></canvas>
 </div>
 </div>
 <div class="third widget">
 <div class="chart-legend">
 <h3>Customer Service Assessment</h3>
 </div>
 <div class="canvas-container">
 <canvas id="departments"></canvas>
 </div>
 </div>
</div>
<div class="push"></div>
</div>
<footer>
</footer>

Note que aqui temos as seções header, o meio “middle” e o rodapé “footer” Here, we can see that we have a basic header, middle, and footer section. Estamos utilizando a classes .wrapper e .push para criar o rodapé (clique aqui para maiores informações sobre o rodapé sticky footer). Vamos criar um layout com foco na responsividade ou mobile friendly, e a partir deste vamos definir os demais layouts, para tablets, desktops e afins. Vamos ter um certo trabalho durante a criação mas a estrutura não vai apresentar problemas de exibição do conteúdo, pelo menos inicialmente.

Antes de continuarmos…

O elemento canvas não funciona muito bem com media queries, que é o recurso mais comum para aplicar técnicas responsivas em páginas web. Então vamos utilizar um método diferente para criar gráficos responsivos com ajuda do JavaScript.

Dentro do nosso arquivo main.js, vamos criar uma função de redimesionamento baseada no tamanho da tela. Também vamos precisar de uma função para redesenhar o canvas após a função de redimesionamento ser executada. E por último, quando o gráfico é refeito não precisa de animações.

(function(){
// variável para o timeout
var t;
// função de redimensionamento
// com argumento para animar ou não o gráfico
function size(animate){
// Não queremos que haja uma animação no gráfico caso o mesmo tenha sido
// redimensionado
 // Otimiza o carregamento da função que apenas executa o redimensionamento após redimensionar a janela
 clearTimeout(t);
 // Essa linha vai resetar o timeout.
 t = setTimeout(function(){
 $("canvas").each(function(i,el){
 // Configurar a altura e largura do elemento canvas igual a do elemento pai.
 // O elemento pai é a div.canvas-container
 $(el).attr({
 "width":$(el).parent().width(),
 "height":$(el).parent().outerHeight()
 });
 });
 redraw(animate);

// criamos um loop através dos widgets e configuramos a altura de acordo
 var m = 0;
 // temos de remover qualquer configuração de altura inline.
 $(".widget").height("");
 $(".widget").each(function(i,el){ m = Math.max(m,$(el).height()); });
 $(".widget").height(m);

}, 100); // o timeout está configurado para 100 milisegundos
}
$(window).on('resize', size);
function redraw(animation){
 var options = {};
 if (!animation){
 options.animation = false;
 } else {
 options.animation = true;
 }
 // ....
 // a resto da criação do gráfico ocorre nesta partehere
 // ....
}
size();

Se ficou confusa a explicação, não se preocupe! Encaminhe um comentário e nós da comunidade Tuts+ vamos tentar te ajudar para que você entenda o que está ocorrendo neste exemplo!

Um pouco de CSS para começarmos

Precisamos configurar algumas estruturas básicas em CSS antes de começarmos. O HTML5 Boilerplate inclui o normalize e outras soluções que você pode alterar, mas para o bem do tutorial, vamos escrever nosso código CSS após a linha “Author’s custom styles”.

html, body {
height: 100%;
}
body {
 font-family: 'Source Sans Pro', sans-serif;
 color: #666;
}
/* button */
.button {
 cursor: pointer;
 text-decoration: none;
 font-size: 0.6em;
 font-weight: 400;
 text-transform: uppercase;
 display: inline-block;
 padding: 4px 6px;
 margin: 0 10px;
 position: relative;
 background: #ccc;
 color: #fff;
 box-shadow: 0 0 2px rgba(0,0,0,0.1);
 background: rgb(190,190,190); /* Old browsers */
 background: -moz-linear-gradient(top, rgba(190,190,190,1) 0%, rgba(170,170,170,1) 100%); /* FF3.6+ */
 background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(190,190,190,1)), color-stop(100%,rgba(170,170,170,1))); /* Chrome,Safari4+ */
 background: -webkit-linear-gradient(top, rgba(190,190,190,1) 0%,rgba(170,170,170,1) 100%); /* Chrome10+,Safari5.1+ */
 background: -o-linear-gradient(top, rgba(190,190,190,1) 0%,rgba(170,170,170,1) 100%); /* Opera 11.10+ */
 background: -ms-linear-gradient(top, rgba(190,190,190,1) 0%,rgba(170,170,170,1) 100%); /* IE10+ */
 background: linear-gradient(to bottom, rgba(190,190,190,1) 0%,rgba(170,170,170,1) 100%); /* W3C */
 filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bebebe', endColorstr='#aaaaaa',GradientType=0 ); /* IE6-9 */
}
.button:hover {
 background: #637b85;
}
/* Header styles */
header {
 text-align: center;
 background: #637b85;
 color: #fff;
 margin-bottom: 40px;
}
header span {
 font-weight: 200;
}
header .button {
 font-size: 0.2em;
 top: -6px;
}

/* various containers */
.container {
 width: 200px;
 margin: 0 auto;
}
.canvas-container {
 min-height: 300px;
 max-height: 600px;
 position: relative;
}
.widget {
 position: relative;
 margin-bottom: 80px;
 background: #efefef;
 padding: 12px;
 margin-bottom: 30px;
 -webkit-box-sizing: border-box;
 -moz-box-sizing: border-box;
 box-sizing: border-box;
}

Aqui definimos via CSS as configurações do sticky footer, assim como a classe para botões, uma classe para centralizar o container, uma classe para a box que vai utilizar o elemento canvas, e uma para o widgets. Também adicionamos uma fonte do Google Fonts conforme a linha de código abaixo, descrita no head do documento HTML.

<link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:200,400,700' rel='stylesheet' type='text/css'>

Gráfico Rosca

Os gráficos em rosca são bem parecidos com gráficos pizza, exceto o fundo no meio, que no gráfico rosca é oco, e o no pizza é totalmente preenchido. Por padrão, o ChartJS define que 50% do meio deve ser retirado para criar o gráfico em rosca; vamos utilizar esse mesmo padrão. O código para criar o gráfico rosca está descrito abaixo.

var data = [
{
 value: 20,
 color:"#637b85"
 },
 {
 value : 30,
 color : "#2c9c69"
 },
 {
 value : 40,
 color : "#dbba34"
 },
 {
 value : 10,
 color : "#c62f29"
 }

];
var canvas = document.getElementById("hours");
var ctx = canvas.getContext("2d");
new Chart(ctx).Doughnut(data);

Neste bloco definimos a cor e as informações que vão gerar o gráfico. Isso é tudo que o gráfico em rosca exige para funcionar. De qualquer modo, o que cada uma dessas sessões representa? Infelizmente o CHARTJS ainda não possui uma forma simples para definir as informações de label das seções do gráfico rosca; mas podemos criar nossas próprias labels para apresentar a informação de cada seção. Modifique o widget HTML do gráfico rosca conforme o bloco abaixo.

<div class="third widget doughnut">
<h3>Breakdown of Hours</h3>
 <p><a href="" class="button">Filter By Employee</a></p>
 <div class="canvas-container">
 <canvas id="hours"></canvas>
 <span class="status"></span>
 </div>
 <div class="chart-legend">
 <ul>
 <li class="ship">Shipping &amp;amp; Receiving</li>
 <li class="rework">Rework</li>
 <li class="admin">Administrative</li>
 <li class="prod">Production</li>
 </ul>
 </div>
</div>

Utilizamos os elementos li através de suas classes, considerando a pseudo classe :before.

.chart-legend ul {
list-style: none;
 width: 100%;
 margin: 30px auto 0;
}
.chart-legend li {
 text-indent: 16px;
 line-height: 24px;
 position: relative;
 font-weight: 200;
 display: block;
 float: left;
 width: 50%;
 font-size: 0.8em;
}
.chart-legend li:before {
 display: block;
 width: 10px;
 height: 16px;
 position: absolute;
 left: 0;
 top: 3px;
 content: "";
}
.ship:before { background-color: #637b85; }
.rework:before { background-color: #2c9c69; }
.admin:before { background-color: #dbba34; }
.prod:before { background-color: #c62f29; }

Continuando, vamos ter um botão curtir no centro do gráfico rosca. Isso exige alguns truques CSS e a inclusão da solução Uncle Dave’s Ol’ Padded Box para que o círculo seja responsivo. Vamos utilizar o elemento span com a classe .status para criar esse círculo. Adicione as seguintes linhas no arquivo main.css:

.widget.doughnut .status {
display: block;
 position: absolute;
 top: 50%;
 left: 50%;
 width: 30%;
 height: 0;
 padding-top: 12%;
 padding-bottom: 18%;
 color: #444;
 margin-top: -15%;
 margin-left: -15%;
 font-size: 1.4em;
 font-weight: 700;
 text-align: center;
 border-radius: 50%;
 background-color: #aaa;
 background-image: url(data:image/png;base64,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);
 background-repeat: no-repeat;
 background-size: 30%;
 background-position: center;
}

O item mais notável aqui é a utilização do data URI para o background image. Isso evita mais requisições HTTP. Também definimos a position deste elemento como absoluta dentro do elemento .widget, que anteriormente definimos com position relative.

Vamos em frente configurar a tipografia do widget. Utilizamos apenas os elementos “p” e “h3” dentro do widget; abaixo está o CSS utilizado.

.widget p {
margin-top: 0;
 text-align: center;
}

.widget h3 {
 margin: -12px 0 12px -12px;
 padding: 12px;
 width: 100%;
 text-align: center;
 color: #627b86;
 line-height: 2em;
 background: #d0dde3;
}

As regras margin e padding no elemento “h3” permitem ao mesmo se posicionar no widget, com 12px de padding do topo. Também definimos o top margin para 0 no elemento “p” para ficar mais próximo e parecido com o header do widget.

Gráfico Linha

Um dos recursos mais interessantes do ChartJS é que alguns dos gráficos tem suporte para múltiplos conjuntos de informações. Esse conjunto de informações é carregada com o gráfico sequencialmente, permitindo a comparação de uma informação com outra. Um exemplo de utilização deste recurso é o gráfico em linha. Vamos utilizar dois conjuntos de informações (datasets) para explorar essa funcionalidade.

var data = {
labels : ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],
 datasets : [
 {
 fillColor : "rgba(99,123,133,0.4)",
 strokeColor : "rgba(220,220,220,1)",
 pointColor : "rgba(220,220,220,1)",
 pointStrokeColor : "#fff",
 data : [65,54,30,81,56,55,40]
 },
 {
 fillColor : "rgba(219,186,52,0.4)",
 strokeColor : "rgba(220,220,220,1)",
 pointColor : "rgba(220,220,220,1)",
 pointStrokeColor : "#fff",
 data : [20,60,42,58,31,21,50]
 },
 ]
}
var canvas = document.getElementById("shipments");
var ctx = canvas.getContext("2d");
new Chart(ctx).Line(data, options);

Algumas informações importantes neste bloco de código: primeiro, estamos utilizando as mesmas variáveis do gráfico em rosca, criado anteriormente. Isso é completamente válido em JavaScript, e reduz a memória utilizada pelo script. Mas, pode causar complicações no futuro, então se você planeja utilizar esse código no futuro, e planeja adaptar este código para produção, é recomendado criar novas variáveis para cada gráfico.

Segundo, o gráfico em linha suporta labels, ou legendas. Isso é importante, pois evita de criar uma legenda manualmente para o gráfico. Também é importante que a as informações da label batam com as informações da linha. No exemplo abaixo, nosso primeiro data-point é o primeiro dataset, 65, que está atrelado a label “Mon”.

E por último, as cores para o dataset são as cores definidas anteriormente na versão RGBa, azul escuro e amarelo. Você consegue converter facilmente uma cor em HEX para RGBa incluindo o código da cor no colorpicker do PhotoShop, se você não tiver PhotoShop existem diversas ferramentas online que podem fazer isso facilmente.

Também vamos adicionar uma marcação HTML para inserir botões e textos para o usuário. No fim o bloco do widget vai se parecer com o bloco de código abaixo.

<div class="third widget line">
<div class="chart-legend">
 <h3>Shipments per Day</h3>
 <p><span>This Week</span> &amp;mdash; <strong>Last Week</strong></p>
 <p><a href="" class="button">Change Date Range</a><a href="" class="button">Filter by Location</a></p>
 </div>
 <div class="canvas-container">
 <canvas id="shipments"></canvas>
 </div>
</div>

Vamos polir um pouco esse bloco de marcação com as seguintes regras CSS:

.widget.line p span {
color: #dbba34;
}
.widget.line p strong {
 color: #637b85;
 font-weight: 400;
}

Gráfico radar

O gráfico radar é útil para destinguir uma seleção de variáveis em um unico gráfico, onde você consegue ter uma visão simples das diferenças entre as variáveis. No nosso exemplo, vamos explorar a ideia de serviço ao cliente, baseado em quantas vezes certas palavras chave são mencionadas. No gráfico radar, os pontos em amarelo ajudam a ter noção do desempenho do serviço ao cliente.

Vamos criar o gráfico! Mais uma vez, vou utilizar a mesma variável de antes.

var data = {
labels : ["Helpful","Friendly","Kind","Rude","Slow","Frustrating"],
 datasets : [
 {
 fillColor : "rgba(220,220,220,0.5)",
 strokeColor : "#637b85",
 pointColor : "#dbba34",
 pointStrokeColor : "#637b85",
 data : [65,59,90,81,30,56]
 }
 ]
}
var canvas = document.getElementById("departments");
var ctx = canvas.getContext("2d");
new Chart(ctx).Radar(data, options);


Abaixo a marcação HTML que vai acompanhar este bloco de JavaScript para gerar o gráfico:

<div class="third widget">
<div class="chart-legend">
 <h3>Customer Service Assessment</h3>
 <p>based on words mentioned</p>
 <p><a href="" class="button">Track another word</a></p>
 </div>
 <div class="canvas-container">
 <canvas id="departments"></canvas>
 </div>
</div>

Olhando o gráfico, da a impressão que um ponto que vai para cima está melhor do que o ponto que vai para baixo e para os lados. Por outro lado, não perdemos a informação de cada variável, que fica muito clara no gráfico. No nosso exemplo, a palavra “rude” foi mencionada várias vezes mas a sensação do serviço é positiva, conforme mostra o gráfico em relação a outras palavras mencionadas.

Gráficos responsivos

Já configuramos o elemento cavas para ser responsivo com a função JavaScript que criamos no inicio do tutorial. Agora precisamos tornar o CSS também responsivo utilizando media queries. Abaixo está o CSS que vamos utilizar para essa tarefa.

@media only screen and (min-width:300px){
.container {
 width: 300px;
 margin: 0 auto;
 }
}

@media only screen and (min-width:600px){
 .container {
 width: 580px;
 margin: 0 auto;
 }
 .third {
 float: left;
 width: 47.5%;
 margin-left: 5%;
 }
 .third:first-child {
 margin-left: 0;
 }
 .third:last-child {
 display: block;
 width: 100%;
 margin-left: 0;
 }
}

@media only screen and (min-width:960px){
 .container {
 width: 940px;
 }
 .third {
 float: left;
 width: 30%;
 margin-left: 2.5%;
 margin-right: 2.5%;
 }
 .third:first-child {
 margin-left: 0;
 }
 .third:last-child {
 margin-right: 0;
 margin-left: 2.5%;
 width: 30%;
 }
}
@media only screen and (min-width:1140px){
 .container {
 width: 1120px;
 }
}
@media only screen and (min-width:1360px){
 .container {
 width: 1300px;
 }
}

A primeira coisa a notar neste CSS é que todas as medias queries são baseadas em min-width, que quer dizer que certas regras são aplicadas em uma certa medida mínima (normalmente é utilizada a medida max, max-width). Isso siginifica que estamos focando em telas pequenas, adicionando novas regras conforme a necessidade. Nosso design não requer muitas mudanças em cada breakepoint, mas essa é uma das boas práticas CSS que podem e devem ser exploradas.

chartjs-small
chartjs-mid
chartjs-large

Podemos adicionar mudanças básicas do layout em cada breakpoint, incluindo a largura do primeiro elemento container, assim como a classe .third, que utilizados em cada widget. Antes de 400 de largura, todos os gráficos são posicionados um acima do outro. Entre 400 e 600 de largura, deixamos dois widgets dividindo o espaço total da primeira linha, enquanto o terceiro gráfico (radar) é apresentado na linha inteira abaixo. Acima de 960 de largura, utilizamos três colunas na mesma linha.

Conclusão

Neste tutorial introduzimos o ChartJS criando um dashboard. Os principais conceitos descritos neste tutorial podem ajudar a criar projetos utilizando essa solução, além de incentivar o design responsivo de baixo pra cima (técnica utilizada com as media queries).

Que experiência você tem com bibliotecas para gráficos? Você utiliza SVG ou o elemento canvas para gerar o gráfico? Que recurso você gostaria de ver no ChartJS? Comente! 🙂


  • Ricardo Paladino

    Parabéns pelo site, Thierry tem como colocar esse gráficos para receber informações de um banco de dados, se tiver pode mostrar como?

    • Olá Ricardo, muito obrigado! tem sim cara, a maneira mais simples que encontrei quando pesquisei sobre, foi fazendo um select no bd retornando o valor em json, e utilizar esses valores no chartjs. nunca testei, mas já vi exemplos online com esse método.