Gráfico Doughnut SVG 3D animation

Gráfico 3D em svg sem precisar de plugins de terceiros, você só vai precisar importar o JQuery para fazer a implementação de dados para cada gráfico.

HTML do gráfico.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Graphic  Doughnut SVG 3D animation</title>

  <link href="https://fonts.googleapis.com/css?family=Montserrat&display=swap" rel="stylesheet">

</head>

<body>

  <div class="container" id="inner-graphic"></div>

</body>

</html>

Segue CSS abaixo.

body {
  background-color: #101010;
  padding: 0px auto;
  margin: 0px auto;
  font-family: "Montserrat", sans-serif;
}

.container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  width: 100%;
}

@media (max-width: 768px) {
  .container {
    display: inline;
  }
}

.card-graphic {
  position: relative;
  margin: 10px;
  padding: 20px;
  height: 180px;
  background-color: #1e1b1b;
  text-align: center;
  align-items: center;
  transition: ease-in-out 300ms;
  overflow: hidden;
  min-width: 200px;
}

.card-graphic .card-title {
  z-index: 100000;
  display: block;
  position: absolute;
  bottom: 15px;
  width: 100%;
  left: 0px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.2);
  transition: ease-in-out 300ms;
}

.card-graphic:hover .card-title {
  font-size: 14px;
  font-weight: 500;
  color: #fff;
}

.card-graphic .porcent {
  position: relative;
  width: 150px;
  height: 150px;
  border-radius: 50%;
  margin: 0 auto;
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.8);
  margin-top: -154px;
  z-index: 1;
}

.card-graphic .porcent .value-graphic {
  color: rgba(255, 255, 255, 0.2);
  font-weight: 500;
  font-size: 22px;
  position: absolute;
  top: 50%;
  margin-top: -12px;
  width: 100%;
  left: 0px;
  line-height: 1;
  transition: ease-in-out 300ms;
}

.card-graphic:before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  /* background: rgba(54, 54, 54, 0.3); */
  background: linear-gradient(#282828, #1a1a1a);
  pointer-events: none;
  z-index: 1;
}

.card-graphic:hover {
  transform: translateY(-10px);
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.8);
}

.card-graphic:hover .value-graphic {
  color: #fff;
  font-size: 28px;
  margin-top: -16px;
  font-weight: 600;
}

.card-graphic svg {
  position: relative;
  width: 150px;
  height: 150px;
  z-index: 1000;
  box-shadow: 0 15px 15px rgba(30, 29, 29, 0.43);
  overflow: hidden;
  border-radius: 100px;
}

.card-graphic svg circle {
  background-color: transparent;
  width: 80%;
  height: 80%;
  fill: none;
  stroke: #191919;
  stroke-width: 8;
  stroke-linecap: round;
  transform: translate(5px, 5px);
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.8);
}

.card-graphic svg circle:nth-child(2) {
  stroke-dasharray: 440;
  stroke-dashoffset: 440;
  transition: ease-in-out 1s;
}

.card-graphic:nth-child(1) svg circle:nth-child(2) {
  stroke: #00ff43;
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.8);
}

.card-graphic:nth-child(2) svg circle:nth-child(2) {
  stroke: #0ebff5;
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.8);
}

.card-graphic:nth-child(3) svg circle:nth-child(2) {
  stroke: rgba(255, 0, 0, 0.92);
  box-shadow: 0 15px 35px rgba(0, 0, 0, 0.8);
}

Agora sim o script que faz toda mágica da animação e que faz população dos dados nos gráficos.
Nele você vai encontrar uma variável do tipo Boolean que já está vindo setada como “false” para já fazer a animação assim que a página for carregada, caso ela for “true” o gráfico só irá fazer a animação quando o usuário passar o mouse em cada gráfico.

Maneiro né? Se gostou comenta embaixo ou se tiver alguma sugestão ou melhorias também. 😀

let validaFunction = false;

data = [
  {
    value: 85,
    title: "JavaScript"
  },
  {
    value: 33,
    title: "NodeJs"
  },
  {
    value: 57,
    title: "Angular"
  }
];

let functionMouse = 'onmouseover = "mouseHover(this);"';

if (validaFunction == true) {
  functionMouse = functionMouse;
} else {
  functionMouse = "";
  animationGraphic();
}

let divGraphic = $("#inner-graphic");

data.forEach(element => {
  let valor = element.value;
  let titulo = element.title;
  let tempGraphic = "";

  tempGraphic += `            
                <div class="card-graphic" ${functionMouse}>
                    <svg>
                        <circle cx="70" cy="70" r="70"></circle>
                        <circle cx="70" cy="70" r="70" class="get-value" value="${valor}" style="stroke-dashoffset:calc( 440 - ( 440 * 0 ) / 100 );"></circle>
                    </svg>

                    <div class="porcent">
                        <div class="value-graphic">${valor}%</div>
                    </div>

                    <div class="card-title">${titulo}</div>
                </div>
            `;

  divGraphic.append(tempGraphic);
});

function mouseHover(e) {
  let getAttrValue = $(e)
    .find($(".get-value"))
    .attr("value");
  let insertValue = $(e).find($(".get-value"));

  if (getAttrValue != 0)
    insertValue.attr(
      "style",
      "stroke-dashoffset:calc( 440 - ( 440 * " + getAttrValue + " ) / 100 )"
    );
}

function animationGraphic() {
  setTimeout(() => {
    let getDivGraphic = $(".get-value");

    getDivGraphic.each((index, element) => {
      let getAttrValue = $(element).attr("value");
      let insertValue = $(element);

      insertValue.attr(
        "style",
        "stroke-dashoffset:calc( 440 - ( 440 * " + getAttrValue + " ) / 100 )"
      );
    });
  }, 500);
}

Segue o link para visualizar o gráfico funcionando.

CLIQUE AQUI


Compartilhe este artigo com seus amigos!