Thursday, April 20, 2017

Save Visualforce Chart as Image in Attachment

The issue that brought me here is a user wants to render chart as PDF as we all know that Visualforce Chart is not renderable into PDF. Visualforce Chart is renderd by Javascript that is why it is not PDF renderable.

Please refer here for limitations:



In order to bypass those limitation, we need to save chart as image and after that use the image in PDF.Currently there a lot chart library that offers saving the chart to user machine.In my scenario, user want to be able to get chart along with Opportunity information in PDF.So saving chart into the local machine and upload it back as Attachment is not ideal solution.

In order to achieve this, we must include canvg library that you can get it here.This library will help to convert SVG to PNG[also please checkout other format].I get this information from here . Note that Visualforce Chart only render in browsers that support SVG, which mean this is a good sign.


1
2
3
<script type="text/javascript" src="http://canvg.github.io/canvg/rgbcolor.js"></script> 
<script type="text/javascript" src="http://canvg.github.io/canvg/StackBlur.js"></script>
<script type="text/javascript" src="http://canvg.github.io/canvg/canvg.js"></script> 

In order Visualforce page , add canvas element in page.In this example, I use demo from Visualforce Chart for pie chart.

1
2
3
4
5
6
7
<input type="button" id="save_img_att" value="Save as Attachment"/>
<div id="container" style="min-width: 400px; max-width: 600px; height: 400px; margin: 0 auto"></div>
    <apex:chart height="350" width="450" data="{!pieData}" id="pieChart" renderTo="container">
        <apex:pieSeries dataField="data" labelField="name" id="pieSeries"/>
        <apex:legend position="right"/>
    </apex:chart>
    <canvas id="canvas" style="display:none;"></canvas>

In Javascript,note 'container' is the div element where chart is render to.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$("#save_img_att").click(function(){
        var mainDiv=document.getElementById('container');
        var svg = mainDiv.children[0].children[0].innerHTML;
        console.log('@@svg .... ' + svg);
        canvg(document.getElementById('canvas'),svg);
        var img = canvas.toDataURL("image/png"); //img is data:image/png;base64
        img = img.replace('data:image/png;base64,', '');
        var data = "bin_data=" + img;
        console.log('@@oppId =' +     '{!Opportunity.Id}');
        Visualforce.remoting.Manager.invokeAction('{!$RemoteAction.VFChart_Server.saveChartAsAttachment}',
       '{!Opportunity.Id}',img,
          function(result,event){
             if(event.status){
             
               console.log('@@@ success');
               
             }
             else {
               console.log('@@@ fail');
             
             }
          
          
          } );
        
      
    });

We use var svg = mainDiv.children[0].children[0].innerHTML; in order to get the div that generated by Salesforce.You can right click at the chart and search for something like below.We don't want to hardcode so we need to find it from 'container' div.


Create @RemoteAction in controller class.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RemoteAction
    global static void saveChartAsAttachment(String oppId,String attachmentBody){
       system.debug('@@@saveChartAsAttachment  oppId ='+ oppId);
       List<Attachment> listAttachment =[Select Name,Id,Body from Attachment Where ParentId=:oppId];
       Attachment att;
       if(listAttachment.size()>0){
          att =listAttachment[0];
          att.Body = EncodingUtil.base64Decode(attachmentBody);
          update att;
       
       }
       else{
       
           att = new Attachment();
           att.Name='spiderChart_VF';
           att.ParentId=oppId;
           att.ContentType='image/png';
           att.Body = EncodingUtil.base64Decode(attachmentBody);
           insert att;
    
       }
  
    }

I include this visualforce page in Opportunity page layout  like below.This is nothing to do with saving it as attachment, it just because I am lazy to create my own custom page.


Click on Save as Attachment. Refresh it, you should see the image is save in Attachment.Here the sample of image that generated from Visualforce Chart.


Once it save as Attachment, it easy for us to render as PDF which I will update in other entry.

For complete source code please check it out here.



Wednesday, April 19, 2017

Determine the Salesforce Edition for Your App



How does Enterprise Edition differ from Professional Edition?

  • Enterprise Edition has features that aren't available in Professional Edition
  • Professional Edition is only sold to Accountants, Dentists, and Lawyers
  • Enterprise Edition supports more users than Professional Edition
  • Professional Edition has higher limits than Enterprise Edition


Which list correctly orders editions from smallest to largest?

  • Enterprise Edition, Professional Edition, Group Edition, Performance Edition
  • Professional Edition, Group Edition, Enterprise Edition, Performance Edition
  • Group Edition, Professional Edition, Enterprise Edition, Performance Edition
  • Professional Edition, Group Edition, Performance Edition, Enterprise Edition



You’re building an ISVforce app that reuses Account, Contact, Lead, and Opportunity objects to vet vendors who resell products for your customers. You use Record Types to ensure that the fields you add don’t interfere with the customers existing use of those objects. What's the lowest edition that you can target?

  • Group Edition
  • Enterprise Edition
  • Performance Edition
  • Professional Edition



For an ISVforce app, what determines the features you should use in your solution?

  • The type of user licenses you're embedding in your application
  • The size of the customer you're targeting and the industry they are from
  • The complexity of your application and the amount of resources it uses
  • The customer’s edition, user licenses, and feature and permission set licenses
  • You want your customers to buy user licenses directly from Salesforce



When should you decide which editions your app supports?

  • After you develop your app, but before you sell it to customers
  • Before you design your app and before you build your app
  • After you’ve designed your app, but before you begin building it
  • Before you determine your target audience and before you design your app


Wednesday, April 12, 2017

To check if the parent have child using SOQL

Use Left Inner Join

SELECT Id FROM Opportunity WHERE Id IN (SELECT Opportunity__c FROM Opportunity_Child__c)

Reference
A Deeper look at SOQL and Relationship Queries on Force.com
SOQL to determine if parent has child records

Friday, April 07, 2017

Global Picklist fail to deploy : Duplicate label: xx xx xx

I am deploying Global Picklist and got Duplicate label error.I am really confident that there is no duplicate label except deactivated picklist. The issue is known as raised here : Deploying picklist values via change set causes "Duplicate Label" error.

It seem like not my case and it said that it's already fixed.I already deactivated the duplicate picklist.Now I suspect, the deactivated picklist causing the error.So I go to Change Set Detail, click at View Source on the picklist.Surely, it will deploy the deactivated picklist.So I delete all the deactivated picklist and redeploy again.It's really annoying because uploading Change Set is not so fast procedure.

The result is SUCCESS. Okay take note if you just deactivate the picklist similar label with the active picklist because it will make your deployment life miserable until you find this blog. =)

Have a nice day.Take care.

Chatter Basic : Getting Started with Chatter

Group types

  • Public groups: Public groups are visible and open to all employees. Anyone in the company can join a public group, post, comment, and add files.
  • Private groups: Private groups are open only to group members. People must request to join a private group. Only group members can post, comment, and add files. Nonmembers can see the group’s picture and description, but they can’t see the group feed or files.
  • Unlisted groups: Unlisted groups are invitation-only and don’t appear in list views and search results. An unlisted group is hidden from everyone except group members. Only the group’s owner or manager can invite people to join an unlisted group.
  • Groups with customers: Groups with customers are private or unlisted groups that allow external users to be members. The group owner or manager must invite external users to join. Need to Allow Customers option to private and unlisted groups.
  • Broadcast only: In broadcast only groups, only group owners and managers can create posts. Group members can comment on them. Apply the Broadcast Only option to private, unlisted, and public groups.