O gráfico é uma representação visual utilizada para apresentar dados. Podem ser usados, por exemplo, para mostrar padrões ou comparar informações.
Hoje usamos o framework Chart.js para a renderização de gráficos.
Anatomia
1. Título
O título é obrigatório em todos os gráficos. Ele serve para fornecer contexto ao usuário.
2. Descrição curta (opcional)
Use a descrição quando for necessário um texto complementar ao título para a contextualização ou quando precisar explicar um indicador. A descrição deve ser sucinta e caber na área destinada a ela em cada componente.
3. Legenda (opcional)
A legenda deve ser usada somente quando necessária. Se, por exemplo, o gráfico possuir apenas uma cor, não use legenda.
4. Gráfico
Completando o componente, temos de fato o gráfico. Este deve ser escolhido de acordo com o objetivo e os dados a serem apresentados. Falamos mais sobre isso no subtítulo Tipos de Gráficos.
As cores utilizadas nos gráficos não são as cores padrão do Purple, são cores específicas para uso nesse contexto e serão apresentadas na próxima seção.
5. Tooltip
As tooltips servem como texto de apoio e jamais devem conter informações essenciais para o entendimento do gráfico. Podem ser usadas para mostrar percentagens ou totais por categoria dos gráficos e complementar informações. Por exemplo, se a descrição curta for maior que o espaço destinado a ela, irredutível e ainda assim necessária, você pode iniciar o texto no campo descrição curta, colocar reticencias no final e o texto completo na tooltip. Isso pode funcionar apenas em gráficos do menor tamanho.
A largura máxima de uma tooltip é 228px (equivalente a 3 colunas do grid com menu lateral). Você pode encontrar mais diretrizes relacionadas a esse componente na página Tooltip.
Eixos
Os gráficos possuem 2 eixos: X e Y. Para que possamos fazer um combinado, é importante que você saiba qual é qual.
Vamos ao combinado: Quando um dos eixos for relativo a tempo, ele deve ser sempre o eixo X. Isso é porque o tempo nos gráficos parte da esquerda para a direita.
Tipos de Gráficos
Inicialmente trabalharemos com 4 tipos de gráficos (barras, linha, circular e numeral) e tabelas para compor dashboards.
Barras
Um gráfico de barras, também conhecido como gráfico de colunas, representa os dados através de retângulos com alturas ou comprimentos proporcionais aos valores declarados.
Serve para comparações de dados.
Sent messages
Default bar chart.
Sent messages
Alternative bar chart: horizontalBar
<div class="columns is-centered is-multiline">
<div class="column is-12 is-8-desktop is-6-widescreen">
<div class="chart">
<h3 class="chart-title">Sent messages</h3>
<p>Default bar chart.</p>
<div class="chart-data">
<canvas id="chart-01"></canvas>
</div>
</div>
</div>
<div class="column is-12 is-8-desktop is-6-widescreen">
<div class="chart">
<h3 class="chart-title">Sent messages</h3>
<p>Alternative bar chart: <code>horizontalBar</code></p>
<div class="chart-data">
<canvas id="chart-02"></canvas>
</div>
</div>
</div>
</div>
Para gráficos com rótulos longos, use o gráfico de barras horizontais.
O número recomendado de barras é 7 ou menos.
Organização de dados
Ao usar um gráfico de barras ou colunas, caso a organização dos dados não seja por data, considere mostrá-los de ordem crescente ou decrescente. Busque sempre uma forma lógica de apresentação dos dados.
O eixo Value (geralmente o Y) sempre deve começar do 0. Isso evita que os cérebros das pessoas sejam enganados por distorções visuais.
Caso uma das dimensões seja tempo, deve ficar sempre que possível no eixo X.
Linhas
O gráfico de linhas exibe dados como pontos (chamados “marcadores”) conectados por linhas.
Serve para comparar dados através do tempo.
Não use esse tipo de gráfico se não for comparar dados em função do tempo.
API Calls
Multiple series.
<div class="columns is-centered is-multiline">
<div class="column is-12 is-8-desktop is-6-widescreen">
<div class="chart">
<h3 class="chart-title">API Calls</h3>
<p>Multiple series.</p>
<div class="chart-data">
<canvas id="chart-03"></canvas>
</div>
</div>
</div>
</div>
Dependendo da largura do gráfico e dos números que serão apresentados, os gráficos de linhas podem ser afetados. Se a inclinação for muito drástica irá influenciar na percepção da informação. Na próxima seção falaremos sobre os tamanhos de gráficos, isso pode ajudar. A recomendação é que os ângulos fiquem em até 45°, então caso os ângulos fiquem muito estreitos com o tamanho que está usando (ex. small), recomendamos utilizar o próximo (ex. medium).
O número recomendado de linhas é 5 a 7 nos tamanhos medium e large e no máximo 4 no tamanho small.
Legenda
A legenda deve seguir a leitura de cima para baixo, sendo o primeiro label o que tem a primeira marcação mais acima.
A única variação deste gráfico que dispensa legenda é quando temos apenas uma linha.
Circular
O gráfico circular representa os dados como fatias proporcionais. Eles mostram partes de um todo.
Serve para apresentação de dados.
Users
Total users by channel.
<div class="columns is-centered">
<div class="column is-12 is-8-desktop is-6-widescreen">
<div class="chart">
<h3 class="chart-title">Users</h3>
<p>Total users by channel.</p>
<div class="chart-data">
<canvas id="chart-04"></canvas>
</div>
</div>
</div>
</div>
Não use gráfico circular se o valor total não soma 100% ou se os valores forem muito semelhantes. Devido a se tratar de ângulos e áreas, é muito difícil de ler nesse caso. Para essa situação, considere usar o gráfico de barras.
Esse gráfico infelizmente possui uma má reputação, por conta de aplicações que não comunicam de forma clara. Por isso, é essencial que esteja atento as diretrizes de uso que serão apresentadas a seguir.
Organização de dados
Ordene as categorias em ordem decrescente, iniciando no ponto 12h. Organize a legenda da maior fatia para a menor.
Use cores diferentes para cada fatia.
Adicione no máximo 5 fatias ao gráfico. Caso seja necessário mais fatias, é melhor optar pelo uso de outro tipo de gráfico. O uso de mais fatias exige outras formas de apresentação de rótulos que podem não ser efetivas.
Numeral
Esse gráfico contem um número ou porcentagem e é usado para dar visibilidade a dados.
Atendimentos
Total de atendimentos pelo Zenvia Chat.
Comparado ao mês anterior
Mensagens enviadas
Total de mensagens recebidas.
Comparado ao mês anterior
<div class="columns is-centered is-multiline">
<div class="column is-12 is-8-desktop is-6-widescreen">
<div class="chart">
<h3 class="chart-title">Atendimentos</h3>
<p>Total de atendimentos pelo Zenvia Chat.</p>
<div class="chart-data">
<span class="chart-data-number">158</span>
<span class="chart-data-delta" data-value="-2">-2%</span>
<p>Comparado ao mês anterior</p>
</div>
</div>
</div>
<div class="column is-12 is-8-desktop is-6-widescreen">
<div class="chart is-success">
<h3 class="chart-title">Mensagens enviadas</h3>
<p>Total de mensagens recebidas.</p>
<div class="chart-data">
<span class="chart-data-number">95.108</span>
<span class="chart-data-delta" data-value="34">+34%</span>
<p>Comparado ao mês anterior</p>
</div>
</div>
</div>
</div>
Em caso de comparação com período anterior (ex.: crescimento percentual de vendas), é recomendado que o aumento ou a queda seja indicado também através de cores (verde e vermelho) e símbolos (seta para cima e para baixo). Nesse caso, sempre informe o usuário com qual período estamos comparando os dados.
Atenção: dependendo do indicador, uma queda pode ser positiva e um aumento negativo. Um exemplo disso é o indicador “Contatos não confirmados” do Zenvia Flow (o aumento é negativo).
Tamanhos
Temos 3 tamanhos de gráficos: Small (4 colunas da grid), Medium (6 colunas) e Large (8 colunas). Sendo o medium o tamanho padrão, mais recomendado por se adequar melhor a mais situações.
A altura de todos eles é padrão, possui 376px
.
Ainda não existem definições de quando cada tamanho deve ser utilizado. Esse tamanho deve ser definido pelo Designer, PM ou outro responsável de acordo com os dados a serem apresentados.
Os gráficos de tamanhos medium e large são iguais em todos os gráficos, com exceção do numeral que não possui tamanho large, apenas small e medium. Já os gráficos small possuem algumas particularidades.
Small
Os gráficos desse tamanho possuem as legendas sempre na parte superior e sua descrição pode não estar completa no campo Descrição curta, deixando reticências e o texto completo em uma tooltip.
Além disso, os gráficos de barras e linhas possuem um grid reduzido no eixo que contém Value.
Aplicação
Os gráficos sempre devem ser postos dentro de cards, isso te dará mais flexibilidade e ajudará a torná-lo responsivo, além de manter a estrutura consistente. As margens internas do card devem ser de no mínimo 24px
.
Ausência de dados
Quando houver ausência de dados, mostre isso visualmente. Opte, por exemplo, por fazer uma pausa no gráfico de linha ou não mostrar uma coluna no gráfico de barras.
Última atualização
Os gráficos não são atualizados em tempo real. Por esse motivo, é necessário que sempre informemos o usuário que podem haver novos dados. Para isso, temos duas abordagens:
Caso o gráfico esteja em um Dashboard
Deve ser apresentada a data e hora de atualização da página em geral. Conheça as diretrizes para esse caso na página Dashboard.
Caso o gráfico não esteja em um Dashboard
A data e hora de atualização devem ser apresentadas fora do card de gráfico, com o estilo Caption. A posição deve ser decidida de acordo com a necessidade de cada página. Veja abaixo as possibilidades:
Para a última atualização, utilizamos o Human Readable timestamp format.
Boas Práticas
- Opte pelo grid horizontal ou vertical. Evite o uso de ambos ao mesmo tempo.
- Não dependa de tooltips. Elas devem ser usadas apenas como apoio.
- Use legenda apenas quando for necessário.
- Evite misturar tipos de gráficos (ex. barras e linhas).
Scripts de inicialização de gráficos
Para começar a usar gráficos em sua página, o script abaixo deve ser carregado como dependência:
<!-- Chart.js library -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/Chart.min.js"></script>
Como o Chart.js possui suas próprias guidelines e comportamentos, precisamos mudar algumas configurações para se adequar ao estilo de uso da Zenvia. Adicione as configurações abaixo no script de sua aplicação.
// General behavior
Chart.defaults.global.responsive = true;
// Font
Chart.defaults.global.defaultFontColor = '#2f3039';
Chart.defaults.global.defaultFontFamily = 'Nunito Sans';
Chart.defaults.global.defaultFontSize = 14;
Chart.defaults.global.maintainAspectRatio = false;
// Legend
Chart.defaults.global.legend.align = 'start';
Chart.defaults.global.legend.fontColor = '#2f3039';
Chart.defaults.global.legend.fontFamily = 'Nunito Sans';
Chart.defaults.global.legend.labels.boxWidth = 8;
Chart.defaults.global.legend.labels.usePointStyle = true;
// Elements
Chart.defaults.global.elements.arc.borderWidth = 0;
Chart.defaults.global.elements.line.fill = false;
Chart.defaults.global.elements.line.borderWidth = 2;
<!-- See below how to start chart rendering -->
<button class="button" onclick="renderCharts()">Render charts</button>
<script>
function renderCharts() {
// Chart 01
new Chart(document.getElementById('chart-01'), {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
datasets: [{
label: 'SMS',
data: [112, 193, 37, 59, 22, 30, 118],
backgroundColor: '#0096dc'
},{
label: 'WhatsApp',
data: [98, 116, 47, 105, 83, 131, 96],
backgroundColor: '#ec407a'
}]
},
options: {
scales: { // for stacked bar charts
xAxes: [{
stacked: true,
gridLines: {
display: false
}
}],
yAxes: [{
stacked: true,
gridLines: {
drawBorder: false
}
}]
}
}
});
// Chart 02
new Chart(document.getElementById('chart-02'), {
type: 'horizontalBar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'],
datasets: [{
label: 'SMS',
data: [112, 193, 37, 59, 22, 30, 118],
backgroundColor: '#0096dc'
},{
label: 'WhatsApp',
data: [98, 116, 47, 105, 83, 131, 96],
backgroundColor: '#ec407a'
}]
},
options: {
scales: { // for stacked bar charts
xAxes: [{
stacked: true,
gridLines: {
drawBorder: false
}
}],
yAxes: [{
stacked: true,
gridLines: {
display: false
}
}]
}
}
});
// Chart 03
new Chart(document.getElementById('chart-03'), {
type: 'line',
data: {
labels: ['0h', '3h', '6h', '9h', '12h', '15h', '18h', '21h'],
datasets: [{
label: 'SMS',
data: [112, 143, 37, 59, 22, 30, 118, 80],
backgroundColor: '#0096dc',
borderColor: '#0096dc'
},{
label: 'WhatsApp',
data: [71, 17, 47, 15, 30, 78, 6, 54],
backgroundColor: '#ec407a',
borderColor: '#ec407a'
},{
label: 'RCS',
data: [98, 116, 47, 105, 83, 131, 96, 18],
backgroundColor: '#00cbee',
borderColor: '#00cbee'
},{
label: 'Voice',
data: [4, 2, 12, 9, 27, 31, 6, 33],
backgroundColor: '#f48fb1',
borderColor: '#f48fb1'
}]
},
options: {
scales: {
xAxes: [{
gridLines: {
display: false
}
}],
yAxes: [{
gridLines: {
drawBorder: false
}
}]
}
}
});
// Chart 04
new Chart(document.getElementById('chart-04'), {
type: 'doughnut',
data: {
labels: ['WhatsApp', 'SMS', 'Facebook', 'RCS'],
datasets: [{
data: [1450, 780, 640, 400],
backgroundColor: [
'#ec407a',
'#f48fb1',
'#ad1457',
'#f06292'
]
}]
},
options: {
legend: {
align: 'middle',
position: 'right'
}
}
});
}
window.onload = function() {
renderCharts();
};
</script>
Para mais informações de como usar e configurar os gráficos, acesse documentação do Chart.js