There are two large issues I have experienced with ZingCharts. To begin, I will list the two errors I am experiencing, how to cause them, and how to fix one of them.
So, the two errors:
- Plot point tooltips unbind. This error occurs when you have more than one chart on a page and you use AJAX to reload one of the charts. When the page first loads, the tooltips will work on both charts. After you have used AJAX to update one of the charts, that chart's tooltips will work, the tooltips for the other chart(s) on the page will no longer function.
- After an AJAX update on a chart, the chart fails to load and only a white block is rendered. This error will only occur after the first error has been fixed and at least one chart on the page has a visible crosshair-x attribute. After you use AJAX to update one of the charts, that chart will fail to render and will just be an empty block.
The causes:
- When ColdFusion uses the <cf/> tags, in this case <cfchart/>, it automatically injects the necessary JavaScript files into the request. When multiple charts and other tags are all in one request, it knows to only second those scripts once and everything will function properly. However, when you use AJAX to update a <cfchart/> on a page, ColdFusion will again inject those JavaScript files, which overwrite previous variables and causes inconsistencies with bound elements. In this case, the zingchart object from cfchart-lite.js is overwritten and the logic within cfchart-html.js is ran again. When this happens the JavaScript variables are impacted and some of the previously bound functionality dies - in this case the tooltips on charts that were not just loaded.
- This is where my primary issue lies. I can resolve the issue from problem one, but as my description of problem two states, it causes this new issue. The only salvation for most use-cases is that if there are no charts on the page with crosshairs, issue two will not present itself.
The solutions:
- Update cfchart-html.js and cfchart-lite.js to prevent rebinding of the variables.
- cfchart-html.js - Add an if condition around the eval logic
if (window.zingChartsLoaded === undefined) {
// eval(function(p,a,c,k,e,d))...
window.zingChartsLoaded = true;
}
- cfchart-lite.js - Add an if condition around the zingchart variable creation
if (typeof zingchart == 'undefined')
- No solution yet.
The following ColdFusion/HTML can generate both issues with minor tweaks. Save the file as chartTest.cfm
<cfparam name="url.chartOnly" default="" />
<cfif url.chartOnly EQ "">
<html>
<head>
<title>Chart Test</title>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
<script>
$(document).ready(function() {
$("a").click(function(event) {
if (typeof zingchart != 'undefined')
zingchart.exec("chart-" + $(this).prev().attr("id"), "destroy");
$(this).prev().load($(this).attr("href"));
return false;
}).click();
});
</script>
</head>
<body>
<div id="one"></div>
<a href="/chartTest.cfm?chartOnly=one">Reload Chart</a>
<div id="two"></div>
<a href="/chartTest.cfm?chartOnly=two">Reload Chart</a>
</body>
</html>
<cfelse>
<cfoutput>#generateChart(id="chart-#url.chartOnly#")#</cfoutput>
</cfif>
<cffunction name="generateChart" returntype="void" access="public">
<cfargument name="id" type="string" required="true" />
<cfchart format="html" width="1080" height="350" id="#arguments.id#" title="Testing" crosshair="#{'line-width'=1}#">
<cfchartseries type="bar">
<cfif arguments.id EQ "chart-one">
<cfchartdata item="a" value="1" />
<cfchartdata item="b" value="2" />
<cfchartdata item="c" value="3" />
<cfelse>
<cfchartdata item="c" value="3" />
<cfchartdata item="b" value="2" />
<cfchartdata item="a" value="1" />
</cfif>
</cfchartseries>
</cfchart>
</cffunction>
Testing/replication:
- If you have not fixed the JavaScript files yet, hitting the 'Reload Chart' link below either chart will break the other chart's tooltips.
- After you have fixed the JavaScript files, hitting the 'Reload Chart' link under either chart will fail and you will get a white block.