{"id":5861,"date":"2016-12-20T19:16:10","date_gmt":"2016-12-20T19:16:10","guid":{"rendered":"http:\/\/www.jitendrazaa.com\/blog\/?p=5861"},"modified":"2017-05-11T01:09:00","modified_gmt":"2017-05-11T01:09:00","slug":"circular-progress-bar-with-conditional-theme-salesforce-lightning-component","status":"publish","type":"post","link":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/circular-progress-bar-with-conditional-theme-salesforce-lightning-component\/","title":{"rendered":"Circular Progress Bar with Conditional Theme \u2013 Salesforce Lightning Component"},"content":{"rendered":"<p style=\"text-align: justify;\">Just after two days of writing\u00a0<strong><a href=\"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/circular-progress-bar-salesforce-lightning-component\/\">Circular Progress Bar<\/a><\/strong> , came up with few more requirements. So, In this post, will share updated code of Circular Progress Bar. This component can be easily used from Lightning App Builder, <a href=\"https:\/\/www.youtube.com\/watch?v=3TUZOvTDkMA\">check this video to get an idea on how it can be used and configured<\/a>.<\/p>\n<p style=\"text-align: justify;\">Complete source code of this component is available on <a href=\"https:\/\/github.com\/JitendraZaa\/LightningExamples\/tree\/master\/Circular%20Progress%20Bar\">my git repository<\/a>. <a href=\"https:\/\/github.com\/JitendraZaa\">Make sure to follow me to get updated by other free source codes<\/a>. \ud83d\ude42<\/p>\n<p style=\"text-align: justify;\">In additional to all previous capabilities, below features are added:<\/p>\n<ol>\n<li style=\"text-align: justify;\">Conditional Theme &#8211; Let&#8217;s say before 50% progress bar should be displayed as red and after 50% green.<\/li>\n<li style=\"text-align: justify;\">Threshold &#8211; On basis of this value, theme will change<\/li>\n<li style=\"text-align: justify;\">Added one more theme &#8211; red<\/li>\n<li style=\"text-align: justify;\">We can show value inside component in three format now &#8211; percentage, Actual value or Mix<\/li>\n<li style=\"text-align: justify;\">Legend font size changes according to size of component<\/li>\n<\/ol>\n<p><!--more--><\/p>\n<p><strong>Apex class &#8211; CircularProgressController<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\/**\r\n * Author\t:\tJitendra Zaa\r\n * Desc\t\t:\tController class for LEX component CircularProgress.\r\n * \t\t\t:\tOn the basis of field API name passed, it calculates percentage of completion.\r\n * *\/\r\npublic class CircularProgressController {    \r\n    \r\n    \/**\r\n     * This class is used to return as JSON Object\r\n     **\/\r\n    class WrapperJSON{\r\n        public Integer total {get;set;}\r\n        public Integer actual {get;set;}\r\n        public Integer val {get;set;}\r\n    }\r\n    \r\n    @AuraEnabled\r\n    public static String computePercentage(String sObjectName, String recordId, String totalValueFieldName, String actualValueFieldName){\r\n        Integer retVal = 0 ;\r\n        String query = null;\r\n        WrapperJSON retObj = new WrapperJSON();\r\n        \r\n        if(totalValueFieldName != null &amp;&amp; totalValueFieldName.trim() != '' &amp;&amp;  actualValueFieldName != null &amp;&amp; actualValueFieldName.trim() != '' ){\r\n            query = 'SELECT '+totalValueFieldName+', '+actualValueFieldName+' FROM '+sObjectName+' WHERE Id =: recordId';\r\n        }\r\n        else if (actualValueFieldName != null &amp;&amp; actualValueFieldName.trim() != '' ) {\r\n            query = 'SELECT '+actualValueFieldName+' FROM '+sObjectName+' WHERE Id =: recordId';\r\n        }\r\n        \r\n        if(query != null){\r\n            try{\r\n                List&lt;SOBject&gt; lstObj = Database.query(query);\r\n                if(lstObj.size() &gt; 0){\r\n                    Decimal totalVal = 0;\r\n                    Decimal actualVal = 0; \r\n                    \r\n                    if(totalValueFieldName != null &amp;&amp; totalValueFieldName.trim() != ''){ \r\n                        totalVal = Decimal.valueOf(String.valueOf(lstObj&#x5B;0].get(totalValueFieldName)));\r\n                        retObj.total = Integer.valueOf(totalVal) ; \r\n                    } \r\n                    actualVal = Decimal.valueOf(String.valueOf(lstObj&#x5B;0].get(actualValueFieldName)));                     \r\n                    \/\/Means only 1 API Name was supplied and field type is percentage\r\n                    if(totalVal == 0){\r\n                        retObj.val = Integer.valueOf(actualVal) ; \r\n                        retObj.actual = Integer.valueOf(actualVal) ;  \r\n                    }else if (actualVal &gt; 0){\r\n                        retObj.val = Integer.valueOf( ( actualVal \/ totalVal ) * 100 );   \r\n                        retObj.actual = Integer.valueOf(actualVal) ;  \r\n                    } \r\n                }\r\n            }catch(Exception e){}\r\n            \r\n        }         \r\n        return JSON.serialize(retObj) ;        \r\n    }\r\n}\r\n<\/pre>\n<p>Test class &#8211; <strong>CircularProgressControllerTest (96%)<\/strong><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n\r\n\/**\r\n* Author : Jitendra Zaa\r\n* Desc : Test class for Apex - CircularProgressController\r\n* *\/\r\n@isTest\r\npublic class CircularProgressControllerTest {\r\n\r\n@testSetup static void methodName() {\r\nOpportunity opp = new Opportunity(Name='Circular Progress bar Test',Amount=80,Probability=60,stageName='In Progress',CloseDate=Date.today().addMonths(2));\r\ninsert opp;\r\n}\r\n\r\n\/**\r\n* Below test method creates dynamic SOQL on the basis of two field API provided\r\n* *\/\r\n@isTest\r\nstatic void testUsingFields(){\r\nOpportunity opp = &#x5B;SELECT Id, Amount, ExpectedRevenue FROM Opportunity];\r\nString retVal = CircularProgressController.computePercentage('Opportunity',Opp.id,'Amount','ExpectedRevenue');\r\n\r\nCircularProgressController.WrapperJSON retPOJO = (CircularProgressController.WrapperJSON)JSON.deserialize(retVal, CircularProgressController.WrapperJSON.class);\r\nSystem.assertEquals(retPOJO.actual, 48) ;\r\nSystem.assertEquals(retPOJO.total, 80) ;\r\nSystem.assertEquals(retPOJO.val, 60) ;\r\n}\r\n\r\n\/**\r\n* Below test method creates dynamic SOQL on the basis of single field considering it as\r\n* percentage type of field\r\n* *\/\r\n@isTest\r\nstatic void testUsingSingleField(){\r\nOpportunity opp = &#x5B;SELECT Id, Amount, ExpectedRevenue FROM Opportunity];\r\nString retVal = CircularProgressController.computePercentage('Opportunity',Opp.id,'','Amount');\r\n\r\nCircularProgressController.WrapperJSON retPOJO = (CircularProgressController.WrapperJSON)JSON.deserialize(retVal, CircularProgressController.WrapperJSON.class);\r\nSystem.assertEquals(retPOJO.actual, 80) ;\r\nSystem.assertEquals(retPOJO.total, null) ;\r\nSystem.assertEquals(retPOJO.val, 80) ;\r\n}\r\n\r\n}\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>CircularProgress.cmp<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;aura:component implements=&quot;flexipage:availableForAllPageTypes, flexipage:availableForRecordHome, force:hasRecordId, force:hasSObjectName&quot; access=&quot;global&quot; controller=&quot;CircularProgressController&quot;&gt;\r\n    \r\n    &lt;aura:attribute name=&quot;recordId&quot; type=&quot;Id&quot; description=&quot;Id of record on which this component is hosted.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;sObjectName&quot; type=&quot;String&quot; description=&quot;API name of record on which this component is hosted.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;resultFormat&quot; type=&quot;String&quot; default=&quot;Percentage&quot; description=&quot;Format of result to be displayed inside Circular Progress Bar. Allowed values are Percentage, Actual Number, Mix.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;Legend&quot; type=&quot;String&quot; description=&quot;Legend to display&quot; \/&gt;\r\n    \r\n\t&lt;aura:attribute name=&quot;perText&quot; type=&quot;String&quot; default=&quot;0%&quot; description=&quot;Text to display inside circle. It is auto calculated field and used internally.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;cirDeg&quot; type=&quot;String&quot; default=&quot;0&quot; description=&quot;Degree of Progress to show. It is auto calculated field and used internally.&quot; \/&gt;\r\n    \r\n    &lt;aura:attribute name=&quot;totalProgress&quot; type=&quot;String&quot; default=&quot;100&quot; description=&quot;Total progress. It can be number OR API name of field.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;actualProgress&quot; type=&quot;String&quot; default=&quot;50&quot; description=&quot;Actual progress. It can be number OR API name of field.&quot; \/&gt;\r\n    \r\n    &lt;aura:attribute name=&quot;themeBeforeThreshold&quot; type=&quot;String&quot; default=&quot;green&quot; description=&quot;Theme of Circular Progress Bar. Possible values are blue, green, orange.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;themeAfterThreshold&quot; type=&quot;String&quot; default=&quot;red&quot; description=&quot;Theme of Circular Progress Bar. Possible values are blue, green, orange.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;theme&quot; type=&quot;String&quot; default=&quot;green&quot; description=&quot;Internally used attribute to decide final theme on basis of threshold value&quot;\/&gt;  \r\n     \r\n    &lt;aura:attribute name=&quot;size&quot; type=&quot;String&quot; default=&quot;small&quot; description=&quot;Size of Circular Progress Bar. Possible values are small, medium, big.&quot; \/&gt;\r\n    &lt;aura:attribute name=&quot;threshold&quot; type=&quot;String&quot; default=&quot;50&quot; description=&quot;This field can be used to support multiple theme after threshold value&quot; \/&gt; \r\n    &lt;aura:handler name=&quot;init&quot; value=&quot;{!this}&quot; action=&quot;{!c.doInit}&quot;\/&gt;\r\n      \r\n\r\n&lt;div class=&quot;clearFloats slds-align--absolute-center&quot;&gt;\r\n\r\n&lt;div class=&quot;{! ( v.cirDeg &gt;\r\n 179 ) ? 'container p50plus '+v.theme+' '+v.size : 'container '+v.theme +' '+v.size }&quot;&gt;\r\n            &lt;span&gt;\r\n                &lt;aura:if isTrue=&quot;{! v.resultFormat == 'Percentage' }&quot;&gt;\r\n                    {!v.perText} \r\n                &lt;\/aura:if&gt; \r\n                &lt;aura:if isTrue=&quot;{! v.resultFormat == 'Actual Number' }&quot;&gt;\r\n                    {!v.actualProgress} \r\n                &lt;\/aura:if&gt; \r\n                &lt;aura:if isTrue=&quot;{! v.resultFormat == 'Mix' }&quot;&gt;\r\n                    {!v.actualProgress}\/{!v.totalProgress} \r\n                &lt;\/aura:if&gt;  \r\n                             \r\n            &lt;\/span&gt;\r\n            \r\n\r\n&lt;div class=&quot;slice&quot;&gt;\r\n\r\n&lt;div class=&quot;bar&quot; style=&quot;{! '-webkit-transform: rotate('+v.cirDeg+'deg); -moz-transform: rotate('+v.cirDeg+'deg); -ms-transform: rotate('+v.cirDeg+'deg); -o-transform: rotate('+v.cirDeg+'deg); transform: rotate('+v.cirDeg+'deg); -ms-transform: rotate('+v.cirDeg+'deg);'}&quot;&gt;&lt;\/div&gt;\r\n\r\n\r\n&lt;div class=&quot;fill&quot;&gt;&lt;\/div&gt;\r\n            &lt;\/div&gt;\r\n        &lt;\/div&gt;         \r\n    &lt;\/div&gt;\r\n&lt;div class=&quot;{!v.size + ' clearFloats slds-align--absolute-center legend '}&quot;&gt; \r\n        {!v.Legend}\r\n    &lt;\/div&gt;\r\n\r\n\r\n&lt;\/aura:component&gt;\r\n<\/pre>\n<p><strong>CircularProgressController.js<\/strong><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n({\r\n\tdoInit : function(component, event, helper) {\r\n\t\thelper.doInit(component, event, helper) ;\r\n\t}\r\n})\r\n<\/pre>\n<p><strong>CircularProgressHelper.js<\/strong><\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n({\r\n\tdoInit : function(component, event, helper)  {\r\n        helper.computeProgress(component, event, helper);\r\n        \r\n\t},\r\n    computeProgress : function(component, event, helper)  {\r\n \r\n        var totalVal = component.get(&quot;v.totalProgress&quot;);\r\n        var actualVal = component.get(&quot;v.actualProgress&quot;); \r\n        \r\n        var threshold = component.get(&quot;v.threshold&quot;);\r\n        var beforeTheme = component.get(&quot;v.themeBeforeThreshold&quot;);\r\n        var afterTheme = component.get(&quot;v.themeAfterThreshold&quot;);\r\n     \r\n        if(totalVal &amp;&amp; actualVal &amp;&amp; !isNaN(parseInt(totalVal)) &amp;&amp; isFinite(totalVal) &amp;&amp; !isNaN(parseInt(actualVal)) &amp;&amp; isFinite(actualVal)){\r\n           \/\/parameter is number \r\n            var percVal = parseInt(actualVal) \/ parseInt(totalVal) ;\r\n            var progressVal = parseInt(  percVal * 360  ) ;\r\n        \r\n            if((percVal * 100) &gt;= threshold){\r\n                component.set(&quot;v.theme&quot; , afterTheme );\r\n            }else{\r\n                component.set(&quot;v.theme&quot; , beforeTheme );\r\n            }\r\n    \r\n            component.set(&quot;v.cirDeg&quot; , progressVal );\r\n            component.set(&quot;v.perText&quot; , parseInt(percVal * 100)  +'%' ); \r\n        }else if(actualVal){\r\n            helper.callApexMethod(component, event, helper, totalVal, actualVal);\r\n        }else{\r\n            \/\/valuea are used directly \r\n            if(actualVal &gt;= threshold){\r\n                component.set(&quot;v.theme&quot; , afterTheme );\r\n            }else{\r\n                component.set(&quot;v.theme&quot; , beforeTheme );\r\n            }\r\n        }\r\n    },\r\n    callApexMethod : function(component, event, helper, txt_totalVal, txt_actualVal)  {\r\n        \r\n        var action = component.get('c.computePercentage');\r\n        var txt_recordId = component.get(&quot;v.recordId&quot;);\r\n        var txt_sObjectName = component.get(&quot;v.sObjectName&quot;);\r\n        \r\n        action.setParams({\r\n            recordId : txt_recordId,\r\n            sObjectName : txt_sObjectName,\r\n            totalValueFieldName : txt_totalVal,\r\n            actualValueFieldName : txt_actualVal\r\n        });\r\n        \r\n        action.setCallback(this, function(a) {\r\n            if (a.getState() === 'SUCCESS') {\r\n                var retObj =  JSON.parse(a.getReturnValue())  ; \r\n                \t\r\n                var threshold = component.get(&quot;v.threshold&quot;);\r\n        \t\tvar beforeTheme = component.get(&quot;v.themeBeforeThreshold&quot;);\r\n        \t\tvar afterTheme = component.get(&quot;v.themeAfterThreshold&quot;);\r\n                \r\n                component.set(&quot;v.totalProgress&quot; , retObj.total );\r\n                component.set(&quot;v.actualProgress&quot; , retObj.actual ); \r\n                \r\n                if( parseInt(retObj.val) &gt;= threshold){\r\n                \tcomponent.set(&quot;v.theme&quot; , afterTheme );\r\n                }else{\r\n                    component.set(&quot;v.theme&quot; , beforeTheme );\r\n                }\r\n                \r\n                var progressVal = parseInt(  (retObj.val\/100) * 360  ) ; \r\n                component.set(&quot;v.cirDeg&quot; , progressVal );\r\n                component.set(&quot;v.perText&quot; , parseInt(retObj.val)  +'%' );              \r\n            }  \r\n        });\r\n        $A.enqueueAction(action);  \r\n    }\r\n})\r\n<\/pre>\n<p><strong>CircularProgress.design<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;design:component&gt;    \r\n    &lt;design:attribute name=&quot;size&quot; label=&quot;Size&quot; datasource=&quot;small, medium, big&quot; description=&quot;Size of the of the component&quot; \/&gt;\r\n    \r\n    &lt;design:attribute name=&quot;totalProgress&quot; label=&quot;Total&quot; description=&quot;Either API Name of field Or numeric value showing total value to be used for computation&quot; \/&gt;\r\n    &lt;design:attribute name=&quot;actualProgress&quot; label=&quot;Actual&quot; description=&quot;Either API Name of field Or numeric value showing actual value to be used for computation&quot; \/&gt;\r\n     \r\n    &lt;design:attribute name=&quot;Legend&quot; label=&quot;Legend&quot; description=&quot;Legend to be displayed.&quot; \/&gt;\r\n    \r\n    &lt;design:attribute name=&quot;resultFormat&quot; label=&quot;Result Format&quot; datasource=&quot;Percentage , Actual Number, Mix&quot; description=&quot;Format of result to be displayed inside Circular Progress Bar. Allowed values are Percentage, Actual Number, Mix.&quot; \/&gt;\r\n     \r\n    &lt;design:attribute name=&quot;themeBeforeThreshold&quot; label=&quot;Theme Before Threshold&quot; datasource=&quot;blue, green , orange, red&quot; description=&quot;Theme of the component before threshold&quot; \/&gt;\r\n    \r\n    &lt;design:attribute name=&quot;themeAfterThreshold&quot; label=&quot;Theme After Threshold&quot; datasource=&quot;blue, green , orange, red&quot; description=&quot;Theme of the component After threshold&quot; \/&gt;\r\n    \r\n    &lt;design:attribute name=&quot;threshold&quot; label=&quot;Threshold after which color needs to be chaged&quot; description=&quot;This field can be used to support multiple theme after threshold value&quot; \/&gt; \r\n     \r\n&lt;\/design:component&gt;\r\n<\/pre>\n<p><strong>CircularProgress.auradocs<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;aura:documentation&gt;\r\n\t&lt;aura:description&gt;\r\n        &lt;code&gt;c:CircularProgress&lt;\/code&gt; component can be used to display progress in circular bar format.\r\n    &lt;\/aura:description&gt;\r\n     \r\n\t&lt;aura:example name=&quot;Example1&quot; label=&quot;Examples of Circular Progress Component&quot; ref=&quot;c:CircularProgressExample&quot;&gt; \r\n\t&lt;\/aura:example&gt;\r\n&lt;\/aura:documentation&gt;\r\n<\/pre>\n<p><strong>CircularProgress.css<\/strong><\/p>\n<pre class=\"brush: css; title: ; notranslate\" title=\"\">\r\n.THIS .clearFloats:before, .THIS .clearFloats:after \r\n{\r\n    content: &quot; &quot;; \r\n    display: table !important;\r\n}\r\n\r\n.THIS  .clearFloats:after {clear: both;}\r\n.THIS .clearFloats {*zoom: 1; }\r\n\r\n.THIS .container .slice , .THIS .container.p50plus .slice\r\n{\r\n\tclip: rect(auto, auto, auto, auto);\r\n}\r\n\r\n.THIS .pie, .THIS .container .bar , .THIS .fill, .THIS .container.p50plus .fill{\r\n\t position: absolute;\r\n\t  border: 0.08em solid #307bbb;\r\n\t  width: 0.84em;\r\n\t  height: 0.84em;\r\n\t  clip: rect(0em, 0.5em, 1em, 0em);\r\n\t  -webkit-border-radius: 50%;\r\n\t  -moz-border-radius: 50%;\r\n\t  -ms-border-radius: 50%;\r\n\t  -o-border-radius: 50%;\r\n\t  border-radius: 50%;\r\n\t  -webkit-transform: rotate(0deg);\r\n\t  -moz-transform: rotate(0deg);\r\n\t  -ms-transform: rotate(0deg);\r\n\t  -o-transform: rotate(0deg);\r\n\t  transform: rotate(0deg);\r\n}\r\n\r\n.THIS .pie-fill, .THIS .container.p50plus .bar:after, .THIS .container.p50plus .fill{\r\n\t -webkit-transform: rotate(180deg);\r\n\t  -moz-transform: rotate(180deg);\r\n\t  -ms-transform: rotate(180deg);\r\n\t  -o-transform: rotate(180deg);\r\n\t  transform: rotate(180deg);\r\n}\r\n\r\n.THIS .container {\r\n\t  position: relative;\r\n\t  font-size: 120px;\r\n\t  width: 1em;\r\n\t  height: 1em;\r\n\t  -webkit-border-radius: 50%;\r\n\t  -moz-border-radius: 50%;\r\n\t  -ms-border-radius: 50%;\r\n\t  -o-border-radius: 50%;\r\n\t  border-radius: 50%;\r\n\t  float: left;\r\n\t  margin: 0 0.1em 0.1em 0;\r\n\t  background-color: #cccccc;\r\n\t}\r\n\r\n.THIS .container *, .THIS .container *:before, .THIS .container *:after {\r\n\t  -webkit-box-sizing: content-box;\r\n\t  -moz-box-sizing: content-box;\r\n\t  box-sizing: content-box;\r\n\t}\r\n\r\n.THIS .container.center {\r\n\t  float: none;\r\n\t  margin: 0 auto;\r\n\t}\r\n.THIS .container.big {\r\n\t  font-size: 240px;\r\n\t}\r\n.THIS .container.small {\r\n\t  font-size: 80px;\r\n\t}\r\n.THIS .container.medium {\r\n\t  font-size: 160px;\r\n\t}\r\n\r\n.THIS .container &gt; span {\r\n\t  position: absolute;\r\n\t  width: 100%;\r\n\t  z-index: 1;\r\n\t  left: 0;\r\n\t  top: 0;\r\n\t  width: 5em;\r\n\t  line-height: 5em;\r\n\t  font-size: 0.2em;\r\n\t  color: #cccccc;\r\n\t  display: block;\r\n\t  text-align: center;\r\n\t  white-space: nowrap;\r\n\t  -webkit-transition-property: all;\r\n\t  -moz-transition-property: all;\r\n\t  -o-transition-property: all;\r\n\t  transition-property: all;\r\n\t  -webkit-transition-duration: 0.2s;\r\n\t  -moz-transition-duration: 0.2s;\r\n\t  -o-transition-duration: 0.2s;\r\n\t  transition-duration: 0.2s;\r\n\t  -webkit-transition-timing-function: ease-out;\r\n\t  -moz-transition-timing-function: ease-out;\r\n\t  -o-transition-timing-function: ease-out;\r\n\t  transition-timing-function: ease-out;\r\n\t}\r\n\r\n.THIS .container:after {\r\n\t  position: absolute;\r\n\t  top: 0.08em;\r\n\t  left: 0.08em;\r\n\t  display: block;\r\n\t  content: &quot; &quot;;\r\n\t  -webkit-border-radius: 50%;\r\n\t  -moz-border-radius: 50%;\r\n\t  -ms-border-radius: 50%;\r\n\t  -o-border-radius: 50%;\r\n\t  border-radius: 50%;\r\n\t  background-color: whitesmoke;\r\n\t  width: 0.84em;\r\n\t  height: 0.84em;\r\n\t  -webkit-transition-property: all;\r\n\t  -moz-transition-property: all;\r\n\t  -o-transition-property: all;\r\n\t  transition-property: all;\r\n\t  -webkit-transition-duration: 0.2s;\r\n\t  -moz-transition-duration: 0.2s;\r\n\t  -o-transition-duration: 0.2s;\r\n\t  transition-duration: 0.2s;\r\n\t  -webkit-transition-timing-function: ease-in;\r\n\t  -moz-transition-timing-function: ease-in;\r\n\t  -o-transition-timing-function: ease-in;\r\n\t  transition-timing-function: ease-in;\r\n\t}\r\n\r\n.THIS .container .slice {\r\n\t  position: absolute;\r\n\t  width: 1em;\r\n\t  height: 1em;\r\n\t  clip: rect(0em, 1em, 1em, 0.5em);\r\n\t}\r\n\r\n.THIS .container:hover {\r\n\t  cursor: default;\r\n\t}\r\n\r\n.THIS .container:hover &gt; span {\r\n\t  width: 3.33em;\r\n\t  line-height: 3.33em;\r\n\t  font-size: 0.3em; \r\n\t}\r\n\r\n.THIS .container:hover:after {\r\n\t  top: 0.04em;\r\n\t  left: 0.04em;\r\n\t  width: 0.92em;\r\n\t  height: 0.92em;\r\n\t}\r\n\r\n.THIS .container.blue .bar, .THIS .container.blue .fill {\r\n  border-color: #307bbb !important;\r\n}\r\n\r\n.THIS .container.blue:hover &gt; span {\r\n  color: #307bbb;\r\n}\r\n\r\n.THIS .container.green .bar, .THIS .container.green .fill {\r\n  border-color: #4db53c !important;\r\n}\r\n\r\n.THIS .container.green:hover &gt; span {\r\n  color: #4db53c;\r\n}\r\n \r\n.THIS .container.orange .bar, .THIS .container.orange .fill {\r\n  border-color: #dd9d22 !important;\r\n}\r\n\r\n.THIS .container.orange:hover &gt; span {\r\n  color: #dd9d22;\r\n}\r\n.THIS .container.red .bar, .THIS .container.red .fill {\r\n  border-color: #ff0000 !important;\r\n}\r\n\r\n.THIS .container.red:hover &gt; span {\r\n  color: #ff0000;\r\n}\r\n\r\n.THIS.legend{ \r\n    color: rgb(22, 50, 92);\r\n    font-weight: bold;\r\n}\r\n.THIS.legend.big{\r\n    font-size: 1.25rem;\r\n    color: rgb(22, 50, 92);\r\n}\r\n.THIS.legend.medium{\r\n    font-size: 1.0rem;\r\n    color: rgb(22, 50, 92);\r\n}\r\n.THIS.legend.small{\r\n    font-size: 0.7rem; \r\n    color: rgb(22, 50, 92);\r\n}\r\n<\/pre>\n<p><strong>CircularProgressExample.cmp<\/strong><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;aura:component &gt;    \r\n\r\n&lt;div class=&quot;slds-grid slds-p-top--xx-large&quot;&gt;\r\n\r\n&lt;div class=&quot;slds-col&quot;&gt;\r\n            &lt;c:CircularProgress themeAfterThreshold=&quot;blue&quot; themeBeforeThreshold=&quot;red&quot; size=&quot;medium&quot; totalProgress=&quot;100&quot; actualProgress=&quot;65&quot; Legend=&quot;Result format Percentage&quot; resultFormat=&quot;Percentage&quot; threshold=&quot;50&quot;\/&gt;              \r\n        &lt;\/div&gt;\r\n\r\n&lt;div class=&quot;slds-col&quot;&gt;\r\n            &lt;c:CircularProgress themeAfterThreshold=&quot;orange&quot; themeBeforeThreshold=&quot;red&quot; size=&quot;medium&quot; totalProgress=&quot;100&quot; actualProgress=&quot;35&quot; Legend=&quot;Result format Actual Number&quot; resultFormat=&quot;Actual Number&quot; threshold=&quot;25&quot; \/&gt;  \r\n        &lt;\/div&gt;\r\n\r\n&lt;div class=&quot;slds-col&quot;&gt;\r\n            &lt;c:CircularProgress themeAfterThreshold=&quot;green&quot; themeBeforeThreshold=&quot;red&quot; size=&quot;medium&quot; totalProgress=&quot;90&quot; actualProgress=&quot;24&quot; Legend=&quot;Result format Mix&quot; resultFormat=&quot;Mix&quot; threshold=&quot;10&quot; \/&gt;  \r\n        &lt;\/div&gt;\r\n\r\n&lt;div class=&quot;slds-col&quot;&gt;\r\n            &lt;c:CircularProgress themeAfterThreshold=&quot;green&quot; themeBeforeThreshold=&quot;red&quot; size=&quot;medium&quot; totalProgress=&quot;90&quot; actualProgress=&quot;24&quot; Legend=&quot;Threshold Second theme in Action&quot; resultFormat=&quot;Mix&quot; threshold=&quot;30&quot; \/&gt;  \r\n        &lt;\/div&gt;\r\n    &lt;\/div&gt;   \r\n&lt;\/aura:component&gt;\r\n<\/pre>\n<p><strong>Output :<\/strong><\/p>\n<figure id=\"attachment_5864\" aria-describedby=\"caption-attachment-5864\" style=\"width: 1200px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Circuar-Progress-Bar-v2-1.gif?ssl=1\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-5864\" src=\"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Circuar-Progress-Bar-v2-1.gif?resize=1200%2C272&#038;ssl=1\" alt=\"Circular Progress Bar with multiple color\" width=\"1200\" height=\"272\" \/><\/a><figcaption id=\"caption-attachment-5864\" class=\"wp-caption-text\">Circular Progress Bar with multiple color<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Salesforce Lightning Component &#8211; Circular Progress Bar with Conditional Theme. Ready to be used by Developers and Admins on App builder for any object. No External Javascript Library, Lightweight CSS based.<\/p>\n","protected":false},"author":1,"featured_media":5862,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"jz_research_post":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[9],"tags":[311],"class_list":["post-5861","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-salesforce","tag-lightning-component"],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Circuar-Progress-Bar-v2.gif?fit=1200%2C272&ssl=1","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":5852,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/how-to-document-lightning-component\/","url_meta":{"origin":5861,"position":0},"title":"How to Document Lightning Component","author":"Jitendra","date":"December 19, 2016","format":false,"excerpt":"Demo and Example, showing process of documenting Lightning Component","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Documentaing Lightning Component","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Documentaing-Lightning-Component.gif?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Documentaing-Lightning-Component.gif?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Documentaing-Lightning-Component.gif?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Documentaing-Lightning-Component.gif?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Documentaing-Lightning-Component.gif?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":5843,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/circular-progress-bar-salesforce-lightning-component\/","url_meta":{"origin":5861,"position":1},"title":"Circular Progress Bar &#8211; Salesforce Lightning Component","author":"Jitendra","date":"December 19, 2016","format":false,"excerpt":"Demo and Complete Source code of Circular Progress Bar, Salesforce Lightning Component","rel":"","context":"In &quot;Lightning&quot;","block_context":{"text":"Lightning","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/lightning\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/12\/Circular-Progress-Bar.gif?fit=332%2C720&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":6298,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/salesforce-winter-18-release-my-favorite-features\/","url_meta":{"origin":5861,"position":2},"title":"Salesforce Winter 18 Release \u2013 My Favorite Features","author":"Jitendra","date":"October 4, 2017","format":false,"excerpt":"My favorite Salesforce Winter 18 features about Lightning, Flow, Platform Event , Shield and Salesforce DX","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Flow in Salesforce App Builder","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/10\/Flow-in-Salesforce-App-Builder.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/10\/Flow-in-Salesforce-App-Builder.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/10\/Flow-in-Salesforce-App-Builder.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/10\/Flow-in-Salesforce-App-Builder.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":5796,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/lightning-data-services-standard-controller-for-lightning-components\/","url_meta":{"origin":5861,"position":3},"title":"Lightning Data Service &#8211; Standard Controller for Lightning Components","author":"Jitendra","date":"July 22, 2017","format":false,"excerpt":"Best Practices for Salesforce Lightning Component. How Lightning Data Service can improve Lightning Component performance and solve inconsistent data problem without writing single line of Apex code. Demo source code, image and slides included.","rel":"","context":"In &quot;Apex&quot;","block_context":{"text":"Apex","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/apex\/"},"img":{"alt_text":"Salesforce Lightning Data Services","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/07\/Salesforce-Lightning-Data-Services.png?fit=1045%2C395&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/07\/Salesforce-Lightning-Data-Services.png?fit=1045%2C395&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/07\/Salesforce-Lightning-Data-Services.png?fit=1045%2C395&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/07\/Salesforce-Lightning-Data-Services.png?fit=1045%2C395&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":6252,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/salesforce-path-read-only-lightning-component\/","url_meta":{"origin":5861,"position":4},"title":"Salesforce Path &#8211; Read Only Lightning Component","author":"Jitendra","date":"September 17, 2017","format":false,"excerpt":"Chevron Component build in Lightning with Same look and feel as of Salesforce Path in read only mode","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Read only Path (Chevron) Component in Salesforce Lightning","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/09\/Chevron-Lightning-Component-Salesforce.gif?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/09\/Chevron-Lightning-Component-Salesforce.gif?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/09\/Chevron-Lightning-Component-Salesforce.gif?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2017\/09\/Chevron-Lightning-Component-Salesforce.gif?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":5109,"url":"https:\/\/www.jitendrazaa.com\/blog\/salesforce\/lightning-component-for-wikipedia-search\/","url_meta":{"origin":5861,"position":5},"title":"Lightning Component for Wikipedia search","author":"Jitendra","date":"January 6, 2016","format":false,"excerpt":"Initially I thought creating Wikipedia Search component will be straight forward. I can simply use AJAX request from Lightning component to get result from Wikipedia using its REST API. Soon, I discovered about Content Security Policy\u00a0in Lightning components developer guide. If we attempt to use AJAX or REST API in\u2026","rel":"","context":"In &quot;Salesforce&quot;","block_context":{"text":"Salesforce","link":"https:\/\/www.jitendrazaa.com\/blog\/category\/salesforce\/"},"img":{"alt_text":"Salesforce Lightning Component for Wikipedia Search","src":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/01\/Salesforce-Lightning-Component-for-Wikipedia-Search.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/01\/Salesforce-Lightning-Component-for-Wikipedia-Search.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/01\/Salesforce-Lightning-Component-for-Wikipedia-Search.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.jitendrazaa.com\/blog\/wp-content\/uploads\/2016\/01\/Salesforce-Lightning-Component-for-Wikipedia-Search.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/5861","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/comments?post=5861"}],"version-history":[{"count":7,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/5861\/revisions"}],"predecessor-version":[{"id":6041,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/posts\/5861\/revisions\/6041"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/media\/5862"}],"wp:attachment":[{"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/media?parent=5861"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/categories?post=5861"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jitendrazaa.com\/blog\/wp-json\/wp\/v2\/tags?post=5861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}