Aguarde...

11 de dezembro de 2020

Como fazer um gráfico de área com CSS

Como fazer um gráfico de área com CSS

Você deve conhecer algumas maneiras de criar gráficos com CSS puro. Alguns deles são abordados aqui no CSS-Tricks , e muitos outros podem ser encontrados no CodePen , mas não vi muitos exemplos de “gráficos de área” (imagine um gráfico de linha com a área inferior preenchida), especialmente qualquer em HTML e CSS sozinho. Neste artigo, faremos exatamente isso, usando uma base HTML semântica e acessível.

Como fazer um gráfico de área com CSS

Vamos começar com o HTML

Para simplificar as coisas, usaremos <ul>tags como wrappers e <li>elementos para itens de dados individuais. Você pode usar qualquer outra tag HTML em seu projeto, dependendo de suas necessidades.

<ul class="area-chart">
  <li> 40% </li>
  <li> 80% </li>
  <li> 60% </li>
  <li> 100% </li>
  <li> 30% </li>
</li>

CSS não pode recuperar o texto HTML interno, é por isso que usaremos propriedades customizadas CSS para passar dados ao nosso CSS. Cada item de dados terá um --start--endpropriedades personalizadas.

<ul class="area-chart">
  <li style="--start: 0.1; --end: 0.4;"> 40% </li>
  <li style="--start: 0.4; --end: 0.8;"> 80% </li>
  <li style="--start: 0.8; --end: 0.6;"> 60% </li>
  <li style="--start: 0.6; --end: 1.0;"> 100% </li>
  <li style="--start: 1.0; --end: 0.3;"> 30% </li>
</li>

Aqui está o que precisamos considerar …

Existem vários princípios de design que devemos considerar antes de passar para o estilo:

  • Dados Unidades: Nós estaremos usando dados da unidade-less na nossa HTML (ou seja, sem pxemrem%ou qualquer outra unidade). As propriedades personalizadas --start--endserão números entre 0 e 1.
  • Largura das colunas: não definiremos um valor fixo widthpara cada <li>elemento. Também não %usaremos, pois não sabemos quantos itens existem. A largura de cada coluna será baseada na largura do wrapper principal, dividida pelo número total de itens de dados. No nosso caso, essa é a largura do <ul>elemento dividido pelo número de <li>elementos.
  • Acessibilidade: os valores dentro de cada um <li>são opcionais e apenas as propriedades personalizadas --start--endsão obrigatórias. Ainda assim, é melhor incluir algum tipo de texto ou valor para leitores de tela e outras tecnologias de assistência para descrever o conteúdo.

Agora, vamos começar a estilizar!

Vamos começar com o estilo geral do layout primeiro. O elemento do wrapper do gráfico é um flex container, exibindo itens em uma linha, estendendo cada elemento filho para que toda a área seja preenchida.

.area-chart {
  /* Reset */
  margin: 0;
  padding: 0;
  border: 0;

  /* Dimensions */
  width: 100%;
  max-width: var(--chart-width, 100%);
  height: var(--chart-height, 300px);

  /* Layout */
  display: flex;
  justify-content: stretch;
  align-items: stretch;
  flex-direction: row;
}

Se o wrapper do gráfico de área for uma lista, devemos remover o estilo de lista para nos dar mais flexibilidade de estilo.

ul.area-chart,
ol.area-chart {
  list-style: none;
}

Este código define o estilo de todas as colunas do gráfico inteiro. Com gráficos de barras é simples: usamos background-colorheightpara cada coluna. Com de char área ts vamos usar a clip-pathpropriedade para definir a região que deve ser mostrado.

Primeiro, configuramos cada coluna:

.area-chart > * {
  /* Even size items */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;

  /* Color */
  background: var(--color, rgba(240, 50, 50, .75));
}

Para criar um retângulo cobrindo toda a área, vamos pegar a clip-pathpropriedade e usar sua polygon()função contendo as coordenadas da área. Isso basicamente não faz nada no momento porque o polígono cobre tudo:

.area-chart > * {
  clip-path: polygon(
    0% 0%,     /* top left */
    100% 0%,   /* top right */
    100% 100%, /* bottom right */
    0% 100%    /* bottom left */
  );
}

Agora para a melhor parte!

Para mostrar apenas parte da coluna, nós a recortamos para criar aquele efeito de gráfico de área. Para mostrar apenas a área que queremos, usamos as propriedades personalizadas --start--enddentro do clip-pathpolígono:

.area-chart > * {
  clip-path: polygon(
    0% calc(100% * (1 - var(--start))),
    100% calc(100% * (1 - var(--end))),
    100% 100%,
    0% 100%
  );
}

Sério, esse único pedaço de CSS faz todo o trabalho. Aqui está o que temos:

Trabalhar com vários conjuntos de dados

Agora que sabemos o básico, vamos criar um gráfico de área com vários conjuntos de dados. Os gráficos de área geralmente medem mais de um conjunto de dados e o efeito é uma comparação em camadas dos dados.

Como fazer um gráfico de área com CSS

Esse tipo de gráfico requer vários elementos filho, portanto, vamos substituir nossa <ul>abordagem por um <table>.

<table class="area-chart">
  <tbody>
    <tr>
      <td> 40% </td>
      <td> 80% </td>
    </tr>
    <tr>
      <td> 60% </td>
      <td> 100% </td>
    </tr>
  </tbody>
</table>

As tabelas são acessíveis e amigáveis ​​aos motores de busca. E se a folha de estilo não carregar por algum motivo, todos os dados ainda estarão visíveis na marcação.

Novamente, usaremos as propriedades personalizadas --start--endcom números entre 0 e 1.

<table class="area-chart">
  <tbody>
    <tr>
      <td style="--start: 0; --end: 0.4;"> 40% </td>
      <td style="--start: 0; --end: 0.8;"> 80% </td>
    </tr>
    <tr>
      <td style="--start: 0.4; --end: 0.6;"> 60% </td>
      <td style="--start: 0.8; --end: 1.0;"> 100% </td>
    </tr>
  </tbody>
</table>

Portanto, primeiro definiremos o layout geral do elemento de embalagem, nossa tabela, que demos uma .area-chartclasse:

.area-chart {
  /* Reset */
  margin: 0;
  padding: 0;
  border: 0;

  /* Dimensions */
  width: 100%;
  max-width: var(--chart-width, 600px);
  height: var(--chart-height, 300px);
}

A seguir, faremos do <tbody>elemento um flex container, exibindo os <tr>itens em uma linha e dimensionados uniformemente:

.area-chart tbody {
  width: 100%;
  height: var(--chart-height, 300px);

  /* Layout */
  display: flex;
  justify-content: stretch;
  align-items: stretch;
  flex-direction: row;
}
.area-chart tr {
  /* Even size items */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 0;
}

Agora precisamos fazer com que os <td>elementos cubram uns aos outros, um elemento em cima do outro, para obtermos esse efeito em camadas. Cada um <td>cobre toda a área do <tr>elemento que o contém.

.area-chart tr {
  position: relative;
}
.area-chart td {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}

Vamos colocar os poderes mágicos do clip-path: polygon()em uso! Nós só está exibindo a área entre os --start--endpropriedades personalizadas que, novamente, são valores entre 0 e 1:

.area-chart td {
  clip-path: polygon(
    0% calc(100% * (1 - var(--start))),
    100% calc(100% * (1 - var(--end))),
    100% 100%,
    0% 100%
  );
}

Agora vamos adicionar cor a cada um:

.area-chart td {
  background: var(--color);
}
.area-chart td:nth-of-type(1) {
  --color: rgba(240, 50, 50, 0.75);
}
.area-chart td:nth-of-type(2) {
  --color: rgba(255, 180, 50, 0.75);
}
.area-chart td:nth-of-type(3) {
  --color: rgba(255, 220, 90, 0.75);
}

É importante usar cores com opacidade para obter um efeito mais agradável, e é por isso que usamos rgba()valores. Você pode usar hsla()aqui, se for assim.

E assim:

Empacotando

Não importa quantos elementos HTML adicionamos ao nosso gráfico, o layout baseado em flex garante que todos os itens tenham o mesmo tamanho. Dessa forma, precisamos apenas definir a largura do elemento do gráfico de envolvimento e os itens serão ajustados de acordo para um layout responsivo.

Postado em Blog
Escreva um comentário