How to use FusionCharts in Windows .NET Applications (WinForms) – Part 3

It’s been some time since we last talked about using FusionCharts in your .NET applications. Hopefully now you know how to generate charts & javascript graphs from data entered in forms, and how to get back the data from the chart in CSV format. In this post, we’ll see how to generate a chart using data from a remote XML file and save that chart in PNG format.

Making a chart using a remotely located XML file

It may not always be the case that you have the XML data inline in your application. You might have a remote server where your chart data is located. In that case you have to use what we call the dataURL method. Let’s take this step by step.

1. So let us create that external XML file first. We will use the same guitar example from last time:

 

 

In the above XML file we have added certain extra chart attributes like exportEnabled, exportHandler and exportFormats. All of these will be required later when we export the chart as an image.

Open an empty notepad file, copy and paste the above text and save it as data.xml in your application startup path. Generally in C#, this would be the binDebug folder under your application folder. Also copy the Column2d.swf file which comes with the FusionCharts Pack to the same folder.

2. Now create a new Windows Application (C#). As in the previous post, add a Shockwave Flash Object to your form. The form would now look like:

Form with Flash object added to it

Notice how small we have kept the size of the form. In this project, we will play around with the size of the form a wee bit as well.

3. Now in the Form1_Load Event, add the following code

 

////Specify the format, path and name of the swf file which will render the chart.

//if “file:///” is added before the path and the XML after the path in the format

//file:///XMLpath?=dataXML=®isterwithjs=1

//then the chart will be loaded directly with no chance of any error.

//For a different chart, change the name from column2d to the required chart,

//add the chart swf to the application startuppath and modify the XML as required.
string appPath = “file:///” + Application.StartupPath + “Column2D.swf”;

//Replace all “” in the .swf path with “/”

appPath = appPath.Replace(“”, “/”);

//Similarly, set the path of the remote XML file as the startup path

//because that is where the file is located

string XMLpath = Application.StartupPath + “Data.XML”;

//Replace all “” in the XML path with “/”

XMLpath = XMLpath.Replace(“”, “/”);

//finally generate the chartXML string which is in the form

//file:///XMLpath?=dataXML=®isterwithjs=1

//This is the string which will be passed to the ShockWave Object

//to load the chart.

string ChartXml = appPath + @”?dataURL=” + XMLpath + “®isterwithjs=1”;

//passing the string ChartXml to the shockwave flash player.

axShockwaveFlash1.Movie = ChartXml;

4. Now if you run the application,  you will see that as the form is loaded your chart is rendered as good as new. Great fun isn’t it?

Form with chart being displayed

Get the picture?

Next, like we’ve been promising for some time now, you will see how to save your chart as an image file. This is where things get real interesting. For this example, you will be saving the chart image in PNG format. You can save the image in any format you like by tweaking the code just a little bit. We  will see how to do that as well.

Before we move on to see how to save your chart image, please remember that unless the chart element in your XML contains the following attributes, exporting will not be enabled in your chart:

 

Ok, let’s get right to it.

1. First you need to configure the form. Like we said, in this example you will have to play around with the Form size a little bit as well. The form, as it stands now, is of size (692,318) pixels. Drag the Form vertically downwards and make its size (692, 605) pixels. The form will now not only contain the chart, but also an image of it in the PictureBox object. Considering the chart dimensions and the image dimensions, this would be the optimum size for the form. You can also change the size by changing it in the Properties window.

Changing form size

2. Next, add a PictureBox to the form. This is where the chart image will be displayed.

Adding picture box to the form

In the Properties window, change the SizeMode property of the PictureBox to AutoSize as shown below.

Setting SizeMode of PictureBox to AutoSize

3. Also add a button to the form. From the Properties window, change its text to Save Chart As Image. The final form would look like:

Final form for exporting the chart

4. Next, add a SaveFileDialog to our application. This will be used to save the chart image on your hard disk when you click the Save Chart As Image button.

Adding SaveFileDialog

5. Now that the form design is done, reduce the form dimensions to the original one. The user need not see the extra form elements (the PictureBox and the button) until he wants to export the image. So make the Form size (692,318) pixels either by dragging it or by changing the Size property in the Properties window. Also make sure in the Properties window, the AutoSize property of the Form is set to False.

Setting AutoSize of the form to false

6. Before coding, you need to have a brief overview of how the exporting is done. We here at FusionCharts have created a .NET Class for you termed as ExportComponent.cs under the namespace FusionCharts. This class has a function that you can use to export your chart as an image. The Class can be downloaded from here.

The FusionCharts chart raises certain events in its lifetime. These events are termed as FlashCalls because they are raised by the flash movie.  The Shockwave Flash object in our form actually has an event called axShockwaveFlash1_FlashCall which is raised every time our chart raises an event. Whenever a user right clicks on the chart and selects Export As Image (or any analogous option), the raw bitmap data of the chart is created and the event FC_ExportDataReady is fired.

The raw bitmap data is returned in the form of an XML file. The class we have created takes this XML file and draws a bitmap image for you.  This bitmap image will be stored in the PictureBox in the Form. So you need to download our class and add it to your application. Right click on your application in the Solutions Explorer and select Add > Existing Item.

Add > Existing Item

Then browse to the location where you have saved the downloaded class and add it.

Before we begin with the actual coding process, we need to use the namespace of this class in our application. So in the namespace declaration section add the line

using FusionCharts;

7. Next we need to write the code to display the chart image in the PictureBox after the raw bitmap data has been gathered. Whenever the FlashCall event of the Shockwave object is fired, we will see if the particular event fired is called  FC_ExportDataReady or not. If this particular event is fired, it means that the chart image data is ready and so we can use this data to build the bitmap and display it in the pictureBox. So in the axShockwaveFlash1_FlashCall event insert the following code

//If the event requested by the chart contains the string FC_ExportDataReady

if (e.request.Contains(“FC_ExportDataReady”))

{

//Initiate a new instance (EC) of exportcomponent class

FusionCharts.ExportComponent EC = new FusionCharts.ExportComponent();

//Set the Autosize property of the form to true so that all the Form elements

//are displayed when the image is exported. If this is not done

//the PictureBox and the button will not be visible.

this.AutoSize = true;

//Pass the parameter of the event FC_ExportDataReady to the function

//EC.GetExportedImage in the class

pictureBox1.Image = EC.GetExportedImage(e.request);

}

Notice how we are setting the AutoSize property of the Form to true here. This is because we need the PictureBox (containing the image of the chart) and the button (to save this image) to be visible now that the chart image is generated and needs to be displayed. Setting this property to true will mean that the form will automatically re-size to display all the elements present in it.

8. Now that the bitmap image is generated and displayed, the image needs to be saved. The object button1 (which says ‘Save Chart As Image’ ) when clicked will enable the user to save it. In this example  the image will be saved in the .png format, but like we said earlier, just a little bit of tweaking will enable you to save it in any format you like. The SaveFileDialog will be used to set the location for the saved image. So in the button1_click event, write the following code:
try

{

//Specify a filename and extension for the file in the savefiledialogbox

saveFileDialog1.FileName = “My Exported Chart.png”;

//Show the savefiledialogbox

saveFileDialog1.ShowDialog();

//Initiate a new instance of System.IO.Filestream saves the image via a filestream

System.IO.FileStream SaveImg = (System.IO.FileStream)saveFileDialog1.OpenFile();

//save the image in the Png format. If any other System.Drawing.Imaging.ImageFormat Format is specified

//the image will be saved in that format instead of the PNG format.

pictureBox1. Image.Save(SaveImg, System.Drawing.Imaging.ImageFormat.Png);

}

catch (Exception)

{

//In case of error, i.e if the cancel button on the savedialogbox is clicked, show a messagebox.

MessageBox.Show(“OOPS!!!”);

}

There you have it. Simple yet effective. To save the image in any other format, instead of specifying the System.Drawing.Imaging.ImageFormat as Png, select the format of your choice.

9. Now we come to the fun part. Run your application. The chart will be loaded. Right-click on the chart and select Save as PNG.

Save as PNG option on right click

You will see a progress bar that shows the chart image data being gathered.

Chart image data being gathered

After the chart data is completely gathered, the form is automatically resized to include the PictureBox and the button. The PictureBox now contains the chart image. So the application now looks like:

Chartwithimage

On top, you have the actual chart, and right below it is the exported image. Now to save the image, click on Save Chart As Image. A save file dialog box appears – the one that we had included but never seen till now.

Save As dialog box

Select the location where you want to save the image and click save. Guess what? The chart that was once a flash object is now a PNG image in your local disk.

Last Words

Hopefully this three part tutorial has meant that now you are much more comfortable using FusionCharts in your Windows .NET applications than when you started off. So go out and try all that you have learnt. Impress both your boss and clients with the cool things that you can now do. And keep visiting this space for more tips and tricks on using FusionCharts, and charting in general. Happy charting till then.

  • Ricardo Cossich November 19, 2009, 1:50 pm

    I’m using c# 2008 express edition, following this post, but had to manually build the axShockwaveFlash1_FlashCall code (manually define it and code it), and it is never get called.
    The Company where i´m actually working had acquire Fushion Charts v 3.1.
    Would you send me the complete c# solution to my email?
    Regards,
    Ricardo Cossich.

  • Ricardo Cossich November 19, 2009, 3:08 pm

    Thanks for your response and support, actually i solved the problem, inserting this code axShockwaveFlash1.FlashCall+=new AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEventHandler(axShockwaveFlash1_FlashCall); somewhere in my form.
    Now i want to launch the export process without user intervention, is this possible?

  • sudi November 20, 2009, 12:47 pm

    Hi Ricardo,
    You can try these steps:
    1. Using FlashCall track whether the function FC_Rendered has been called for the specific chart
    2. Wait for 1/2 seconds (if you have animation – to let the animation finish)
    3. Use CallFunction() of the shockwave control to invoke exportChart() function. You need to build an XML (similar to the XML that is passed to FlashCall function) and pass it as the parameter of CallFunction method.
    Hope this helps.

  • Ricardo Cossich November 20, 2009, 5:34 pm

    Than Sudi for your response, i’m tracking requests sended to FlashCall and get this:
    null
    AND AFTER selecting Save as PNG: (I replaced the string for stream with …)
    fcExporter1nullFusionCharts_selfdownloadFC_ExportedPNG=Save as PNGPNG1nullFFFFFF248514Guitar Prices…
    =================================================================
    Should I call then FlashCall function within this same function when condition e.request.Contains(“FC_Rendered”) is TRUE building “e” parameter as the XML showed above in FC_ExportDataReady call?
    Thanks.

  • Ricardo Cossich November 20, 2009, 5:39 pm

    Sorry Sudi, my last post doesn´t look like when i wrote it. Will try to post it again later.

  • Ricardo Cossich November 20, 2009, 9:46 pm

    To all members of FushionCharts Team that helped me, thanks a lot!
    I Finally found the solution:
    Inserting this code in FlashCall Function:
    parametros = “null”;
    if (e.request.Contains(“FC_Rendered”))
    llamada = axShockwaveFlash1.CallFunction(parametros);
    Automatically gets the BMP in the image control of my form.
    Again, thanks a lot,
    Ricardo Cossich.

  • dimir February 12, 2010, 3:35 pm

    Hi, I need some help:
    If I have a label with a link, how can I handle if form .net?
    example:
    ?
    Thanks

  • Sudipto Choudhury February 13, 2010, 2:09 pm

    Hi dimir,
    As of now, labels do not support links to raise FlashCall events. Labels can only have HTML links which in turn can open URLs (websites) in browser when clicked.

  • rajesh March 13, 2010, 12:17 pm

    I am trying to export data to png file, I have added FlashCall Event but it is not working or there may be something missing in my code .(not get called on the right click on chart and select save as PNG option)
    also used the above code to add image to picture box inside the following FushCall event
    private void ChartContainer1_FlashCall(object sender, AxShockwaveFlashObjects._IShockwaveFlashEvents_FlashCallEvent e)

  • Sudipto Choudhury March 16, 2010, 11:34 am

    Hi Rajesh,
    It seems that your Flash Player Global Security settings are not properly set.
    You need to allow Flash Player to call extra flash functions like events etc.
    Please follow this and let us know:
    http://www.fusioncharts.com/forum/FindPost8077.aspx

  • Cuni April 27, 2010, 8:03 pm

    Having the scenario of FF not loading the chart when printing, and i would like to get the image to replace the chart on the print page.
    Is it possible to have the process you described above for getting the image, on a web application?
    -I am using MVC.net

  • Sudipto Choudhury May 9, 2010, 6:55 am

    Since it takes a bit of time to gather image-data before the equivalent image object can replace the chart and Firefox does not allow this lag time in onBeforePrint event, this is not possible as of now. We are working on this and would let you know.

  • Phillip July 29, 2010, 8:58 pm

    Is it possible, at all, in C# winforms, to embed the SWF to the project resources, and use that instead of a URL for the flash movie?  I dont want to rely on a secondary file in my installer, or a web url for this, would prefer just to use the embeded resources.

  • JotaPé September 16, 2010, 10:29 pm

    Hi, Excelent post. It has helped to me very much.
    I have only one question: What change i must to make in the code for to export the chart in any of the possible formats depending on the choice in the contextual menu of the right click on the chart.

  • Dan July 27, 2011, 6:04 pm

    I am able to load the charts fine using your examples, but when I try to use datasets, the chart says that there is no data to be loaded.  I’ve used the examples online and match the xml precisely, but still the same result.  The problem is not with the categories, but with the dataset tag itself, any thoughts?

    • Shamasis Bhattacharya July 28, 2011, 1:38 pm

      Just looking into possibilities: Are you sure that you are using the proper chart-type for your data? Data having “datasets” indicate that it is a multi-series or a stacked chart. Try replacing the chart SWF (in step 1) with MSColumn2D.swf or other multi-series chart types.

  • Dan July 28, 2011, 5:51 pm

    Sometimes the easiest explanation is the correct one.  I first tried with stacked and it worked, then I realized I had NOT been using MSColumn3D or 2D and so it was not working properly (I was using Column3D/2D).    It is now working as intended.  Thanks so much!

  • subbiah March 23, 2012, 4:03 pm

    can i export a chart automatically in windows application.

    Here the above code is working after clicking the “Save As PNG”.

    My requirment is has to export as image on page load

    Is it Possible. please help me.

    • Hrishikesh Choudhari March 27, 2012, 2:37 pm

      You can write the code for exporting the chart within a function that triggers on Page Load.

      • subbiah March 27, 2012, 2:56 pm

        hi hrishikesh choudhari,

        in FlashCall Event trigger we are using e.request.

        if i use the e.request in pageLoad, it shows the compilation error. please check the following code.

        if (e.request.Contains(“FC_ExportDataReady”))

        {
        //Initiate a new instance (EC) of exportcomponent class
        FusionCharts.
        ExportComponent EC = new FusionCharts.ExportComponent();//Set the Autosize property of the form to true so that all the Form elements//are displayed when the image is exported. If this is not done//the PictureBox and the button will not be visible.this.AutoSize = true;//Pass the parameter of the event FC_ExportDataReady to the function//EC.GetExportedImage in the class
        pictureBox1.Image = EC.GetExportedImage(e.request);

        }

        here e.request could not get on page_load.(showing error on page_load). Please help me.

        Thanks
        subbiah.

        • Hrishikesh Choudhari March 27, 2012, 3:03 pm

          The code you wrote above is the same as shown in the blog post. Are you saying you’re getting errors within this block? Where are you getting the compilation error?

          • subbiah March 27, 2012, 3:13 pm

            In page_Load if i use the above block . i got error.

  • subbiah March 24, 2012, 11:01 pm

    in windows application , shall i export images automatically without button click event.
     
    is it possible to export images when page load.
     
    Thanks
    subbiah.

  • Lucas February 26, 2013, 2:47 am

    So how do we save the chart w/o the right-click save as PNG interaction?  It says we need to call the exportChart() function in the FlashCall event after the FC_Rendered result.  But nobody shows us how to do that.  Can somebody explain how to do that?

    • Sanjukta February 27, 2013, 3:30 pm

      Please call the following function in FlashCall when ‘FC_Rendered’ is True to export the charts automatically after it is rendered.
      Ex: ChartContainer.CallFunction(“<invoke name=’exportChart’> </invoke>”); 

      The chart would be exported automatically instead of right-clicking on the chart. All the steps related to export, like XML configurations, etc. would be exactly the same as described in this post. 

  • mcborrero April 24, 2013, 6:42 am

    Hi,
    Can I use a link to another winform or do something to show me clik to give information?
    Something like this:
    link = ‘infocity.aspx id = 1’

    • Sanjukta April 26, 2013, 6:55 pm

      Please note that you can call a JavaScript function as link that in turn would open an aspx page or a winform, as mentioned in the JavaScript function. You can check with this page for details.
      You cannot open a winform directly on clicking a dataplot by providing the form ID on the “link” attribute.

  • Alex Silva October 10, 2015, 6:48 am

    Hi, first at all ‘kudos’ for the helpful winforms tutorials!
    I follow the 3 ones and it works fine, but… only with simple charts.
    If I try to use a multi-series chart I get: ‘No Data to Display’. Same code pointing to Line.swf and Line.xml, it works fine.
    It looks like not recognising some xml content.
    Any idea to help me? Thanks in advance!

Leave a Comment