mightyenigma

Chrome Refuses Exportchart()

Recommended Posts

All browsers except Chrome will execute the call to someChartObject.exportChart();

 

There is no error, it just does nothing at that line of code and continues on with the rest of the script perfectly.

 

 

Maybe it's getting a different object than the other browsers, an object that doesn't have that method?

 

I get the charts in a loop: for (chartId in FusionCharts.items)

and inside the loop: var curChart = getChartFromId(chartId);

and then inside the loop I call: curChart.exportChart();

 

Every line of code executes except for that one. It's as if it's commented out.

 

P.S. Maybe it's executing and just deciding to do nothing?

Edited by mightyenigma

Share this post


Link to post
Share on other sites
Guest Bindhu

Hi,

 

Please share the sample code to test from our end.

 

If possible, please share a live URL using which we can replicate the issue.

Share this post


Link to post
Share on other sites

Hi,

 

Please share the sample code to test from our end.

 

If possible, please share a live URL using which we can replicate the issue.

 

Thank you. I included doneSavingChart() just so the rest would make more sense. During the problem though, since no exports happen, the callback doneSavingChart never happens either.

There is a lot that goes into all this across multiple files, so for you to be able to test it I'd have to put quite some time into developing a reduced test case.

I hope you can ascertain some flaw that is Chrome-specific by just reviewing the code. I would like to include the chart HTML but it contains company information that I probably don't have permission to divulge.

I'm sorry that's not very helpful. If reviewing the code gives nothing significant to pursue as a possible solution, I'll see what else I can arrange for you.

 

Keep in mind it's specifically a Chrome issue. Testing in Firefox, IE, and Safari this problem does not occur. Have not tested in Opera yet.

 

 

//callback for when a chart finishes saving to server disk. This was set up in dashboard_body.php
function doneSavingChart(objRtn){
		var domID = objRtn.DOMId;
		var fileName = objRtn.fileName;

		//window.setTimeout(function(){
			numChartsSaved++;
			var fileNameContainerId = 'chartFileName---' + domID;
			$('#' + fileNameContainerId).text(fileName);
			var chartDiv = $('#' + domID).closest('.frame').find('div');
			//$(chartDiv).css({left:'', top:'', bottom:'0', right:'0'});
			//busyChart = null;//clear it here to start another chart exporting when the current one is finished.

			if (numChartsSaved < numChartsToSave){
			return;
			}else{
			window.clearInterval(exportProcessTimer);
			var dataObj = new Object();
			dataObj.sectionLabel = $('#menu li.current').text().replace(trimPattern, '');
			dataObj.dateRange = fetchDateRange();
			dataObj.chartData = fetchChartData();

			postReport(dataObj);
			}
		//}, 500);//small delay to make sure the picture has finished saving.
}


//timed polling function to take next action in report/export process:
function exportCharts(){

		busyChart = null;//clear busyChart here if you want it to start another export every time the exportcharts timer fires. clear it in doneSavingChart to start another one every time a chart completely finishes exporting.
		//I am putting this delay in between calling somechart.exportChart() because I have observed it prevents blank image exports (otherwise file handle getting yanked before it can write? It was not designed for bath exporting after all).

		if (numFlashChartsMade < numChartsToSave){
			//$('.ui-jqgrid-titlebar-close').click();//open them back up. Probably not important for FusionChart export, but this way I can see everything non-chart that we'll be putting in the PDF.

			for (var chartId in FusionCharts.items){
			var curChart = getChartFromId(chartId);

			if (curChart.hasGeneratedExportCharts || curChart.isExportChart){

				continue;//don't generate exportable charts from already-exportable charts. That's an exponentially growing recursion right there!'
			}	
			curChart.hasGeneratedExportCharts = true;

			var myFrame = $('#' + chartId + 'Div').closest('.frame');
			var frameName = $(myFrame).attr('id').split('_')[0];

			//this is for the existing chart on the page, IF it has export => true:
			if ($(myFrame).hasClass('exportChart')) {
				$(myFrame).removeClass('exportChart');//shouldn't need to do that with the hasGeneratedExportCharts member in place.

				var newChartParams = curChart.clone({renderer: 'flash', id: chartId, width: 240, height: 177}, true);//true makes it just return the params
				curChart.dispose();//get rid of JS chart so it doesn't cause a DOM id conflict when we create flash version of chart
				var myClone = new FusionCharts(newChartParams);//create flash version so we can export to server.
				numFlashChartsMade++;
				myClone.setChartAttribute('animation', 0);//keep it from exporting the unfinished animation frames instead of the finished plot, by disabling animation on this flash version of it.
				myClone.render();

				getChartFromId(chartId).isExportChart = true;//new chart should have same id as old one; we set it so in newChartParams.

				var origChartDiv = $('#' + chartId + 'Div');//which section of the page do these charts belong to?
				$(origChartDiv).css({width: '240px', height: '177px'});//A forum post stated that percent-unit chart div container dimensions can adversely affect rendering, so I give specific pixel dimensions here.
				var exportedChartFileName = document.createElement('span');
				$(exportedChartFileName).addClass('chartFileName');
				$(exportedChartFileName).attr('id', 'chartFileName---' + chartId);
				$(exportedChartFileName).css('display','none');
				$(origChartDiv).append(exportedChartFileName);
			}

			//This is for the action stubs in marketing.php that have export => true:
			//Those that have that flag set will have a function to call in exportReportFunctions array.
			//createExportCharts is the callback for the ajax in those functions.
			if ('undefined' !== typeof(exportReportFunctions[frameName])){
				for (var i = 0; i < exportReportFunctions[frameName].length; i++){
				if('undefined' !== typeof(exportReportFunctions[frameName][i])){
					exportReportFunctions[frameName][i](chartId);
				}
				}
			}

			}
		}else if (numChartsToSave > 0){

			for (var chartId in FusionCharts.items){ //not using cloneCharts array here because it doesn't contain the needed mappings, but I do believe it contains our cloned charts....
			var curChart = getChartFromId(chartId);

			if ( null == busyChart && curChart.hasRendered && curChart.hasRendered() && !curChart.exportHasBeenCalled && curChart.isExportChart){
				busyChart = curChart;//let's just do one at a time. pixels must be in the viewport for export to succeed, apparently (except in firefox. We can do them all at once in Firefox).

				curChart.scrollIntoView();//even the fixed position won't always bring chart into view. Safari doesn't even treat it like it exists until viewport has touched it. So we scroll to make sure it has to be acknowledged and rendered.

				var myTop	= ($(window).height() - 177)*0.5;
				var myLeft	= ($(window).width() - 240)*0.5; 

				$(curChart).closest('.frame').css({border:'2px solid black', position:'fixed', top:''+myTop+'px', left:''+myLeft+'px', width:'240px', height:'177px', 'z-index':'1000'});//A forum post stated that percent-unit chart div container dimensions can adversely affect rendering, so I give specific pixel dimensions here.
				curChart.exportChart({exportFormat: 'PNG'});//doneSavingChart callback will redirect when all charts have finished.
				curChart.exportHasBeenCalled = true;//so the call doesn't get repeated next time the process polling timer fires.

			}
			}
		}else{///no charts to save. Get datagrids at least.
			//this code is repeated in doneSavingChart()
			window.clearInterval(exportProcessTimer);
			var dataObj = new Object();
			dataObj.sectionLabel = $('#menu li.current').text().replace(trimPattern, '');
			dataObj.dateRange = fetchDateRange();
			dataObj.chartData = fetchChartData();

			postReport(dataObj);
		}
}

function printOutCharts(){

		numChartsSaved = 0;
		numFlashChartsMade = 0;

		//Add the number of charts which are already on the page and which are flagged as 'exportChart'.
		$('.exportChart').each(function(){
			numChartsToSave++;
		});

		exportProcessTimer = window.setInterval(exportCharts, 1500);

		if ($('#modal-mask').length == 0){
			var mask = document.createElement('div');
			$(mask).attr('id', 'modal-mask').css({width:'100%', height:'100%', position:'fixed', top:'0px', left:'0px', background:'rgba(255,255,255,0.77)', filter:'Alpha(Opacity=77)', 'z-index':500});
			$(document.body).append(mask);
		}
}

Share this post


Link to post
Share on other sites
Guest Bindhu

Hi,

 

From what I understand, you are trying to clone the chart and export the cloned chart.

 

I created a sample demo project that illustrates "Clone + Export" of the cloned chart.

 

This works fine in Chrome browser.

 

If this is not what you are looking for, please elaborate a bit more.

 

Also, please provide us the debug information along with a live URL for further testing.

 

Please share your email id to receive the sample demo created.

Edited by Bindhu

Share this post


Link to post
Share on other sites

Thank you for testing it on your system. I must be doing something in my javascript that is preventing the export() function call somehow. Perhaps the inclusion of another Javascript library is interfering. At least I know that it should be working in chrome, even on a cloned Flash chart. That helps narrow down the problem a bit.

 

I would like to receive your demo at [email protected]

 

By comparing our code I may be able to find the flaw in mine.

Share this post


Link to post
Share on other sites

Thank you for the slick example.

 

Unfortunately I miscommunicated what I need.

 

My code successfully clones an exportable flash chart, after starting with a HTML/JS/SVG chart on the page.

That's what I want.

 

But the part that isn't working (only in Google Chrome, no other browsers have this problem) is when the method exportChart() is called by my script.

 

When the code hits that point (and I've debugged step by step to ensure this is the spot it fails at), then the javascript simply halts with no error.

It's as if the exportChart method doesn't exist on the clone.

 

The strange thing is that I can trigger this exportChart() method from the Google Chrome console. Why won't it let my script see the method, but it lets it see all other methods (except for maybe hasRendered or isActive?)

All other browsers can see these methods on the JS objects that correspond to the flash charts on the page.

 

 

 

Aaron McC

 

 

Hi,

 

I have sent the demo project to your email id.

 

Hope this helps!

Share this post


Link to post
Share on other sites

Correction:

 

I just put console.log() calls immediately before and after the failing exportChart() call. Both console.logs execute successfully. However, the chart does not start the bitmap scanning process to create the image file. It will in other browsers, just not in Chrome.

Do I need to insert a small delay before calling exportChart to have it scan the image out to a file in Chrome?

Share this post


Link to post
Share on other sites

I have debugged and dug in a little deeper.

 

I have found that

for (var chartId in FusionCharts.items){
var curChart = getChartFromId(chartId);
if (curChart.hasRendered()){
	curChart.exportChart();
}	
}

 

 

just loops through and never exports any charts in Chrome, but works great in all other browsers.

Share this post


Link to post
Share on other sites

Here is the same sample with the delay added:

 

for (var chartId in FusionCharts.items){
var curChart = getChartFromId(chartId);
if (curChart.hasRendered()){
        window.setTimeout(function(){
	curChart.exportChart();
  }, 5000);
}	
}

 

Why do you suppose the SWF objects need this delay before calling their Javascript exportCharts() hook will do anything? Maybe they javascript and html are done rendering and being defined before the SWF objects finish loading?

Share this post


Link to post
Share on other sites

Actually now even with the delay it refuses to export anything in Chrome.

Maybe the delay does not help after all.

 

How do I make the SWF call FCExporter like it does in all the other browsers?

Share this post


Link to post
Share on other sites

Hi,

 

Is you application running from a Web server and the URL to the ExportHandler lies in the same domain?

 

Yes, they are in the same domain.

 

I solved the problem by removing the Javascript command to set the charts' container div's CSS to have position: fixed.

I seems that this causes the Flash object to be erased temporarily and then re-instated after the container div has been moved to the fixed-position space in the browser window.

So to have the fixed position (thereby allowing the chart to scan the bitmap for export no matter where the user scrolls to) AND actually export, I had to load all the charts,

position them, wait for 1000ms, and THEN call exportChart() on all of the charts. That way works great.

Share this post


Link to post
Share on other sites
Hi,

 

I have code to export multiple charts as image as below

 

var firstChartObject = getChartFromId("first");

firstChartObject .exportChart({});

 

var secondChartObject = getChartFromId("second");

secondChartObject.exportChart({});

 

var thirdChartObject = getChartFromId("third");

thirdChartObject .exportChart({});

 

My chart are getting rendered in Bootstrap Modal. Only two chart are visible other chart will come after scrolling down.

 

Problem is since only two charts are visible only those two chart are getting exported other one is not getting exported. only when I scroll down exporting of third chart will start.

 

And also if first chart is half exported and I scroll down exporting of first chart will stop in between. Only visible charts are getting exported.

 

Please give me solution. Thanks in advance.

Share this post


Link to post
Share on other sites

Even I have chartObject.hasRendered() condition for all three exports.

 

After all the charts are rendered, onclick of button I am calling method to export the charts.

Share this post


Link to post
Share on other sites

I have code for multiple chart export as below

 

var firstChartObject = getChartFromId("first");
if(firstChartObject  && firstChartObject .hasRendered()){
    firstChartObject .exportChart({});
}

 

var secondChartObject = getChartFromId("second");
if(secondChartObject && secondChartObject .hasRendered()){
    secondChartObject .exportChart({});
}
 
var thirdChartObject = getChartFromId("third");
if(thirdChartObject && thirdChartObject .hasRendered()){
    thirdChartObject .exportChart({});
}
 
It is working fine in Mozilla Firefox browser.
 
Not working in Chrome and IE
 
The problem is Since third chart is out of focus, export of third chart is not happening. Only first two charts are getting exported. When third chart comes into focus after scrolling down the page, exporting of third chart will start. 
 
I have to export all the charts without scrolling down the page.
 
Please help me to make it work. Thanks.
 
 
Edited by sun123

Share this post


Link to post
Share on other sites

Hey,

 

As per my understanding, issue mentioned here seems to be related to Flash charts.

 

FusionCharts along with Flash Player, does not allow the charts to render until it is in the viewable area of the browser page.

The exporting of the charts, which are not in the viewable portion of the browser naturally does not take place as the charts are not rendered. This process can only be performed if the page is scrolled down and all the charts in the page are forced to render.

 

Please note: We have deprecated the support for Flash. Starting FusionCharts Suite v3.4, FusionCharts is a pure JavaScript library. 

JavaScript charts does not support batch 

 

If you would like to export the entire charts[JavaScript mode] present in a page, we suggest you to use "PhantomJS" or "wkhtmltoimage" third party library, which will generate the reports of charts, at server side.

 

The details of the implementation you could find from our blog post link: http://blog.fusioncharts.com/2013/03/how-to-save-charts-as-images-at-server-side/

 

Hope this helps.

Share this post


Link to post
Share on other sites

Hi,

 

Thanks for the quick reply.

 

As mightyenigma mentioned   "I solved the problem by removing the Javascript command to set the charts' container div's CSS to have position: fixed."

 

Is it possible to set position css and make it working.

 

Because Since its working in Mozilla Firefox I think we can make it work with Chrome and IE.

Share this post


Link to post
Share on other sites

Hi, when i am exporting a chart using exportChart() method nothing happens in chrome, but working in all browsers plz help me how to fix this issue to work in chrome 

 

Below is my code :

 

 <input type="image" id="img123" onclick="ExportMyChart()" class="pull-right" style="margin-left: 16px;" src="~/Images/jpg-20.png" Height="18px" Width="17px" />

 

 function ExportMyChart() {            
            var chartObject = document.getElementById('exp1');
            if (chartObject.hasRendered())
              chartObject.exportChart({ exportAtClient: '1', exportFormat: 'JPEG' });             
        }
 
PLz help me how to fix this issue its urgent
Edited by surendravanga

Share this post


Link to post
Share on other sites

Hi

 

Please share the scaled down sample with complete source code with us so that we can assist you accordingly. Also, please mention which version of FusionCharts Suite are you using?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now