Como fazer um gráfico de bolhas animado com CSS

Cobrimos várias técnicas para desenvolver diferentes tipos de gráficos usando CSS e/ou JavaScript. Hoje, mostrarei como fazer um gráfico de bolhas com CSS.

O que é um gráfico de bolhas?

UMA gráfico de bolhas é um tipo de gráfico, considerado primo do gráfico de dispersão, e seu objetivo principal é visualizar as relações entre três dimensões/variáveis ​​diferentes: uma é representada pelo eixo X, uma pelo eixo Y e uma pelo tamanho da bolha.

uma imagem de exemplo de um gráfico de bolhasuma imagem de exemplo de um gráfico de bolhasuma imagem de exemplo de um gráfico de bolhas
3 variáveis ​​numéricas são comparadas em um gráfico de bolhas

Esse tipo de gráfico pode fornecer informações úteis sobre tendências ao longo do ano, comparação de dados históricos, comparação de vendas etc.

Você pode criar gráficos de bolha dinâmicos complexos usando diferentes bibliotecas JavaScript, como Highcharts.js e ApexCharts.js.

1. Comece com os dados

Para esta demonstração, pegaremos emprestados alguns dados de um tutorial gráfico anterior e elaborá-los um pouco. Então, vamos supor que queremos visualizar em um gráfico de bolhas os seguintes dados que descrevem o financiamento de uma instituição de caridade ao longo dos anos:

Ano Financiamento número de empregados
2018 € 95.000 12
2016 € 72.000 10
2015 € 50.000 8
2012 € 35.000 6
2010 € 15.000 4

Cada linha da tabela corresponderá a um ponto (bolha). As duas primeiras colunas descreverão a posição da bolha ao longo dos eixos X e Y, enquanto a terceira indicará seu tamanho.

2. Especifique a marcação da página

Vamos especificar um elemento wrapper que contém duas listas:

  • A primeira lista define o intervalo do eixo y. Se você observar mais de perto os dados da tabela acima, verá que a segunda coluna inclui valores de até 95.000. Tendo isso em mente, definiremos seis valores de 0 a 100.000 com um tamanho de passo de 20.000. Os valores do eixo y serão, portanto, 0, 20.000, 40.000, 60.000, 80.000 e 100.000.
  • A segunda lista define os dados do eixo x. Esses números são extraídos da primeira coluna da nossa tabela, do menor para o maior. Observe na marcação abaixo, porém, que um item de lista contém o mesmo ano duas vezes. Poderíamos ter omitido a definição do ano como nó de texto do item. Mas é importante armazenar esse valor no data-year atributo. Como veremos mais adiante, passaremos o valor deste atributo para o relacionado ::before pseudo-elemento. Considere também o data-details atributo. Seu valor servirá como dica de ferramenta da bolha correspondente. Dentro deste valor existem múltiplas aparências do que é a representação HTML em formato hexadecimal de um caractere de avanço de linha. Vamos colocá-lo após cada pedaço de texto onde queremos forçar uma nova linha. Mais sobre isso mais tarde.

Aqui está a marcação necessária:

1
 class="chart-wrapper">
2
   class="chart-y">
3
    
  • €100,000
  • 4
        ...
    
    5
      
    
    6
       class="chart-x">
    
    7
         data-year="2010">
    
    8
           data-details="UK:72%
    USA:24%
    Sweden:3%">2010
    
    9
        
    
    10
        ...
    
    11
      
    
    12
    
    

    3. Estilizar o gráfico

    Para simplificar, vou pular alguns estilos básicos/redefinidos. Você pode conferir o restante clicando no botão CSS guia do projeto de demonstração.


    Não otimizei os estilos, tornando mais fácil para você ver o que está acontecendo

    Por fim, incorporei o premium Cheddar Gótico fonte retirada de ga-analytics#sendElementsClickEvent”>Envato Elements para o título.

    O wrapper do gráfico será um contêiner flexível com largura máxima de 700px e conteúdo centralizado horizontalmente. O eixo y será três vezes maior que o eixo x.

    O CSS relacionado:

    1
    .chart-wrapper {
    
    2
      display: flex;
    
    3
      max-width: 700px;
    
    4
      padding-right: 15px;
    
    5
      margin: 30px auto 0; 
    
    6
    }
    
    7
    8
    .chart-wrapper .chart-y {
    
    9
      flex: 1;
    
    10
    }
    
    11
    12
    .chart-wrapper .chart-x {
    
    13
      flex: 3;
    
    14
    }
    

    O eixo x

    A segunda lista que inclui os dados do eixo x também será um contêiner flexível. Seus itens terão uma largura de 12%, serão distribuídos uniformemente no eixo principal e ficarão no fundo do contêiner. Faremos a lista parecer um elemento neumórfico com a ajuda de esta ferramenta.

    Além disso, cada item da lista terá uma altura que dependerá do valor do financiamento associado (ver tabela acima). Por exemplo, um valor de 15.000 corresponde a height: 15%.

    Aqui estão os estilos relacionados:

    1
    .chart-wrapper .chart-x {
    
    2
      display: flex;
    
    3
      justify-content: space-around;
    
    4
      align-items: flex-end;
    
    5
      border-radius: 48px;
    
    6
      background: #f0f0f0;
    
    7
      box-shadow: -8px 8px 20px #b4b4b4, 8px -8px 20px #ffffff;
    
    8
    }
    
    9
    10
    .chart-wrapper .chart-x li {
    
    11
      position: relative;
    
    12
      width: 12%;
    
    13
    }
    
    14
    15
    .chart-wrapper .chart-x li:nth-child(1) {
    
    16
      height: 15%; /*represents €15,000*/
    
    17
    }
    
    18
    19
    .chart-wrapper .chart-x li:nth-child(2) {
    
    20
      height: 35%; /*represents €35,000*/
    
    21
    }
    
    22
    23
    .chart-wrapper .chart-x li:nth-child(3) {
    
    24
      height: 50%; /*represents €50,000*/
    
    25
    }
    
    26
    27
    .chart-wrapper .chart-x li:nth-child(4) {
    
    28
      height: 72%; /*represents €72,000*/
    
    29
    }
    
    30
    31
    .chart-wrapper .chart-x li:nth-child(5) {
    
    32
      height: 95%; /*represents €95,000*/
    
    33
    }
    

    A seguir, usaremos o ::before pseudo-elemento de cada item para gerar os rótulos do eixo x.

    Os rótulos do eixo xOs rótulos do eixo xOs rótulos do eixo x

    O CSS associado:

    1
    .chart-wrapper .chart-x li::before {
    
    2
      content: attr(data-year);
    
    3
      position: absolute;
    
    4
      left: 50%;
    
    5
      bottom: 0;
    
    6
      width: 100%;
    
    7
      text-align: center;
    
    8
      transform: translate(-50%, 40px) rotate(45deg);
    
    9
    }
    

    Bolhas

    Cada span elemento corresponderá a uma bolha (ponto). Cada bolha terá uma cor e tamanho diferentes.

    As bolhas do gráficoAs bolhas do gráficoAs bolhas do gráfico

    O tamanho da bolha dependerá do valor da terceira coluna da tabela relacionada (consulte a tabela). Assumindo que a largura e a altura da menor (primeira) bolha serão 15px, calcularemos de acordo o tamanho das restantes.

    Outra coisa que faremos é impedir a exibição das bolhas por padrão e, em vez disso, mostrá-las com uma animação de fade e escala. Em suas próprias páginas onde o DOM provavelmente conterá mais elementos, para resultados mais precisos você pode esperar até que a página carregue antes de mostrar as bolhas como fizemos no gráfico de termômetro.

    Aqui estão os estilos associados:

    1
    /*CUSTOM VARIABLES HERE*/
    
    2
    3
    .chart-wrapper .chart-x li:nth-child(1) span {
    
    4
      width: 15px; /*represents 4 employees*/
    
    5
      height: 15px; /*represents 4 employees*/
    
    6
      background-color: var(--bubble-color1);
    
    7
    }
    
    8
    9
    .chart-wrapper .chart-x li:nth-child(2) span {
    
    10
      width: 22.5px; /*represents 6 employees*/
    
    11
      height: 22.5px; /*represents 6 employees*/
    
    12
      background-color: var(--bubble-color2);
    
    13
    }
    
    14
    15
    .chart-wrapper .chart-x li:nth-child(3) span {
    
    16
      width: 30px; /*represents 8 employees*/
    
    17
      height: 30px; /*represents 8 employees*/
    
    18
      background-color: var(--bubble-color3);
    
    19
    }
    
    20
    21
    .chart-wrapper .chart-x li:nth-child(4) span {
    
    22
      width: 37.5px;  /*represents 10 employees*/
    
    23
      height: 37.5px; /*represents 10 employees*/
    
    24
      background-color: var(--bubble-color4);
    
    25
    }
    
    26
    27
    .chart-wrapper .chart-x li:nth-child(5) span {
    
    28
      width: 45px; /*represents 12 employees*/
    
    29
      height: 45px; /*represents 12 employees*/
    
    30
      background-color: var(--bubble-color5);
    
    31
    }
    
    32
    33
    .chart-wrapper .chart-x span {
    
    34
      content: "";
    
    35
      position: absolute;
    
    36
      top: 0;
    
    37
      left: 50%;
    
    38
      border-radius: 50%;
    
    39
      font-size: 0;
    
    40
      cursor: pointer;
    
    41
      opacity: 0;
    
    42
      transform: scale(0.001);
    
    43
      animation: fade-in 0.8s linear forwards;
    
    44
    }
    
    45
    46
    @keyframes fade-in {
    
    47
      100% {
    
    48
        opacity: 1;
    
    49
        transform: scale(1) translateX(-50%);
    
    50
      }
    
    51
    }
    

    dicas

    Conforme discutimos, cada bolha terá uma dica de ferramenta para mostrar mais informações. Isso ficará visível quando a largura da viewport for maior que 700px e quando passarmos o mouse sobre uma bolha.

    Uma dica de bolhaUma dica de bolhaUma dica de bolha

    Para criá-lo, usaremos o ::before e ::after pseudo-elementos de cada span (bolha). o ::after pseudo-elemento servirá como a dica de ferramenta real enquanto o ::before um terá um lugar mais decorativo e servirá como o triângulo da dica de ferramenta.

    Como mencionamos acima, as informações da dica de ferramenta virão do data-details atributo. Aqui usamos o representação hexadecimal para dividir o valor do atributo em várias linhas. Mas isso não é suficiente; também temos que usar o white-space propriedade. Aqui está um tópico detalhado do Stack Overflow sobre isso.

    Os estilos relacionados:

    1
    .chart-wrapper .chart-x span::before {
    
    2
      content: "";
    
    3
      position: absolute;
    
    4
      left: 50%;
    
    5
      bottom: calc(100% + 3px);
    
    6
      transform: translateX(-50%);
    
    7
      width: 0;
    
    8
      height: 0;
    
    9
      border-style: solid;
    
    10
      border-width: 6px 6px 0 6px;
    
    11
      border-color: rgba(0, 0, 0, 0.7) transparent transparent transparent;
    
    12
      opacity: 0;
    
    13
      transition: opacity 0.15s linear;
    
    14
      pointer-events: none;
    
    15
    }
    
    16
    17
    .chart-wrapper .chart-x span::after {
    
    18
      content: attr(data-details);
    
    19
      position: absolute;
    
    20
      left: 50%;
    
    21
      bottom: calc(100% + 9px);
    
    22
      min-width: 90px;
    
    23
      line-height: 1.35;
    
    24
      transform: translateX(-50%);
    
    25
      color: var(--white);
    
    26
      background: rgba(0, 0, 0, 0.7);
    
    27
      font-size: 1rem;
    
    28
      white-space: pre;
    
    29
      border-radius: 3px;
    
    30
      padding: 6px;
    
    31
      opacity: 0;
    
    32
      z-index: 1;
    
    33
      transition: opacity 0.15s linear;
    
    34
      pointer-events: none;
    
    35
    }
    
    36
    37
    .chart-wrapper .chart-x span:hover::before,
    
    38
    .chart-wrapper .chart-x span:hover::after {
    
    39
      opacity: 1;
    
    40
    }
    
    41
    42
    @media screen and (max-width: 700px) {
    
    43
      .chart-wrapper .chart-x span::before,
    
    44
      .chart-wrapper .chart-x span::after {
    
    45
        display: none;
    
    46
      }
    
    47
    }
    

    Conclusão

    Pronto, pessoal! Hoje, praticamos nosso conhecimento de CSS construindo um gráfico de bolhas totalmente funcional. Embora não seja o método mais popular para visualizar dados, esperamos que tenha lugar em um de seus futuros projetos de visualização de dados.

    Vamos nos lembrar do que construímos:

    Como sempre, obrigado pela leitura!

    Deixe uma resposta