function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Sylvie SerpletSylvie Serplet 

Progress bar with summary by section in Lightning Component

I would like to create a Lightning Component with a progress bar that display the next 30 days split in 4 section for weeks and summarize the number of opportunities by weeks on top. Something like this:
User-added image
If not possible in Lightning a VF page or even a report will do.
Any idea how to do it?
Thank you in advance for your help.
Sylvie
Best Answer chosen by Sylvie Serplet
Alain CabonAlain Cabon
Hello Syvie,

It is the DreamHouseApp (open source). I found the source code for the Spring 17/Summer 17.

PropertyDaysOnMarketChart
The PropertyDaysOnMarketChart component provides a visual representation of the number of days a property has been on the market. It can be used on the Property record page, or on the Property Explorer or Command Centerpages as part of a master/details interface.

https://developer.salesforce.com/blogs/developer-relations/2017/08/winter-coming-lightning.html

http://www.dreamhouseapp.io/

Source Code:

The source code for the PropertyExplorer component is included in the DreamHouse unmanaged package.

http://www.dreamhouseapp.io/installation/

User-added image
<aura:component implements="force:hasRecordId,flexipage:availableForAllPageTypes" access="global">
    
    <aura:attribute name="recordId" type="Id" />
	<aura:attribute name="property" type="Property__c" default="{Days_On_Market__c: 0}"/> 
	<aura:attribute name="formattedDateListed" type="String" /> 
	<aura:attribute name="status" type="String" /> 
    
	<force:recordPreview aura:id="service" 
                         recordId="{!v.recordId}" 
                         targetRecord="{!v.property}" 
                         fields="['Id', 'Date_Listed__c', 'Days_On_Market__c']" 
                         recordUpdated="{!c.recordUpdated}"/>
    
    <aura:handler event="ltng:selectSObject" action="{!c.recordChangeHandler}"/>

    <div>
        <lightning:layout >
        	<lightning:layoutitem class="{! 'days-block ' + v.status}">
                <div class="days">{!v.property.Days_On_Market__c}</div>days
            </lightning:layoutitem>
            <lightning:layoutitem flexibility="grow" class="chart">
                <div class="{! 'bar ' + v.status }" style="{! 'width:' + v.property.Days_On_Market__c / 90 * 100 + '%' }"/>
                <div class="axis">
                    <div><div class="legend">{!v.formattedDateListed}</div></div>
                    <div><div class="legend">30 days</div></div>
                    <div><div class="legend">60 days</div></div>
                </div>
            </lightning:layoutitem>
        </lightning:layout>
    </div>
    
</aura:component>

Controller:
({
	recordUpdated : function(component, event, helper) {
		var changeType = event.getParams().changeType;
        if (changeType === "LOADED" || changeType === "CHANGED") {
			helper.showDaysOnMarket(component);
        }
	},

   	recordChangeHandler : function(component, event) {
        var id = event.getParam("recordId");
        component.set("v.recordId", id);
        var service = component.find("service");
        service.reloadRecord();
	}

})
Helper
({
	showDaysOnMarket : function(component) {
    	var property = component.get("v.property");
        var daysOnMarket = property.Days_On_Market__c;
        var status = "green";
        if (daysOnMarket > 60) {
            status = 'red';
        } else if (daysOnMarket > 30) {
            status = 'orange'
        }
        component.set("v.status", status);
        component.set("v.formattedDateListed", new Date(property.Date_Listed__c).toLocaleString('en-US', {month: 'short', year: 'numeric', day: 'numeric'}));
	}
})
Style
.THIS .days-block {
	text-align: center;
    margin-right: 8px;
    padding: 8px 12px;
    border-radius: 0.25rem;
    border: solid 1px rgb(216, 221, 230);
} 
.THIS .days-block.red {
	color: #C23934;
    border: solid 1px #C23934;
} 

.THIS .days-block.green {
	color: #00716B;
    border: solid 1px #00716B;
} 

.THIS .days-block.orange {
	color: #FFB75D;
    border: solid 1px #FFB75D;
} 

.THIS .days {
	font-size: 32px;
	line-height: 32px;
	font-weight: 300;
    margin-right: 12px;
    margin: 0;
    padding: 0;
} 

.THIS .chart {
    position: relative;
    height: 40px;
}

.THIS .bar {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    height: 32px;
    width: 0;
    transition: all .5s ease-in-out;
    position: absolute;
    bottom: 2px;
    left: 2px;
    right: 0;
}

.THIS .bar.green {
    background-color: #00716B;
}

.THIS .bar.orange {
    background-color: #FFB75D;
}

.THIS .bar.red {
    background-color: #C23934;
}

.THIS .axis {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    bottom: 0;

}

.THIS .axis > div {
    height: 34px;
	flex: 1;
	border-bottom: solid 1px rgb(216, 221, 230);
	border-left: solid 1px rgb(216, 221, 230);
}

.THIS .axis .legend {
    margin-top: 36px;
}

SVG
 
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="88.316px" height="88.318px" viewBox="0 0 88.316 88.318" enable-background="new 0 0 88.316 88.318" xml:space="preserve">
<g id="Layer_1_copy">
	<path fill="#E9696E" d="M88.316,73.268c0,8.312-6.738,15.051-15.054,15.051H15.05C6.737,88.319,0,81.581,0,73.268V15.052
		C0,6.74,6.737,0,15.05,0h58.215c8.312,0,15.054,6.74,15.054,15.052L88.316,73.268L88.316,73.268z"/>
</g>
<g id="Layer_5">
	<g>
		<path fill="#FFFFFF" d="M68.883,35.941H19.554c-0.963,0-1.806,0.842-1.806,1.805v29.478c0,2.646,2.166,4.812,4.812,4.812h43.312
			c2.647,0,4.812-2.165,4.812-4.812V37.746C70.687,36.783,69.844,35.941,68.883,35.941z M35.797,62.41
			c0,0.722-0.48,1.203-1.203,1.203h-4.812c-0.722,0-1.203-0.481-1.203-1.203v-4.812c0-0.723,0.481-1.203,1.203-1.203h4.812
			c0.723,0,1.203,0.48,1.203,1.203V62.41z M35.797,50.379c0,0.723-0.48,1.203-1.203,1.203h-4.812c-0.722,0-1.203-0.48-1.203-1.203
			v-4.812c0-0.723,0.481-1.203,1.203-1.203h4.812c0.723,0,1.203,0.48,1.203,1.203V50.379z M47.828,62.41
			c0,0.722-0.48,1.203-1.203,1.203h-4.812c-0.723,0-1.203-0.481-1.203-1.203v-4.812c0-0.723,0.48-1.203,1.203-1.203h4.812
			c0.723,0,1.203,0.48,1.203,1.203V62.41z M47.828,50.379c0,0.723-0.48,1.203-1.203,1.203h-4.812c-0.723,0-1.203-0.48-1.203-1.203
			v-4.812c0-0.723,0.48-1.203,1.203-1.203h4.812c0.723,0,1.203,0.48,1.203,1.203V50.379z M59.859,62.41
			c0,0.722-0.481,1.203-1.203,1.203h-4.812c-0.722,0-1.202-0.481-1.202-1.203v-4.812c0-0.723,0.48-1.203,1.202-1.203h4.812
			c0.722,0,1.203,0.48,1.203,1.203V62.41z M59.859,50.379c0,0.723-0.481,1.203-1.203,1.203h-4.812c-0.722,0-1.202-0.48-1.202-1.203
			v-4.812c0-0.723,0.48-1.203,1.202-1.203h4.812c0.722,0,1.203,0.48,1.203,1.203V50.379z M65.875,20.301h-6.016v-2.405
			c0-1.927-1.563-3.609-3.609-3.609c-1.925,0-3.608,1.564-3.608,3.609v2.405H35.797v-2.405c0-1.927-1.563-3.609-3.608-3.609
			c-1.925,0-3.609,1.564-3.609,3.609v2.405h-6.016c-2.647,0-4.812,2.166-4.812,4.812v3.008c0,0.962,0.842,1.805,1.806,1.805h49.327
			c0.963,0,1.806-0.842,1.806-1.805v-3.008C70.687,22.466,68.522,20.301,65.875,20.301z"/>
	</g>
</g>
</svg>

A+

Alain

All Answers

Sylvie SerpletSylvie Serplet
I am also looking for the SVG tab of the bundle for the following component.

User-added image

Thank you for your help.
Sylvie
 
Alain CabonAlain Cabon
Hello Sylvie,

I keep my eye on your question. 

There is exactly your widget here but there is not the complete code. I lacks the most interesting part.
<lightning:card iconName="standard:event" title="Days on the Market">
        <div class="slds-p-horizontal_medium">
            // content goes here
        </div>
</lightning:card>

https://developer.salesforce.com/blogs/developer-relations/2017/08/winter-coming-lightning.html

You can search directly in the code with Ctrl + Maj + J  and Ctrl + Shift + C with Chrome.

I will continue to search myself tonight.

Regards
Alain CabonAlain Cabon
You can search directly in the code and "point and click" with Ctrl + Shift + C with Chrome but it is no panacea.

Regards
Sylvie SerpletSylvie Serplet
Hi Alain,
I found most part of the code (below) but my component is lacking the charting part (days-block, bar, width) and look likes this.
User-added image
Should probably be define as CSS or SVG but I do not know how to write it.

Component
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="transaction" type="Transaction__c" />
    <aura:attribute name="formattedDueDate" type="String" />
    <aura:attribute name="status" type="String" />
    
    <force:recordData aura:id="transRec"
                      recordId="{!v.recordId}"
                      targetFields="{!v.transaction}" 
                      fields="Id, DaysPaymentDue__c, Due_Date__c"
                      recordUpdated="{!c.recordUpdated}"
                      />
    
    <lightning:card iconName="utility:event" title="Days Payment Due" >
        <div class="indent">
            <lightning:layout >
                <lightning:layoutitem class="{! 'days-block' + v.status + 'bgcolor' }" >
                    <div class="days">{!v.transaction.DaysPaymentDue__c}</div>days  
                </lightning:layoutitem> 
                <lightning:layoutitem flexibility="grow" class="chart">
                    <div class ="{! 'bar' + v.status }" style="{! 'width:' + v.transaction.Due_Date__c}" />
                    <div class="axis bgcolor">
                        <div><div class="legend">{!v.formattedDueDate}</div></div>   
                        <div><div class="legend">14 days</div></div>  
                        <div><div class="legend">30 days</div></div>  
                    </div>
                </lightning:layoutitem>                              
            </lightning:layout>
        </div>
    </lightning:card>
</aura:component>

JavascriptController
({
    recordUpdated : function(component, event, helper) {
        var changeType = event.getParams().changeType;
        if (changeType === "LOADED" || changeType === "CHANGED"){
            helper.showDaysPaymentDue (component);            
        }
    }
})

Helper
({
	showDaysPaymentDue : function(component) {
	var transaction = component.get("v.transaction");	
        var daysPaymentDue = transaction.DaysPaymentDue__c;
        var status = "green";
        if (daysPaymentDue > 30){
            status = 'red';
        } else if (daysPaymentDue > 14 ){
            status = 'orange';
        }
        component.set ("v.status", status);
        component.set ("v.formattedDueDate", new Date(transaction.Due_Date__c).toLocaleDateString('en-GB'));
	}
})

Any help will be very appreciated.
Thank you in advance.
Sylvie
Alain CabonAlain Cabon
Hello Syvie,

It is the DreamHouseApp (open source). I found the source code for the Spring 17/Summer 17.

PropertyDaysOnMarketChart
The PropertyDaysOnMarketChart component provides a visual representation of the number of days a property has been on the market. It can be used on the Property record page, or on the Property Explorer or Command Centerpages as part of a master/details interface.

https://developer.salesforce.com/blogs/developer-relations/2017/08/winter-coming-lightning.html

http://www.dreamhouseapp.io/

Source Code:

The source code for the PropertyExplorer component is included in the DreamHouse unmanaged package.

http://www.dreamhouseapp.io/installation/

User-added image
<aura:component implements="force:hasRecordId,flexipage:availableForAllPageTypes" access="global">
    
    <aura:attribute name="recordId" type="Id" />
	<aura:attribute name="property" type="Property__c" default="{Days_On_Market__c: 0}"/> 
	<aura:attribute name="formattedDateListed" type="String" /> 
	<aura:attribute name="status" type="String" /> 
    
	<force:recordPreview aura:id="service" 
                         recordId="{!v.recordId}" 
                         targetRecord="{!v.property}" 
                         fields="['Id', 'Date_Listed__c', 'Days_On_Market__c']" 
                         recordUpdated="{!c.recordUpdated}"/>
    
    <aura:handler event="ltng:selectSObject" action="{!c.recordChangeHandler}"/>

    <div>
        <lightning:layout >
        	<lightning:layoutitem class="{! 'days-block ' + v.status}">
                <div class="days">{!v.property.Days_On_Market__c}</div>days
            </lightning:layoutitem>
            <lightning:layoutitem flexibility="grow" class="chart">
                <div class="{! 'bar ' + v.status }" style="{! 'width:' + v.property.Days_On_Market__c / 90 * 100 + '%' }"/>
                <div class="axis">
                    <div><div class="legend">{!v.formattedDateListed}</div></div>
                    <div><div class="legend">30 days</div></div>
                    <div><div class="legend">60 days</div></div>
                </div>
            </lightning:layoutitem>
        </lightning:layout>
    </div>
    
</aura:component>

Controller:
({
	recordUpdated : function(component, event, helper) {
		var changeType = event.getParams().changeType;
        if (changeType === "LOADED" || changeType === "CHANGED") {
			helper.showDaysOnMarket(component);
        }
	},

   	recordChangeHandler : function(component, event) {
        var id = event.getParam("recordId");
        component.set("v.recordId", id);
        var service = component.find("service");
        service.reloadRecord();
	}

})
Helper
({
	showDaysOnMarket : function(component) {
    	var property = component.get("v.property");
        var daysOnMarket = property.Days_On_Market__c;
        var status = "green";
        if (daysOnMarket > 60) {
            status = 'red';
        } else if (daysOnMarket > 30) {
            status = 'orange'
        }
        component.set("v.status", status);
        component.set("v.formattedDateListed", new Date(property.Date_Listed__c).toLocaleString('en-US', {month: 'short', year: 'numeric', day: 'numeric'}));
	}
})
Style
.THIS .days-block {
	text-align: center;
    margin-right: 8px;
    padding: 8px 12px;
    border-radius: 0.25rem;
    border: solid 1px rgb(216, 221, 230);
} 
.THIS .days-block.red {
	color: #C23934;
    border: solid 1px #C23934;
} 

.THIS .days-block.green {
	color: #00716B;
    border: solid 1px #00716B;
} 

.THIS .days-block.orange {
	color: #FFB75D;
    border: solid 1px #FFB75D;
} 

.THIS .days {
	font-size: 32px;
	line-height: 32px;
	font-weight: 300;
    margin-right: 12px;
    margin: 0;
    padding: 0;
} 

.THIS .chart {
    position: relative;
    height: 40px;
}

.THIS .bar {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    height: 32px;
    width: 0;
    transition: all .5s ease-in-out;
    position: absolute;
    bottom: 2px;
    left: 2px;
    right: 0;
}

.THIS .bar.green {
    background-color: #00716B;
}

.THIS .bar.orange {
    background-color: #FFB75D;
}

.THIS .bar.red {
    background-color: #C23934;
}

.THIS .axis {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    bottom: 0;

}

.THIS .axis > div {
    height: 34px;
	flex: 1;
	border-bottom: solid 1px rgb(216, 221, 230);
	border-left: solid 1px rgb(216, 221, 230);
}

.THIS .axis .legend {
    margin-top: 36px;
}

SVG
 
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="88.316px" height="88.318px" viewBox="0 0 88.316 88.318" enable-background="new 0 0 88.316 88.318" xml:space="preserve">
<g id="Layer_1_copy">
	<path fill="#E9696E" d="M88.316,73.268c0,8.312-6.738,15.051-15.054,15.051H15.05C6.737,88.319,0,81.581,0,73.268V15.052
		C0,6.74,6.737,0,15.05,0h58.215c8.312,0,15.054,6.74,15.054,15.052L88.316,73.268L88.316,73.268z"/>
</g>
<g id="Layer_5">
	<g>
		<path fill="#FFFFFF" d="M68.883,35.941H19.554c-0.963,0-1.806,0.842-1.806,1.805v29.478c0,2.646,2.166,4.812,4.812,4.812h43.312
			c2.647,0,4.812-2.165,4.812-4.812V37.746C70.687,36.783,69.844,35.941,68.883,35.941z M35.797,62.41
			c0,0.722-0.48,1.203-1.203,1.203h-4.812c-0.722,0-1.203-0.481-1.203-1.203v-4.812c0-0.723,0.481-1.203,1.203-1.203h4.812
			c0.723,0,1.203,0.48,1.203,1.203V62.41z M35.797,50.379c0,0.723-0.48,1.203-1.203,1.203h-4.812c-0.722,0-1.203-0.48-1.203-1.203
			v-4.812c0-0.723,0.481-1.203,1.203-1.203h4.812c0.723,0,1.203,0.48,1.203,1.203V50.379z M47.828,62.41
			c0,0.722-0.48,1.203-1.203,1.203h-4.812c-0.723,0-1.203-0.481-1.203-1.203v-4.812c0-0.723,0.48-1.203,1.203-1.203h4.812
			c0.723,0,1.203,0.48,1.203,1.203V62.41z M47.828,50.379c0,0.723-0.48,1.203-1.203,1.203h-4.812c-0.723,0-1.203-0.48-1.203-1.203
			v-4.812c0-0.723,0.48-1.203,1.203-1.203h4.812c0.723,0,1.203,0.48,1.203,1.203V50.379z M59.859,62.41
			c0,0.722-0.481,1.203-1.203,1.203h-4.812c-0.722,0-1.202-0.481-1.202-1.203v-4.812c0-0.723,0.48-1.203,1.202-1.203h4.812
			c0.722,0,1.203,0.48,1.203,1.203V62.41z M59.859,50.379c0,0.723-0.481,1.203-1.203,1.203h-4.812c-0.722,0-1.202-0.48-1.202-1.203
			v-4.812c0-0.723,0.48-1.203,1.202-1.203h4.812c0.722,0,1.203,0.48,1.203,1.203V50.379z M65.875,20.301h-6.016v-2.405
			c0-1.927-1.563-3.609-3.609-3.609c-1.925,0-3.608,1.564-3.608,3.609v2.405H35.797v-2.405c0-1.927-1.563-3.609-3.608-3.609
			c-1.925,0-3.609,1.564-3.609,3.609v2.405h-6.016c-2.647,0-4.812,2.166-4.812,4.812v3.008c0,0.962,0.842,1.805,1.806,1.805h49.327
			c0.963,0,1.806-0.842,1.806-1.805v-3.008C70.687,22.466,68.522,20.301,65.875,20.301z"/>
	</g>
</g>
</svg>

A+

Alain
This was selected as the best answer
Alain CabonAlain Cabon
 
<div>
        <lightning:layout >
        	<lightning:layoutitem class='days-block orange'>
                <div class="days">41</div>days
            </lightning:layoutitem>
            <lightning:layoutitem flexibility="grow" class="chart">
                <div class="bar orange" style="width: 41%"/>
                <div class="axis">
                    <div><div class="legend">May 18, 2017</div></div>
                    <div><div class="legend">30 days</div></div>
                    <div><div class="legend">60 days</div></div>
                </div>
            </lightning:layoutitem>
        </lightning:layout>
 </div>

User-added image

A+
Alain
Sylvie SerpletSylvie Serplet
Hello Alain,
Sorry for my late response (I was away for a few days). Thank you very much for the codes.
Will try to make it works now!
Sylvie
Alain CabonAlain Cabon
Hello Sylvie,

I enjoy hearing from you and I hope that could help a little even if you had almost a complete code yet.

Regards
Alain