Friday, December 24, 2010

Horizontal Bar graph in visualforce page

It came to me multiple times to create horizontal bar graph kind of representation of some status based on some field values; both on standard layout and on a visualforce page.

Let us take an example, you want to show a bar graph to user with red and green color with varying width of red and green color depending upon a percent or number type
field (say Percent_Complete__c). If the value of the field is 40,you want show a bar with 40% green and remaining 60% as red and so on.



You could create a formula field of type text then using an IMAGE function. The formula could be -

(IMAGE("/img/samples/color_green.gif", "green", 15, Percent_Complete__c*2) & IMAGE("/img/samples/color_red.gif", "red", 15, 200 - Percent_Complete__c*2))

But here is a catch in using a formula field, waht if the caculation is based upon data from multiple objects and fields. This could be very painful or even sometime not possible
to do this using formula field.

So what options do we have left, VISUALFORCE page.

Again, to do this in visualforce, there many be many ways. Some people may use some javascript library like jQuery or some other library. But there is an easier way of doing this.
This solution WE (I along with a colleague of mine, Chetan - AS) came across while working on a similar requirement. We used a simple html table with one row amd two table data
(columns) with background color of green and red. The width of the columns would be varying based upon your requirements.

Here is a simple code snippet assuming a single field would be basis to calculate the width of red and green colored columns.


HorizontalBar.page

<apex:page controller="BarController">
  <table>
    <tr>
      <td style="background-color:red" width="{!redPart}">
      </td>
   
      <td style="background-color:green" width="{!greenPart}">
      </td>
    </tr>
  </table>
</apex:page>

BarController.cls
public class BarController(){
    public Integer redPart{get;set;}
    public Integer greenPart{get;set;}

    public BarController(){
        Object__c obj = [SELECT Percent_Complete__c FROM Object__c WHERE XYZ = 'xyz'][0];
        greenPart = obj.Percent_Complete__c;
        redPart = 100 - greenPart;
    }
}


 AND that is it. This page can even be used in inline VF page in standard page layout.

Hope this helps.

Happy Clouding... :)

3 comments:

  1. This is superb Swaleh!!

    But I have a query regarding colour coding and that is 'Can we create text in different colours based on the conditions as you have mentioned in this post instead of creating flag'?

    ReplyDelete
  2. Tanvi, first of all, sorry for so late reply and thanks for the compliment :)

    I did not fully understand your question. We can get the colors dynamically if you specify it in your controller based on your conditions.

    For example, instead of saying
    "style="background-color:red"
    you can write "style={!valuefromcontroller}".

    Hope this resolves your query. :)

    ReplyDelete
  3. Hi,

    I need a requirement which calculates no of records that are shown in enhancedlist(records are shown 50 out of 120) and according to that horizontalbar should be displayed.
    If i remove records from enhancedlist, the horizontalbar should update

    Can I know to do this.??

    ReplyDelete