+ Start a Discussion
prakash chaudharyprakash chaudhary 

Is it possible to use Fusion charts in VFPage ??????

Is it possible to use fusion charts on visual force ?

If Yes then please let me know with simple example bcoz I am able to use fusioncharts in webpage like html, jsp but I am trying with all my capabilities but not getting any output so please help me whether it is possible or not ?

 

Please tell me how can i do it ?

Thnking you so much if u can help me for this....

sfdcfoxsfdcfox

My intial reaction would be "yes, this is definitely possible." It appears that you would simply need to upload the file as a static resource (Setup > Develop > Static Resources), and embed the component using apex:flash. You also need some JS files. You can have the contents directly copy-pasted into the VF page, or you can use more static resources. The caveat here is you'll have to embed them in order, because JavaScript won't be able to find them using their auto-loading mechanism (as per their documentation). I don't know the specific order, but I suppose it would look like this:

 

<apex:page>
  <apex:includeScript value="{!$Resource.jquerymin}"/>
  <apex:includeScript value="{!$Resource.highchart}"/>
  <apex:includeScript value-"{!$Resource.FusionCharts}"/>
  <apex:flash flashvars="..." id="..." src="{!$Resource.FusionChartSWF}"/>
</apex:page>

This is just a crude guess, but if I get a moment, I'll download the demo/trial version and see if I can get it working. Oh, and the SWF file should be the file that was created for rendering the specific chart type you wanted.  Alternatively, just stick to the JavaScript version for better compatibility but reduced features.

prakash chaudharyprakash chaudhary

Yaa sfdcfox,

But here problem is, When I have to pass my parameter in fusion charts then how can i do that ?

Since it will show me fusion charts of predefined layout that is always same for every page but I need to show my dynamic charts bcoz my values will vary according to their changes.

So please tell me how to pass values in it ?
Regards... 

sfdcfoxsfdcfox

I'll download the trial, and get back to you in the next 24 hours or so.

prakash chaudharyprakash chaudhary

Yaa Its okk...

Thanks alot sfdcfox.

sfdcfoxsfdcfox

 

<apex:page showHeader="false" sidebar="false">
    <apex:includeScript value="{!$Resource.FC_JQ_MIN}"/>
    <apex:includeScript value="{!$Resource.FC_HC}"/>
    <apex:includeScript value="{!$Resource.FC}"/>
    
    <div id="FC_canvas">
    </div>
    
    <button onclick="rendernewdata()">Update</button>
<script>
function rendernewdata() {
    a = FusionCharts("myChartId")
    a.setJSONData('{ "chart" : {}, "data" : [ { "label" : "test", "value" : "30" },{ "label" : "test", "value" : "50" } ] }')
}
</script>
    
<script>
a = new FusionCharts("{!$Resource.FC_SWF}","myChartId","400","300","0","1")
a.setJSONData('{ "chart" : {}, "data" : [ { "label" : "test", "value" : "50" },{ "label" : "test", "value" : "30" } ] }')
a.render("FC_canvas")
</script>    
</apex:page>

Here's a VF example. You need to upload the files "highcharts.js", "jquery.min.js", "FusionCharts.js", and your preferred SWF chart, using the static resource names "FC_HC", "FC_JQ_MIN", "FC", and "FC_SWF", respectively. The inclusion order was chosen to work around the auto-load mechanisms in the JS files, since they have hard-coded names and would otherwise fail (we can't control the file names, so this is the preferred method).

 

Next, we construct a container, which I called "FC_canvas" as a div tag. I also set up a button that demonstrates updating the data. Then, I create a function that updates the data. This uses hard-coded data, but it would be trivial to use an AJAX call back to the server. You could use "sforce.apex.execute" to get new data, or you could use a hidden container that is updated using VF AJAX calls. For example, you could use something like the following:

 

<apex:form>
<apex:actionFunction action="{!updatedata}" name="updatedata" reRender="dataContainer" oncomplete="updatechartdata()"/>
<apex:outputText id="dataContainer" style="display: none">{!datasource}</apex:outputText>
</apex:form>

No matter how you get the data, you need to rerender it as JSON or XML data (as necessary), and then call an update function (setXMLData or setJSONData). I've successfully made this work in my developer org, and I'm going to write a more comprehensive example in the next day or so; this was only for proof of concept.

prakash chaudharyprakash chaudhary

Thanks alot sfdcfox, for your very useful help.

But explore this concept as much as possible & now I am able to implement it.

& In your code, as I checked that without JQuery.min.js & highcharts.js, it works very well.

Can u also tell me that whether any changes u r seeing after commeting the line...

<!-- 

<apex:includeScript value="{!$Resource.FC_HC}"/>

<apex:includeScript value="{!$Resource.FC_JQ_MIN}"/> 

-->

 

As I see no changes after making comment on it.

prakash chaudharyprakash chaudhary

Since the code that u have given to me, is in JSON format but I am looking to build charts in xml format.

You have already done with JSON format so u will probably get very less time to do it in XML format.

I am pasting here my code with litlle bit explanation so please tell me the problem bcoz of it is not working.

 

<apex:page showHeader="false" sidebar="false">  
<apex:includeScript value="{!$Resource.FusionCharts}"/>    
<apex:includeScript value="{!$Resource.FusionChartsExportComponent}"/>   
<div id="chartContainer">FusionCharts will load here!</div>  
    <script type="text/javascript">
          
        var myChart = new FusionCharts("{!$Resource.Column3D}",  "myChartId", "600", "400", "0", "1" );
        myChart.setXMLData("<chart animation='1' palette='2' caption='Weekly Sales Summary' exportEnabled='1' exportAtClient='1' exportHandler='fcExporter1'>
                <set label='Week 1' value='14400'  /> 
                <set label='Week 2' value='19600' /> 
                <set label='Week 3' value='24000' /> 
                <set label='Week 4' value='15700' /> 
        </chart>");                  
        // myChart.setXMLUrl("{!$Resource.Data}");
        myChart.render("chartContainer");      
        
        var myExportComponent = new FusionChartsExportObject("fcExporter1","{!$Resource.FCExporter}");
        myExportComponent.Render("fcexpDiv");
          
        function FC_Exported(e) {
            alert ( e.DOMId + (e.statusCode ? " chart has been Exported." : " chart has not been Exported." ) );
        }
    </script> 
    
    <apex:pageBlock >   
        <apex:form >
            <div id="chartContainer">FusionCharts will load here!</div>  
            <div id="fcexpDiv">FusionCharts Export Component will load here!</div>
            <input type="button" value="Export Chart" align="center" onClick="myChart.exportChart( { exportFormat : 'JPEG'} );"/>
        </apex:form>
    </apex:pageBlock> 
</apex:page>

 

sfdcfoxsfdcfox

Here's a complete example using XML from start to end:

 

<apex:page controller="FC_Chart">
    <apex:includeScript value="{!$Resource.FC}"/>
    
    <div id="FC_canvas">
    </div>

    <button onclick="goback()">Back One Year</button>
    <button onclick="goforward()">Forward One Year</button>
    
<script>
function updatechart() {
    a = FusionCharts("myChartId")
    a.setXMLData(document.getElementById('{!$Component.theForm.chartdata}').value)
}
</script>

<apex:form id="theForm">
<apex:inputHidden value="{!chartdata}" id="chartdata"/>
<apex:actionFunction action="{!goback}" reRender="theForm" name="goback" oncomplete="updatechart()"/>
<apex:actionFunction action="{!goforward}" reRender="theForm" name="goforward" oncomplete="updatechart()"/>
</apex:form>

<script>
a = new FusionCharts("{!$Resource.FC_SWF}","myChartId","400","300","0","1")
a.setXMLData(document.getElementById('{!$Component.theForm.chartdata}').value)
a.render("FC_canvas")
</script>    
</apex:page>

 

public class FC_Chart {
    date selecteddate = system.today();
    public void goback() {
        selecteddate = selecteddate.addmonths(-12);
    }
    public void goforward() {
        selecteddate = selecteddate.addmonths(12);
    }
    
    public string getchartdata() {
        map<integer,decimal> data = new map<integer,decimal>();
        string encodeddata = '<chart caption="Closed Sales for '+ String.valueOf(selecteddate.year()) +'">';
        date firstdate = selecteddate.addmonths(1-selecteddate.month()).tostartofmonth();
        date lastdate = selecteddate.addmonths(13-selecteddate.month()).tostartofmonth();
        for(integer i = 1; i < 13; i++)
            data.put(i,0);
        for(opportunity o:[select id,amount,closedate from opportunity where iswon = true and closedate >= :firstdate and closedate < :lastdate ]) {
            data.put(o.closedate.month(),o.amount+data.get(o.closedate.month()));
        }
        for(integer i = 1; i < 13; i++) {
            encodeddata += '<set label="' + datetime.newinstance(selecteddate.year(),i,1,1,1,1).format('MMM') + '" value="' + data.get(i) + '"/>';
        }
        encodeddata += '</chart>';
        return encodeddata;
    }
    
    public void setchartdata(string s) {
    
    }
}

Note that this method isn't recommended if there's any potential user input; you'd want to normally use the XMLWriter class to ensure proper escaping and such. This code is for demonstration purposes only, and does work in my developer organization as-is.

 

Note the use of the function getchartdata(), which posts data directly into a hidden field that we use to obtain the data in the AJAX request. This value is automatically encoded and decoded for us, so it is safely transported; the only problem we have is if a label translated to something that included a quotation mark. The solution would be EncodingUtil.URLEncode to make sure that the values do not exhibit this behavior.

 

You should be able to add the "export chart" function from here. Let me know if you need any further help.

Suresh PawarSuresh Pawar

Hiiii sfdcfox, Since i am working on fusion charts but I am confuse in your code as,

Can u explain controller code ?

I want to know completely about generating chart dynamically & have to implement very urgently so hope from you I will get right way to work on VFPage & Fusion charts.

Regards...

sfdcfoxsfdcfox

I simplified the code by using some of the "newer" features of Apex Code; this should be easier to understand:

 

public class FC_Chart {

    // The current year we're looking at. Starting with this year.
    Integer currentYear = System.today().year();

    // Go back a year.
    public void goback() {
        currentYear--;
    }

    // Go forward a year.
    public void goforward() {
        currentYear++;
    }

    // Example output for getchartdata():
    /*
        <chart caption="Closed Sales for 2011">
            <set label="Jan" value="100"/>
            <set label="Feb" value="100"/>
            <set label="Mar" value="100"/>
            <set label="Apr" value="100"/>
            <set label="Jun" value="100"/>
            <set label="Jul" value="100"/>
            <set label="Aug" value="100"/>
            <set label="Sep" value="100"/>
            <set label="Oct" value="100"/>
            <set label="Nov" value="100"/>
            <set label="Dec" value="100"/>            
        </chart>    
    */
    
    public string getchartdata() {
        // 12 months of data, plus dummy zero index for zero-based array.
        list<decimal> monthData = new list<decimal> { 0,0,0,0,0,0,0,0,0,0,0,0,0 };

        // Find all sales in the current year
        for(AggregateResult o:[select calendar_month(closedate),sum(amount) from opportunity
                            where iswon = true and
                                calendar_year(closedate)=:currentYear
                                group by calendar_month(closedate)])
            monthData[(Integer)(o.get('expr0'))] = (Decimal)(o.get('expr1'));

        XmlStreamWriter xml = new XmlStreamWriter();
        xml.writeStartElement(null,'chart',null);
        xml.writeAttribute(null,null,'caption','Closed Sales for '+String.valueOf(currentYear));
        
        for(integer month = 1; month < 13; month++) {
            xml.writeEmptyElement(null,'set',null);
            xml.writeAttribute(null,null,'label',datetime.newinstance(currentYear,month,1,1,1,1).format('MMM'));
            xml.writeAttribute(null,null,'value',String.valueOf(monthData[month]));
        }
            
        xml.writeEndElement();
        
        // Post this xml string back to the server.
        return xml.getXmlString();
    }
    
    // This is only to satisfy "read-only error" when using an inputHidden field.
    public void setchartdata(string s) {
    
    }
}

As you can see, we basically perform a query, populate some data, convert it to an XML string, and then output the results. You should take a look at the Force.com Apex Code Developer's Guide for details on the XmlStreamWriter.

Venkat_rdVenkat_rd

Hi,

I have followed the exact procedure given by you here. But when i click on update button nothing is displayed. can you please help me with this. PFB the code.

 

<apex:page>
<apex:includeScript value="{!$Resource.jquerymini}"/>
<apex:includeScript value="{!$Resource.HighCharts}"/>
<apex:includeScript value="{!$Resource.FusionCharts}"/>

   
    <div id="FC_canvas">
    </div>
    
    <button onclick="rendernewdata()">Update</button>
<script>
function rendernewdata() {
    a = FusionCharts("myChartId")
    a.setJSONData('{ "chart" : {}, "data" : [ { "label" : "test", "value" : "30" },{ "label" : "test", "value" : "50" } ] }')
}
</script>
    
<script>
a = new FusionCharts("{!$Resource.bar2d}","myChartId","400","300","0","1")
a.setJSONData('{ "chart" : {}, "data" : [ { "label" : "test", "value" : "50" },{ "label" : "test", "value" : "30" } ] }')
a.render("FC_canvas")
</script>    
</apex:page>

 

When i click on update nothing is displayed. I have added three js files and one bar2d swf in static resources.

 

Thanks