1 /*********************************************************************************
2 * SugarCRM Community Edition is a customer relationship management program developed by
3 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU Affero General Public License version 3 as published by the
7 * Free Software Foundation with the addition of the following permission added
8 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
9 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
10 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * You should have received a copy of the GNU Affero General Public License along with
18 * this program; if not, see http://www.gnu.org/licenses or write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
23 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25 * The interactive user interfaces in modified source and object code versions
26 * of this program must display Appropriate Legal Notices, as required under
27 * Section 5 of the GNU Affero General Public License version 3.
29 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
30 * these Appropriate Legal Notices must retain the display of the "Powered by
31 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
32 * technical reasons, the Appropriate Legal Notices must display the words
33 * "Powered by SugarCRM".
34 ********************************************************************************/
39 function loadSugarChart (chartId,jsonFilename,css,chartConfig,pageCols) {
40 var labelType, useGradients, nativeTextSupport, animate;
42 var ua = navigator.userAgent,
43 typeOfCanvas = typeof HTMLCanvasElement,
44 nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
45 textSupport = nativeCanvasSupport
46 && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
48 nativeTextSupport = labelType == 'Native';
49 useGradients = nativeCanvasSupport;
53 var delay = (SUGAR.isIE) ? 500 : 0;
54 switch(chartConfig["chartType"]) {
56 var handleFailure = function(o){
58 if(o.responseText !== undefined){
62 var handleSuccess = function(o){
64 if(o.responseText !== undefined && o.responseText != "No Data"){
65 var json = eval('('+o.responseText+')');
67 var properties = $jit.util.splat(json.properties)[0];
68 var marginBottom = (chartConfig["orientation"] == 'vertical' && json.values.length > 8) ? 20*4 : 20;
70 var barChart = new $jit.BarChart({
71 //id of the visualization container
73 //whether to add animations
75 nodeCount: json.values.length,
76 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
77 backgroundColor: 'rgb(255,255,255)',
78 colorStop1: 'rgba(255,255,255,.8)',
79 colorStop2: 'rgba(255,255,255,0)',
84 //horizontal or vertical barcharts
85 orientation: chartConfig["orientation"],
88 text: properties['title'],
94 text: properties['subtitle'],
101 color: css["gridLineColor"]
104 barsOffset: (chartConfig["orientation"] == "vertical") ? 30 : 20,
105 //visualization offset
113 text: (chartConfig["scroll"] && SUGAR.util.isTouchScreen()) ? "Use two fingers to scroll" : "",
118 onClick: function(node) {
119 if(!node || SUGAR.util.isTouchScreen()) return;
120 if(node.link == 'undefined' || node.link == '') return;
121 window.location.href=node.link;
124 //labels offset position
127 type: useGradients? chartConfig["barType"]+':gradient' : chartConfig["barType"],
128 //whether to show the aggregation of the values
130 //whether to show the labels for the bars
134 type: labelType, //Native or HTML
136 family: css["font-family"],
143 onShow: function(tip, elem) {
144 if(elem.link != 'undefined' && elem.link != '') {
145 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
150 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
151 value = "elem.valuelabel";
153 value = "elem.value";
155 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
160 barChart.loadJSON(json);
166 var list = $jit.id('id-list'),
167 button = $jit.id('update'),
168 orn = $jit.id('switch-orientation');
169 //update json on click 'Update Data'
170 $jit.util.addEvent(button, 'click', function() {
171 var util = $jit.util;
172 if(util.hasClass(button, 'gray')) return;
173 util.removeClass(button, 'white');
174 util.addClass(button, 'gray');
175 barChart.updateJSON(json2);
178 //dynamically add legend to list
179 var list = $jit.id('legend'+chartId);
180 var legend = barChart.getLegend(),
181 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
182 rows = Math.ceil(legend["name"].length/cols),
183 table = "<table cellpadding='0' cellspacing='0' align='left'>";
185 for(i=0;i<rows;i++) {
187 for(td=0;td<cols;td++) {
189 table += '<td width=\'16\' valign=\'top\'>';
190 if(legend["name"][j] != undefined) {
191 table += '<div class=\'query-color\' style=\'background-color:'
192 + legend["color"][j] +'\'> </div>';
196 table += '<td class=\'label\' valign=\'top\'>';
197 if(legend["name"][j] != undefined) {
198 table += legend["name"][j];
208 list.innerHTML = table;
211 //save canvas to image for pdf consumption
212 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
214 var firstLoad = (SUGAR.isIE) ? true: false,
215 orgWindowWidth = document.body.offsetWidth,
216 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
218 var refreshGraph = function() {
219 var newWindowWidth = document.body.offsetWidth;
220 var diff = Math.abs(newWindowWidth - orgWindowWidth);
221 if(diff>20 && !firstLoad){
222 barChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
227 //refresh graph on window resize
229 var doRefresh = function() {
230 setTimeout(function() {refreshGraph()}, delay);
233 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
240 success:handleSuccess,
241 failure:handleFailure,
242 argument: { foo:'foo', bar:''}
245 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
249 var handleFailure = function(o){
251 if(o.responseText !== undefined){
255 var handleSuccess = function(o){
257 if(o.responseText !== undefined && o.responseText != "No Data"){
258 var json = eval('('+o.responseText+')');
260 var properties = $jit.util.splat(json.properties)[0];
262 var lineChart = new $jit.LineChart({
263 //id of the visualization container
265 //whether to add animations
267 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
268 backgroundColor: 'rgb(255,255,255)',
269 colorStop1: 'rgba(255,255,255,.8)',
270 colorStop2: 'rgba(255,255,255,0)',
271 selectOnHover: false,
273 text: properties['title'],
279 text: properties['subtitle'],
286 color: css["gridLineColor"]
288 //visualization offset
297 onClick: function(node) {
298 if(!node || SUGAR.util.isTouchScreen()) return;
299 if(node.link == 'undefined' || node.link == '') return;
300 window.location.href=node.link;
303 //labels offset position
306 type: useGradients? chartConfig["lineType"]+':gradient' : chartConfig["lineType"],
307 //whether to show the aggregation of the values
309 //whether to show the labels for the bars
313 type: labelType, //Native or HTML
315 family: css["font-family"],
322 onShow: function(tip, elem) {
323 if(elem.link != 'undefined' && elem.link != '') {
324 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
329 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
330 var value = "elem.valuelabel";
332 var value = "elem.value";
336 eval("var name = elem."+chartConfig["tip"]+";");
337 var content = '<table>';
339 for(var i=0; i<name.length; i++) {
340 content += '<tr><td><b>' + name[i] + '</b>:</td><td> ' + elem.value[i] + ' - ' + elem.percentage[i] + '%' + '</td></tr>';
342 content += '</table>';
343 tip.innerHTML = content;
345 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
351 lineChart.loadJSON(json);
355 var list = $jit.id('id-list'),
356 button = $jit.id('update'),
357 orn = $jit.id('switch-orientation');
358 //update json on click 'Update Data'
359 $jit.util.addEvent(button, 'click', function() {
360 var util = $jit.util;
361 if(util.hasClass(button, 'gray')) return;
362 util.removeClass(button, 'white');
363 util.addClass(button, 'gray');
364 barChart.updateJSON(json2);
367 //dynamically add legend to list
368 var list = $jit.id('legend'+chartId);
369 var legend = lineChart.getLegend(),
370 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
371 rows = Math.ceil(legend["name"].length/cols),
372 table = "<table cellpadding='0' cellspacing='0' align='left'>";
374 for(i=0;i<rows;i++) {
376 for(td=0;td<cols;td++) {
378 table += '<td width=\'16\' valign=\'top\'>';
379 if(legend["name"][j] != undefined) {
380 table += '<div class=\'query-color\' style=\'background-color:'
381 + legend["color"][j] +'\'> </div>';
385 table += '<td class=\'label\' valign=\'top\'>';
386 if(legend["name"][j] != undefined) {
387 table += legend["name"][j];
397 list.innerHTML = table;
400 //save canvas to image for pdf consumption
401 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
403 var firstLoad = (SUGAR.isIE) ? true: false,
404 orgWindowWidth = document.body.offsetWidth,
405 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
407 var refreshGraph = function() {
408 var newWindowWidth = document.body.offsetWidth;
409 var diff = Math.abs(newWindowWidth - orgWindowWidth);
410 if(diff>20 && !firstLoad){
411 lineChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
416 //refresh graph on window resize
418 var doRefresh = function() {
419 setTimeout(function() {refreshGraph()}, delay);
422 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
429 success:handleSuccess,
430 failure:handleFailure,
431 argument: { foo:'foo', bar:''}
434 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
440 var handleFailure = function(o){
442 if(o.responseText !== undefined){
446 var handleSuccess = function(o){
448 if(o.responseText !== undefined){
449 var json = eval('('+o.responseText+')');
450 var properties = $jit.util.splat(json.properties)[0];
453 var pieChart = new $jit.PieChart({
454 //id of the visualization container
456 //whether to add animations
458 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
459 backgroundColor: 'rgb(255,255,255)',
460 colorStop1: 'rgba(255,255,255,.8)',
461 colorStop2: 'rgba(255,255,255,0)',
462 labelType: properties['labels'],
469 type: useGradients? chartConfig["pieType"]+':gradient' : chartConfig["pieType"],
470 //whether to show the labels for the slices
473 text: properties['title'],
479 text: properties['subtitle'],
492 onClick: function(node) {
493 if(!node || SUGAR.util.isTouchScreen()) return;
494 if(node.link == 'undefined' || node.link == '') return;
495 window.location.href=node.link;
500 type: labelType, //Native or HTML
502 family: css["font-family"],
508 onShow: function(tip, elem) {
509 if(elem.link != 'undefined' && elem.link != '') {
510 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
515 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
516 value = "elem.valuelabel";
518 value = "elem.value";
520 eval("tip.innerHTML = '<b>' + elem.label + '</b>: ' + "+ value +" + ' - ' + elem.percentage + '%' + drillDown");
525 pieChart.loadJSON(json);
527 //dynamically add legend to list
528 var list = $jit.id('legend'+chartId);
529 var legend = pieChart.getLegend(),
530 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
531 rows = Math.ceil(legend["name"].length/cols);
532 table = "<table cellpadding='0' cellspacing='0' align='left'>";
534 for(i=0;i<rows;i++) {
536 for(td=0;td<cols;td++) {
538 table += '<td width=\'16\' valign=\'top\'>';
539 if(legend["name"][j] != undefined) {
540 table += '<div class=\'query-color\' style=\'background-color:'
541 + legend["color"][j] +'\'> </div>';
545 table += '<td class=\'label\' valign=\'top\'>';
546 if(legend["name"][j] != undefined) {
547 table += legend["name"][j];
557 list.innerHTML = table;
560 //save canvas to image for pdf consumption
561 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
563 var firstLoad = (SUGAR.isIE) ? true: false,
564 orgWindowWidth = document.body.offsetWidth,
565 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
567 var refreshGraph = function() {
568 var newWindowWidth = document.body.offsetWidth;
569 var diff = Math.abs(newWindowWidth - orgWindowWidth);
570 if(diff>20 && !firstLoad){
571 pieChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
576 //refresh graph on window resize
578 var doRefresh = function() {
579 setTimeout(function() {refreshGraph()}, delay);
582 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
590 success:handleSuccess,
591 failure:handleFailure,
592 argument: { foo:'foo', bar:''}
595 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
602 var handleFailure = function(o){
604 if(o.responseText !== undefined){
608 var handleSuccess = function(o){
610 if(o.responseText !== undefined && o.responseText != "No Data"){
611 var json = eval('('+o.responseText+')');
613 var properties = $jit.util.splat(json.properties)[0];
616 var funnelChart = new $jit.FunnelChart({
617 //id of the visualization container
619 //whether to add animations
621 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
622 backgroundColor: 'rgb(255,255,255)',
623 colorStop1: 'rgba(255,255,255,.8)',
624 colorStop2: 'rgba(255,255,255,0)',
625 //orientation setting should not be changed
626 orientation: "vertical",
629 text: properties['title'],
635 text: properties['subtitle'],
642 //visualization offset
651 onClick: function(node) {
652 if(!node || SUGAR.util.isTouchScreen()) return;
653 if(node.link == 'undefined' || node.link == '') return;
654 window.location.href=node.link;
657 //labels offset position
660 type: useGradients? chartConfig["funnelType"]+':gradient' : chartConfig["funnelType"],
661 //whether to show the aggregation of the values
663 //whether to show the labels for the bars
667 type: labelType, //Native or HTML
669 family: css["font-family"],
676 onShow: function(tip, elem) {
677 if(elem.link != 'undefined' && elem.link != '') {
678 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
683 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
684 value = "elem.valuelabel";
686 value = "elem.value";
688 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
693 funnelChart.loadJSON(json);
697 var list = $jit.id('id-list'),
698 button = $jit.id('update'),
699 orn = $jit.id('switch-orientation');
700 //update json on click 'Update Data'
701 $jit.util.addEvent(button, 'click', function() {
702 var util = $jit.util;
703 if(util.hasClass(button, 'gray')) return;
704 util.removeClass(button, 'white');
705 util.addClass(button, 'gray');
706 barChart.updateJSON(json2);
709 //dynamically add legend to list
710 var list = $jit.id('legend'+chartId);
711 var legend = funnelChart.getLegend(),
712 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
713 rows = Math.ceil(legend["name"].length/cols);
714 table = "<table cellpadding='0' cellspacing='0' align='left'>";
716 for(i=0;i<rows;i++) {
718 for(td=0;td<cols;td++) {
720 table += '<td width=\'16\' valign=\'top\'>';
721 if(legend["name"][j] != undefined) {
722 table += '<div class=\'query-color\' style=\'background-color:'
723 + legend["color"][j] +'\'> </div>';
727 table += '<td class=\'label\' valign=\'top\'>';
728 if(legend["name"][j] != undefined) {
729 table += legend["name"][j];
739 list.innerHTML = table;
741 //save canvas to image for pdf consumption
742 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
744 var firstLoad = (SUGAR.isIE) ? true: false,
745 orgWindowWidth = document.body.offsetWidth,
746 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
748 var refreshGraph = function() {
749 var newWindowWidth = document.body.offsetWidth;
750 var diff = Math.abs(newWindowWidth - orgWindowWidth);
751 if(diff>20 && !firstLoad){
752 funnelChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
757 //refresh graph on window resize
759 var doRefresh = function() {
760 setTimeout(function() {refreshGraph()}, delay);
763 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
771 success:handleSuccess,
772 failure:handleFailure,
773 argument: { foo:'foo', bar:''}
776 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
783 var handleFailure = function(o){
785 if(o.responseText !== undefined){
789 var handleSuccess = function(o){
791 if(o.responseText !== undefined){
792 var json = eval('('+o.responseText+')');
793 var properties = $jit.util.splat(json.properties)[0];
796 var gaugeChart = new $jit.GaugeChart({
797 //id of the visualization container
799 //whether to add animations
801 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
802 backgroundColor: 'rgb(255,255,255)',
803 colorStop1: 'rgba(255,255,255,.8)',
804 colorStop2: 'rgba(255,255,255,0)',
805 labelType: properties['labels'],
808 text: properties['title'],
814 text: properties['subtitle'],
822 backgroundColor: '#aaaaaa',
823 borderColor: '#999999',
824 needleColor: 'rgba(255,0,0,.8)',
826 positionFontSize: 24,
830 type: useGradients? chartConfig["gaugeType"]+':gradient' : chartConfig["gaugeType"],
831 //whether to show the labels for the slices
835 onClick: function(node) {
836 if(!node || SUGAR.util.isTouchScreen()) return;
837 if(node.link == 'undefined' || node.link == '') return;
838 window.location.href=node.link;
843 type: labelType, //Native or HTML
845 family: css["font-family"],
851 onShow: function(tip, elem) {
852 if(elem.link != 'undefined' && elem.link != '') {
853 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
857 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
858 value = "elem.valuelabel";
860 value = "elem.value";
862 eval("tip.innerHTML = '<b>' + elem.label + '</b>: ' + "+ value +" + drillDown");
867 gaugeChart.loadJSON(json);
870 var list = $jit.id('legend'+chartId);
871 var legend = gaugeChart.getLegend(),
872 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
873 rows = Math.ceil(legend["name"].length/cols);
874 table = "<table cellpadding='0' cellspacing='0' align='left'>";
876 for(i=0;i<rows;i++) {
878 for(td=0;td<cols;td++) {
880 table += '<td width=\'16\' valign=\'top\'>';
881 if(legend["name"][j] != undefined) {
882 table += '<div class=\'query-color\' style=\'background-color:'
883 + legend["color"][j] +'\'> </div>';
887 table += '<td class=\'label\' valign=\'top\'>';
888 if(legend["name"][j] != undefined) {
889 table += legend["name"][j];
899 list.innerHTML = table;
902 //save canvas to image for pdf consumption
903 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
905 var firstLoad = (SUGAR.isIE) ? true: false,
906 orgWindowWidth = document.body.offsetWidth,
907 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
909 var refreshGraph = function() {
910 var newWindowWidth = document.body.offsetWidth;
911 var diff = Math.abs(newWindowWidth - orgWindowWidth);
912 if(diff>20 && !firstLoad){
913 gaugeChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
918 //refresh graph on window resize
920 var doRefresh = function() {
921 setTimeout(function() {refreshGraph()}, delay);
924 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
932 success:handleSuccess,
933 failure:handleFailure,
934 argument: { foo:'foo', bar:''}
937 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);