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) {
42 if(document.getElementById(chartId) == null) {
45 var labelType, useGradients, nativeTextSupport, animate;
47 var ua = navigator.userAgent,
48 typeOfCanvas = typeof HTMLCanvasElement,
49 nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
50 textSupport = nativeCanvasSupport
51 && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
53 nativeTextSupport = labelType == 'Native';
54 useGradients = nativeCanvasSupport;
58 var delay = (SUGAR.isIE) ? 500 : 0;
59 switch(chartConfig["chartType"]) {
61 var handleFailure = function(o){
63 if(o.responseText !== undefined){
67 var handleSuccess = function(o){
69 if(o.responseText !== undefined && o.responseText != "No Data"){
70 var json = eval('('+o.responseText+')');
72 var properties = $jit.util.splat(json.properties)[0];
73 var marginBottom = (chartConfig["orientation"] == 'vertical' && json.values.length > 8) ? 20*4 : 20;
75 var barChart = new $jit.BarChart({
76 //id of the visualization container
78 //whether to add animations
80 nodeCount: json.values.length,
81 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
82 backgroundColor: 'rgb(255,255,255)',
83 colorStop1: 'rgba(255,255,255,.8)',
84 colorStop2: 'rgba(255,255,255,0)',
89 //horizontal or vertical barcharts
90 orientation: chartConfig["orientation"],
93 text: properties['title'],
99 text: properties['subtitle'],
106 color: css["gridLineColor"]
109 barsOffset: (chartConfig["orientation"] == "vertical") ? 30 : 20,
110 //visualization offset
118 text: (chartConfig["scroll"] && SUGAR.util.isTouchScreen()) ? "Use two fingers to scroll" : "",
123 onClick: function(node) {
124 if(!node || SUGAR.util.isTouchScreen()) return;
125 if(node.link == 'undefined' || node.link == '') return;
126 window.location.href=node.link;
129 //labels offset position
132 type: useGradients? chartConfig["barType"]+':gradient' : chartConfig["barType"],
133 //whether to show the aggregation of the values
135 //whether to show the labels for the bars
139 type: labelType, //Native or HTML
141 family: css["font-family"],
148 onShow: function(tip, elem) {
149 if(elem.link != 'undefined' && elem.link != '') {
150 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
155 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
156 value = "elem.valuelabel";
158 value = "elem.value";
160 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
165 barChart.loadJSON(json);
171 var list = $jit.id('id-list'),
172 button = $jit.id('update'),
173 orn = $jit.id('switch-orientation');
174 //update json on click 'Update Data'
175 $jit.util.addEvent(button, 'click', function() {
176 var util = $jit.util;
177 if(util.hasClass(button, 'gray')) return;
178 util.removeClass(button, 'white');
179 util.addClass(button, 'gray');
180 barChart.updateJSON(json2);
183 //dynamically add legend to list
184 var list = $jit.id('legend'+chartId);
185 var legend = barChart.getLegend(),
186 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
187 rows = Math.ceil(legend["name"].length/cols),
188 table = "<table cellpadding='0' cellspacing='0' align='left'>";
190 for(i=0;i<rows;i++) {
192 for(td=0;td<cols;td++) {
194 table += '<td width=\'16\' valign=\'top\'>';
195 if(legend["name"][j] != undefined) {
196 table += '<div class=\'query-color\' style=\'background-color:'
197 + legend["color"][j] +'\'> </div>';
201 table += '<td class=\'label\' valign=\'top\'>';
202 if(legend["name"][j] != undefined) {
203 table += legend["name"][j];
213 list.innerHTML = table;
216 //save canvas to image for pdf consumption
217 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
219 var firstLoad = (SUGAR.isIE) ? true: false,
220 orgWindowWidth = document.body.offsetWidth,
221 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
223 var refreshGraph = function() {
224 var newWindowWidth = document.body.offsetWidth;
225 var diff = Math.abs(newWindowWidth - orgWindowWidth);
226 if(diff>20 && !firstLoad){
227 barChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
232 //refresh graph on window resize
234 var doRefresh = function() {
235 setTimeout(function() {refreshGraph()}, delay);
238 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
245 success:handleSuccess,
246 failure:handleFailure,
247 argument: { foo:'foo', bar:''}
250 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
254 var handleFailure = function(o){
256 if(o.responseText !== undefined){
260 var handleSuccess = function(o){
262 if(o.responseText !== undefined && o.responseText != "No Data"){
263 var json = eval('('+o.responseText+')');
265 var properties = $jit.util.splat(json.properties)[0];
267 var lineChart = new $jit.LineChart({
268 //id of the visualization container
270 //whether to add animations
272 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
273 backgroundColor: 'rgb(255,255,255)',
274 colorStop1: 'rgba(255,255,255,.8)',
275 colorStop2: 'rgba(255,255,255,0)',
276 selectOnHover: false,
278 text: properties['title'],
284 text: properties['subtitle'],
291 color: css["gridLineColor"]
293 //visualization offset
302 onClick: function(node) {
303 if(!node || SUGAR.util.isTouchScreen()) return;
304 if(node.link == 'undefined' || node.link == '') return;
305 window.location.href=node.link;
308 //labels offset position
311 type: useGradients? chartConfig["lineType"]+':gradient' : chartConfig["lineType"],
312 //whether to show the aggregation of the values
314 //whether to show the labels for the bars
318 type: labelType, //Native or HTML
320 family: css["font-family"],
327 onShow: function(tip, elem) {
328 if(elem.link != 'undefined' && elem.link != '') {
329 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
334 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
335 var value = "elem.valuelabel";
337 var value = "elem.value";
341 eval("var name = elem."+chartConfig["tip"]+";");
342 var content = '<table>';
344 for(var i=0; i<name.length; i++) {
345 content += '<tr><td><b>' + name[i] + '</b>:</td><td> ' + elem.value[i] + ' - ' + elem.percentage[i] + '%' + '</td></tr>';
347 content += '</table>';
348 tip.innerHTML = content;
350 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
356 lineChart.loadJSON(json);
360 var list = $jit.id('id-list'),
361 button = $jit.id('update'),
362 orn = $jit.id('switch-orientation');
363 //update json on click 'Update Data'
364 $jit.util.addEvent(button, 'click', function() {
365 var util = $jit.util;
366 if(util.hasClass(button, 'gray')) return;
367 util.removeClass(button, 'white');
368 util.addClass(button, 'gray');
369 barChart.updateJSON(json2);
372 //dynamically add legend to list
373 var list = $jit.id('legend'+chartId);
374 var legend = lineChart.getLegend(),
375 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
376 rows = Math.ceil(legend["name"].length/cols),
377 table = "<table cellpadding='0' cellspacing='0' align='left'>";
379 for(i=0;i<rows;i++) {
381 for(td=0;td<cols;td++) {
383 table += '<td width=\'16\' valign=\'top\'>';
384 if(legend["name"][j] != undefined) {
385 table += '<div class=\'query-color\' style=\'background-color:'
386 + legend["color"][j] +'\'> </div>';
390 table += '<td class=\'label\' valign=\'top\'>';
391 if(legend["name"][j] != undefined) {
392 table += legend["name"][j];
402 list.innerHTML = table;
405 //save canvas to image for pdf consumption
406 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
408 var firstLoad = (SUGAR.isIE) ? true: false,
409 orgWindowWidth = document.body.offsetWidth,
410 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
412 var refreshGraph = function() {
413 var newWindowWidth = document.body.offsetWidth;
414 var diff = Math.abs(newWindowWidth - orgWindowWidth);
415 if(diff>20 && !firstLoad){
416 lineChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
421 //refresh graph on window resize
423 var doRefresh = function() {
424 setTimeout(function() {refreshGraph()}, delay);
427 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
434 success:handleSuccess,
435 failure:handleFailure,
436 argument: { foo:'foo', bar:''}
439 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
445 var handleFailure = function(o){
447 if(o.responseText !== undefined){
451 var handleSuccess = function(o){
453 if(o.responseText !== undefined){
454 var json = eval('('+o.responseText+')');
455 var properties = $jit.util.splat(json.properties)[0];
458 var pieChart = new $jit.PieChart({
459 //id of the visualization container
461 //whether to add animations
463 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
464 backgroundColor: 'rgb(255,255,255)',
465 colorStop1: 'rgba(255,255,255,.8)',
466 colorStop2: 'rgba(255,255,255,0)',
467 labelType: properties['labels'],
474 type: useGradients? chartConfig["pieType"]+':gradient' : chartConfig["pieType"],
475 //whether to show the labels for the slices
478 text: properties['title'],
484 text: properties['subtitle'],
497 onClick: function(node) {
498 if(!node || SUGAR.util.isTouchScreen()) return;
499 if(node.link == 'undefined' || node.link == '') return;
500 window.location.href=node.link;
505 type: labelType, //Native or HTML
507 family: css["font-family"],
513 onShow: function(tip, elem) {
514 if(elem.link != 'undefined' && elem.link != '') {
515 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
520 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
521 value = "elem.valuelabel";
523 value = "elem.value";
525 eval("tip.innerHTML = '<b>' + elem.label + '</b>: ' + "+ value +" + ' - ' + elem.percentage + '%' + drillDown");
530 pieChart.loadJSON(json);
532 //dynamically add legend to list
533 var list = $jit.id('legend'+chartId);
534 var legend = pieChart.getLegend(),
535 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
536 rows = Math.ceil(legend["name"].length/cols);
537 table = "<table cellpadding='0' cellspacing='0' align='left'>";
539 for(i=0;i<rows;i++) {
541 for(td=0;td<cols;td++) {
543 table += '<td width=\'16\' valign=\'top\'>';
544 if(legend["name"][j] != undefined) {
545 table += '<div class=\'query-color\' style=\'background-color:'
546 + legend["color"][j] +'\'> </div>';
550 table += '<td class=\'label\' valign=\'top\'>';
551 if(legend["name"][j] != undefined) {
552 table += legend["name"][j];
562 list.innerHTML = table;
565 //save canvas to image for pdf consumption
566 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
568 var firstLoad = (SUGAR.isIE) ? true: false,
569 orgWindowWidth = document.body.offsetWidth,
570 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
572 var refreshGraph = function() {
573 var newWindowWidth = document.body.offsetWidth;
574 var diff = Math.abs(newWindowWidth - orgWindowWidth);
575 if(diff>20 && !firstLoad){
576 pieChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
581 //refresh graph on window resize
583 var doRefresh = function() {
584 setTimeout(function() {refreshGraph()}, delay);
587 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
595 success:handleSuccess,
596 failure:handleFailure,
597 argument: { foo:'foo', bar:''}
600 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
607 var handleFailure = function(o){
609 if(o.responseText !== undefined){
613 var handleSuccess = function(o){
615 if(o.responseText !== undefined && o.responseText != "No Data"){
616 var json = eval('('+o.responseText+')');
618 var properties = $jit.util.splat(json.properties)[0];
621 var funnelChart = new $jit.FunnelChart({
622 //id of the visualization container
624 //whether to add animations
626 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
627 backgroundColor: 'rgb(255,255,255)',
628 colorStop1: 'rgba(255,255,255,.8)',
629 colorStop2: 'rgba(255,255,255,0)',
630 //orientation setting should not be changed
631 orientation: "vertical",
634 text: properties['title'],
640 text: properties['subtitle'],
647 //visualization offset
656 onClick: function(node) {
657 if(!node || SUGAR.util.isTouchScreen()) return;
658 if(node.link == 'undefined' || node.link == '') return;
659 window.location.href=node.link;
662 //labels offset position
665 type: useGradients? chartConfig["funnelType"]+':gradient' : chartConfig["funnelType"],
666 //whether to show the aggregation of the values
668 //whether to show the labels for the bars
672 type: labelType, //Native or HTML
674 family: css["font-family"],
681 onShow: function(tip, elem) {
682 if(elem.link != 'undefined' && elem.link != '') {
683 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
688 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
689 value = "elem.valuelabel";
691 value = "elem.value";
693 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
698 funnelChart.loadJSON(json);
702 var list = $jit.id('id-list'),
703 button = $jit.id('update'),
704 orn = $jit.id('switch-orientation');
705 //update json on click 'Update Data'
706 $jit.util.addEvent(button, 'click', function() {
707 var util = $jit.util;
708 if(util.hasClass(button, 'gray')) return;
709 util.removeClass(button, 'white');
710 util.addClass(button, 'gray');
711 barChart.updateJSON(json2);
714 //dynamically add legend to list
715 var list = $jit.id('legend'+chartId);
716 var legend = funnelChart.getLegend(),
717 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
718 rows = Math.ceil(legend["name"].length/cols);
719 table = "<table cellpadding='0' cellspacing='0' align='left'>";
721 for(i=0;i<rows;i++) {
723 for(td=0;td<cols;td++) {
725 table += '<td width=\'16\' valign=\'top\'>';
726 if(legend["name"][j] != undefined) {
727 table += '<div class=\'query-color\' style=\'background-color:'
728 + legend["color"][j] +'\'> </div>';
732 table += '<td class=\'label\' valign=\'top\'>';
733 if(legend["name"][j] != undefined) {
734 table += legend["name"][j];
744 list.innerHTML = table;
746 //save canvas to image for pdf consumption
747 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
749 var firstLoad = (SUGAR.isIE) ? true: false,
750 orgWindowWidth = document.body.offsetWidth,
751 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
753 var refreshGraph = function() {
754 var newWindowWidth = document.body.offsetWidth;
755 var diff = Math.abs(newWindowWidth - orgWindowWidth);
756 if(diff>20 && !firstLoad){
757 funnelChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
762 //refresh graph on window resize
764 var doRefresh = function() {
765 setTimeout(function() {refreshGraph()}, delay);
768 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
776 success:handleSuccess,
777 failure:handleFailure,
778 argument: { foo:'foo', bar:''}
781 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
788 var handleFailure = function(o){
790 if(o.responseText !== undefined){
794 var handleSuccess = function(o){
796 if(o.responseText !== undefined){
797 var json = eval('('+o.responseText+')');
798 var properties = $jit.util.splat(json.properties)[0];
801 var gaugeChart = new $jit.GaugeChart({
802 //id of the visualization container
804 //whether to add animations
806 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
807 backgroundColor: 'rgb(255,255,255)',
808 colorStop1: 'rgba(255,255,255,.8)',
809 colorStop2: 'rgba(255,255,255,0)',
810 labelType: properties['labels'],
813 text: properties['title'],
819 text: properties['subtitle'],
827 backgroundColor: '#aaaaaa',
828 borderColor: '#999999',
829 needleColor: 'rgba(255,0,0,.8)',
831 positionFontSize: 24,
835 type: useGradients? chartConfig["gaugeType"]+':gradient' : chartConfig["gaugeType"],
836 //whether to show the labels for the slices
840 onClick: function(node) {
841 if(!node || SUGAR.util.isTouchScreen()) return;
842 if(node.link == 'undefined' || node.link == '') return;
843 window.location.href=node.link;
848 type: labelType, //Native or HTML
850 family: css["font-family"],
856 onShow: function(tip, elem) {
857 if(elem.link != 'undefined' && elem.link != '') {
858 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
862 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
863 value = "elem.valuelabel";
865 value = "elem.value";
867 eval("tip.innerHTML = '<b>' + elem.label + '</b>: ' + "+ value +" + drillDown");
872 gaugeChart.loadJSON(json);
875 var list = $jit.id('legend'+chartId);
876 var legend = gaugeChart.getLegend(),
877 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
878 rows = Math.ceil(legend["name"].length/cols);
879 table = "<table cellpadding='0' cellspacing='0' align='left'>";
881 for(i=0;i<rows;i++) {
883 for(td=0;td<cols;td++) {
885 table += '<td width=\'16\' valign=\'top\'>';
886 if(legend["name"][j] != undefined) {
887 table += '<div class=\'query-color\' style=\'background-color:'
888 + legend["color"][j] +'\'> </div>';
892 table += '<td class=\'label\' valign=\'top\'>';
893 if(legend["name"][j] != undefined) {
894 table += legend["name"][j];
904 list.innerHTML = table;
907 //save canvas to image for pdf consumption
908 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
910 var firstLoad = (SUGAR.isIE) ? true: false,
911 orgWindowWidth = document.body.offsetWidth,
912 orgContainerDivWidth = document.getElementById(chartId).offsetWidth;
914 var refreshGraph = function() {
915 var newWindowWidth = document.body.offsetWidth;
916 var diff = Math.abs(newWindowWidth - orgWindowWidth);
917 if(diff>20 && !firstLoad){
918 gaugeChart.resizeGraph(json,orgWindowWidth,orgContainerDivWidth,pageCols);
923 //refresh graph on window resize
925 var doRefresh = function() {
926 setTimeout(function() {refreshGraph()}, delay);
929 YAHOO.util.Event.addListener(window, 'resize', function() {doRefresh()});
937 success:handleSuccess,
938 failure:handleFailure,
939 argument: { foo:'foo', bar:''}
942 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);