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.