Incorporating a dynamic fill effect into an SVG pie chart

I am looking to animate a pie chart with a variable value that is unknown upon loading. Assuming I fetch the value promptly and convert it into a rounded percentage :

var percentage = Math.round(sum * 100 / total);

Next, I place this value here :

<div class="pie animated" id="pie-get-percentage"></div>

$('#pie-get-percentage').html(percentage);

SVG

$(document).ready(function() {
    $('#pie-get-percentage').html(percentage);

    function $$(selector, context) {
        context = context || document;
        var elements = context.querySelectorAll(selector);
        return Array.prototype.slice.call(elements);
    }

    $$('.pie').forEach(function(pie) {
        var p = parseFloat(pie.textContent);
        var NS = "http://www.w3.org/2000/svg";
        var svg = document.createElementNS(NS, "svg");
        var circle = document.createElementNS(NS, "circle");
        var title = document.createElementNS(NS, "title");

        circle.setAttribute("r", 16);
        circle.setAttribute("cx", 16);
        circle.setAttribute("cy", 16);
        circle.setAttribute("stroke-dasharray", p + " 100");

        svg.setAttribute("viewBox", "0 0 32 32");
        title.textContent = pie.textContent;
        pie.textContent = '';
        svg.appendChild(title);
        svg.appendChild(circle);
        pie.appendChild(svg);
    });

});

CSS

.pie-wrapper {
    .pie {
        width: 100px;
        height: 100px;
        display: inline-block;
        margin: 10px;
        transform: rotate(-90deg);
    }
    svg {
        background: $primary;
        border-radius: 50%;
    }
    circle {
        fill: $primary;
        stroke: $secondary;
        stroke-width: 32;
    }
    @keyframes grow {
        to {
            stroke-dasharray: 100 100
        }
    }
    .pie.animated {
        animation: grow 2s linear;
    }
}

I previously believed that adjusting the .pie.animated CSS properties would allow me to animate up to the dynamic value, but so far, only the full circle has been animated.

Essentially, if my value is 42%, I aim to expand my circle to reflect 42% of the SVG. However, my challenge lies in applying a dynamic value to the CSS animation. It is possible that using inline CSS might be necessary, but I am uncertain if it can be utilized for animation keyframes.

The JSFiddle link is available here

Answer №1

After experimenting with the JQuery portion of your JSFiddle, here is what I came up with.

<div class="pie">60%</div>

<div class="pie">90%</div>

<div class="pie">12%</div>

The concept is straightforward—I utilized a JavaScript interval timer to invoke the count function repeatedly. Additionally, I introduced variables such as max-val, inc-val, and others to facilitate its functionality.

function $$(selector, context) {
    context = context || document;
    var elements = context.querySelectorAll(selector);
    return Array.prototype.slice.call(elements);
} 

function count(){
    var isUsed = false;
 $$('.pie').forEach(function(pie) {
    var p = parseFloat(pie.textContent);

    if(pie.maxValue == null){
         pie.maxValue = p;
         pie.incValue = p / 100.0;
         pie.lastValue = 0;
    }
    else
        pie.lastValue = pie.lastValue + pie.incValue;

   if(pie.lastValue <= pie.maxValue){
        var NS = "http://www.w3.org/2000/svg";
        var svg = document.createElementNS(NS, "svg");
        var circle = document.createElementNS(NS, "circle");
        var title = document.createElementNS(NS, "title");

        circle.setAttribute("r", 16);
        circle.setAttribute("cx", 16);
        circle.setAttribute("cy", 16);
        circle.setAttribute("stroke-dasharray", pie.lastValue + " 100");

        svg.setAttribute("viewBox", "0 0 32 32");
        title.textContent = pie.textContent;
        pie.textContent = '';
        svg.appendChild(title);
        svg.appendChild(circle);
        pie.appendChild(svg);

       isUsed = true;
   }

});
    if(isUsed)
        window.setTimeout(function() {  count(); }, 30);
}

window.setTimeout(function() {  count(); }, 30);

count();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error encountered when attempting to retrieve token from firebase for messaging

I am currently working on implementing web push notifications using Firebase. Unfortunately, when attempting to access messaging.getToken(), I encounter an error stating "messaging is undefined." Below is the code snippet I am utilizing: private messaging ...

The legend color in a JavaFX StackedBarChart does not adhere to the chart color CSS styling

Within my application, using JDK version 1.8u51, I need to assign specific colors to different data categories in a StackedBarChart. To accomplish this, I have created the following CSS: .root{ -fx-ok-color: darkgreen; -fx-critical-color: darkblue ...

Switch between divs based on the current selection

var header = $("#accordion"); $.each(data, function () { header.append("<a id='Headanchor' href='javascript:toggleDiv($(this));'>" + this.LongName + "</a>" + "<br />", "&l ...

Show detailed information in a table cell containing various arrays using AngularJS

After integrating d3.js into my code, I now have an array with key-value pairs. Each team is assigned a key and its corresponding cost is the value. When I check the console log, it looks like this: Console.log for key and value Rate for current month [{ ...

Observable task queuing

Here's the scenario: In my application, the user can tap a button to trigger a task that takes 2 seconds to complete. I want to set up a queue to run these tasks one after another, in sequence. I am working with Ionic 3 and TypeScript. What would be ...

Unleashing the power of Sinon: a guide to covertly observing the e

I need to verify if the method "res.render" is invoked with the correct parameters. it("Checks if the page for creating a new user is rendered", done => { const spy = sinon.spy(ejs, "render"); chai .request(app) .get("/users/create ...

Properly setting up event handling for a file input and Material UI Button

In my attempt to create a customized form using material UI elements, I am facing an issue. The form allows users to upload files and add notes for each option, which are stored in an array in the component's state. Here is a simplified version of th ...

Tips for adjusting the placeholder color in Material UI using React JS

Is there a way to customize the background color and flashing color of the Skeleton component in Material UI? I would like to implement custom styling for it, similar to what is shown below: <Skeleton variant="circle" classes={{root:'pla ...

Instructions for connecting a button and an input field

How can I connect a button to an input field? My goal is to make it so that when the button is clicked, the content of the text field is added to an array (displayed below) const userTags = []; function addTags(event) { userTags.push(event.target.__ wha ...

Declaring an object in the form of a function

I need some assistance with calling a method that is declared like an object in the following code. What approach should I take to call the function properly? var draw = function() { anotherFunction(); } draw(); Upon execution, an error stating "Typ ...

Troubleshooting Guide: Issues with Bootstrap 3 Modal Window Implementation

This question is so simple that it's embarrassing. I attempted to copy the code from http://getbootstrap.com/javascript/#modals directly into a basic page setup, but it's not functioning. It seems like I'm making a very silly mistake. Here i ...

What is the best way to create a clickable button link using PHP echo?

Whenever I click the button, it always redirects to just story.php, ignoring all other details. I attempted using JavaScript but I found that utilizing form action is the closest method for me to accomplish this: <form action='./story.php?u=$id&a ...

Struggling to comprehend certain sections of code within AngularJS

I have been working through an AngularJS book to learn, but I am struggling with some code that is not well explained. The selectCategory() function is included in the ng-click directive like this: <a ng-click="selectCategory()">Home</a> < ...

Tips for implementing a method to switch CSS properties of a main container by using a checkbox within its child element in a Svelte component

It took me a while to figure this out, but I still feel like my implementation is not ideal. I'm confused as to why things break when I remove the checkedActivities.has(activity) ? "checked" : "unchecked", because I thought TypeScr ...

Dynamic HTML element

I created an input number field and I want to dynamically display the value of this field in a container without having to refresh the page. I am currently using ajax for this purpose, but unfortunately, I still need to reload the page. HTML: < ...

Monitoring individual elements of an array within an Angular service

Is there a way to monitor changes in an array element within a service? Let's consider the following scenario with CartController and ProductListService. Within the ProductListService, data is fetched as follows: /** * Fetch all the products in us ...

Inform the user that an error has occurred when attempting to perform an invalid

While using redux promise middleware for my front end, I am wondering about the correct status code to throw from my backend in case of an error. I know that I can use res.status(500).json(something), but is 500 the appropriate code for all types of erro ...

With the power of jQuery, easily target and retrieve all label elements within a specified

Currently, I'm working on developing a function that should be executed whenever any of the labels for a particular group of radio buttons are clicked. So, I need a way to reference all the labels in this radio button group. In my search for a soluti ...

What is the most efficient way to use jQuery to retrieve the count of tags associated with a variable

I am trying to filter my data retrieved from ajax using a function. Here is the initial code: var csvf = data.filter(function (el) { return ['TRUCK_CPX'].indexOf(el.TAG) >= 0 && ['CA5533'].indexOf(el.Chave) >= 0 }); Now ...

Difficulty in accessing controller data in AngularJS with ng-repeat

I am trying to display comments using ng-repeat in a section, but I am having trouble accessing the data. Even after debugging, I cannot access the data without modifying the controller. I am new to Angular and prone to making mistakes. HTML / JS &apo ...