4

In recent release salesforce has released progress ring part of SLDS. https://www.lightningdesignsystem.com/components/progress-ring/#content I am little confused on how to use this with lightning component. My requirement is to show some kind of progress depending on Goal and actual values. Below is the code to start with. I can see the circle with green border. I had to add code into renderer to remove cDATA tags as lightning is not allowing to put the svg directly in the component. (I know there is a separate svg helper file but I am not sure how to reference the icon from the helper file into component so keeping directly into component.)

I think i need to be able to update the d in the path dynamically for this to work.

Any suggestions are welcome!

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome" access="global">
    <div class="slds-progress-ring">
        <div class="slds-progress-ring__progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="58">
            <div aura:id="svg_content">
                <![CDATA[
                    <svg viewBox="-1 -1 2 2">
                        <path class="slds-progress-ring__path" id="slds-progress-ring-path" d="M 1 0 A 1 1 0 1 1 0.7289686274214112 -0.684547105928689 L 0 0" />
                    </svg>
                ]]>
            </div>
        </div>
        <div class="slds-progress-ring__content"></div>
    </div>

</aura:component>

Renderer

({
    // Your renderer method overrides go here

    afterRender: function(component, helper) {
        var svg = component.find("svg_content");
        var value = svg.getElement().innerText;
        value = value.replace("<![CDATA[", "").replace("]]>", "");
        svg.getElement().innerHTML = value;        
    }

})
1
  • 1
    Ideally, wait until Summer '18. SLDS tends to be about one release ahead of the Lightning Component system. if you work around it now, you'll just end up having to replace it later.
    – sfdcfox
    Commented Feb 22, 2018 at 18:38

2 Answers 2

6

You need to use custom rendering. This is not a complete example (it doesn't show any icons/variants), but this will get you started:


Component

<aura:component >
    <aura:attribute name="value" type="Integer" default="0" />
    <aura:handler name="init" value="{!this}" action="{!c.updateView}" />
    <aura:handler name="change" value="{!v.value}" action="{!c.updateView}" />
    <div class="slds-progress-ring">
        <div id="progressContainer" class="slds-progress-ring__progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="{!v.value}">

        </div>
        <div class="slds-progress-ring__content">
        </div>
    </div>
</aura:component>

Controller

({
    updateView: function(component, event, helper) {
        // Does nothing *now*, but would be responsible for
        // choosing the correct css class for the progress area, etc.
    }
})

Renderer

({
    // Create SVG, path, populate with default values from controller
    render: function(component, helper) {
        var result = this.superRender(),
            xmlns = "http://www.w3.org/2000/svg",
            updateContainer = result[0].querySelector("#progressContainer"),
            value = component.get("v.value"),
            dValue = "M 1 0 A 1 1 0 "+Math.floor(value / 50)+" 1 "+
                Math.cos(2 * Math.PI * value / 100)+" "+
                Math.sin(2 * Math.PI * value / 100)+" L 0 0",
            svg = document.createElementNS(xmlns,"svg"),
            path = document.createElementNS(xmlns,"path");
        svg.setAttributeNS(null,"viewBox", "-1 -1 2 2");
        path.setAttributeNS(null, "class", "slds-progress-ring__path");
        path.setAttributeNS(null, "d", dValue);
        svg.appendChild(path);
        updateContainer.appendChild(svg);
        return result;
    },
    // Update the progress bar on a rerender event
    rerender: function(component, helper) {
        var value = component.get("v.value"),
            dValue = "M 1 0 A 1 1 0 "+Math.floor(value / 50)+" 1 "+
                Math.cos(2 * Math.PI * value / 100)+" "+
                Math.sin(2 * Math.PI * value / 100)+" L 0 0",
            svg = component.getElement().querySelector("svg"),
            path = svg.childNodes[0];
        this.superRerender();
        path.setAttributeNS(null, "d", dValue);
    }
})

Note that this implementation uses an Integer value from 0-100. If you want to use a different scale (e.g. 0-1 floating point), adjust accordingly.

2
  • @user360 I actually did finish the icons and whatnot, so here's a gist for you with the extra details.
    – sfdcfox
    Commented Feb 23, 2018 at 17:15
  • Appreciate your efforts and help! I will check it out!
    – user360
    Commented Feb 23, 2018 at 19:06
2

There is also a great LWC implementation on Github here: https://github.com/texei/progress-ring

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .