1 /*********************************************************************************
2 * SugarCRM Community Edition is a customer relationship management program developed by
3 * SugarCRM, Inc. Copyright (C) 2004-2012 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) {
42 if(document.getElementById(chartId) == null) {
46 var labelType, useGradients, nativeTextSupport, animate;
48 var ua = navigator.userAgent,
49 typeOfCanvas = typeof HTMLCanvasElement,
50 nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
51 textSupport = nativeCanvasSupport
52 && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
54 nativeTextSupport = labelType == 'Native';
55 useGradients = nativeCanvasSupport;
60 switch(chartConfig["chartType"]) {
62 var handleFailure = function(o){
64 if(o.responseText !== undefined){
68 var handleSuccess = function(o){
70 if(o.responseText !== undefined && o.responseText != "No Data"){
71 var json = eval('('+o.responseText+')');
73 var properties = $jit.util.splat(json.properties)[0];
74 var marginBottom = (chartConfig["orientation"] == 'vertical' && json.values.length > 8) ? 20*4 : 20;
76 var barChart = new $jit.BarChart({
77 //id of the visualization container
79 //whether to add animations
81 nodeCount: json.values.length,
82 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
83 backgroundColor: 'rgb(255,255,255)',
84 colorStop1: 'rgba(255,255,255,.8)',
85 colorStop2: 'rgba(255,255,255,0)',
90 //horizontal or vertical barcharts
91 orientation: chartConfig["orientation"],
94 text: properties['title'],
100 text: properties['subtitle'],
107 color: css["gridLineColor"]
110 barsOffset: (chartConfig["orientation"] == "vertical") ? 30 : 20,
111 //visualization offset
119 text: (chartConfig["scroll"] && SUGAR.util.isTouchScreen()) ? "Use two fingers to scroll" : "",
124 onClick: function(node) {
125 if(!node || SUGAR.util.isTouchScreen()) return;
126 if(node.link == 'undefined' || node.link == '') return;
127 window.location.href=node.link;
130 //labels offset position
133 type: useGradients? chartConfig["barType"]+':gradient' : chartConfig["barType"],
134 //whether to show the aggregation of the values
136 //whether to show the labels for the bars
140 type: labelType, //Native or HTML
142 family: css["font-family"],
149 onShow: function(tip, elem) {
150 if(elem.link != 'undefined' && elem.link != '') {
151 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
156 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
157 value = "elem.valuelabel";
159 value = "elem.value";
161 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
166 barChart.loadJSON(json);
172 var list = $jit.id('id-list'),
173 button = $jit.id('update'),
174 orn = $jit.id('switch-orientation');
175 //update json on click 'Update Data'
176 $jit.util.addEvent(button, 'click', function() {
177 var util = $jit.util;
178 if(util.hasClass(button, 'gray')) return;
179 util.removeClass(button, 'white');
180 util.addClass(button, 'gray');
181 barChart.updateJSON(json2);
184 //dynamically add legend to list
185 var list = $jit.id('legend'+chartId);
186 var legend = barChart.getLegend(),
187 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
188 rows = Math.ceil(legend["name"].length/cols),
189 table = "<table cellpadding='0' cellspacing='0' align='left'>";
191 for(i=0;i<rows;i++) {
193 for(td=0;td<cols;td++) {
195 table += '<td width=\'16\' valign=\'top\'>';
196 if(legend["name"][j] != undefined) {
197 table += '<div class=\'query-color\' style=\'background-color:'
198 + legend["color"][j] +'\'> </div>';
202 table += '<td class=\'label\' valign=\'top\'>';
203 if(legend["name"][j] != undefined) {
204 table += legend["name"][j];
214 list.innerHTML = table;
217 //save canvas to image for pdf consumption
218 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
220 trackWindowResize(barChart, chartId, json);
226 success:handleSuccess,
227 failure:handleFailure,
228 argument: { foo:'foo', bar:''}
231 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
235 var handleFailure = function(o){
237 if(o.responseText !== undefined){
241 var handleSuccess = function(o){
243 if(o.responseText !== undefined && o.responseText != "No Data"){
244 var json = eval('('+o.responseText+')');
246 var properties = $jit.util.splat(json.properties)[0];
248 var lineChart = new $jit.LineChart({
249 //id of the visualization container
251 //whether to add animations
253 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
254 backgroundColor: 'rgb(255,255,255)',
255 colorStop1: 'rgba(255,255,255,.8)',
256 colorStop2: 'rgba(255,255,255,0)',
257 selectOnHover: false,
259 text: properties['title'],
265 text: properties['subtitle'],
272 color: css["gridLineColor"]
274 //visualization offset
283 onClick: function(node) {
284 if(!node || SUGAR.util.isTouchScreen()) return;
285 if(node.link == 'undefined' || node.link == '') return;
286 window.location.href=node.link;
289 //labels offset position
292 type: useGradients? chartConfig["lineType"]+':gradient' : chartConfig["lineType"],
293 //whether to show the aggregation of the values
295 //whether to show the labels for the bars
299 type: labelType, //Native or HTML
301 family: css["font-family"],
308 onShow: function(tip, elem) {
309 if(elem.link != 'undefined' && elem.link != '') {
310 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
315 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
316 var value = "elem.valuelabel";
318 var value = "elem.value";
322 eval("var name = elem."+chartConfig["tip"]+";");
323 var content = '<table>';
325 for(var i=0; i<name.length; i++) {
326 content += '<tr><td><b>' + name[i] + '</b>:</td><td> ' + elem.value[i] + ' - ' + elem.percentage[i] + '%' + '</td></tr>';
328 content += '</table>';
329 tip.innerHTML = content;
331 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
337 lineChart.loadJSON(json);
341 var list = $jit.id('id-list'),
342 button = $jit.id('update'),
343 orn = $jit.id('switch-orientation');
344 //update json on click 'Update Data'
345 $jit.util.addEvent(button, 'click', function() {
346 var util = $jit.util;
347 if(util.hasClass(button, 'gray')) return;
348 util.removeClass(button, 'white');
349 util.addClass(button, 'gray');
350 barChart.updateJSON(json2);
353 //dynamically add legend to list
354 var list = $jit.id('legend'+chartId);
355 var legend = lineChart.getLegend(),
356 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
357 rows = Math.ceil(legend["name"].length/cols),
358 table = "<table cellpadding='0' cellspacing='0' align='left'>";
360 for(i=0;i<rows;i++) {
362 for(td=0;td<cols;td++) {
364 table += '<td width=\'16\' valign=\'top\'>';
365 if(legend["name"][j] != undefined) {
366 table += '<div class=\'query-color\' style=\'background-color:'
367 + legend["color"][j] +'\'> </div>';
371 table += '<td class=\'label\' valign=\'top\'>';
372 if(legend["name"][j] != undefined) {
373 table += legend["name"][j];
383 list.innerHTML = table;
386 //save canvas to image for pdf consumption
387 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
389 trackWindowResize(lineChart, chartId, json);
395 success:handleSuccess,
396 failure:handleFailure,
397 argument: { foo:'foo', bar:''}
400 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
406 var handleFailure = function(o){
408 if(o.responseText !== undefined){
412 var handleSuccess = function(o){
414 if(o.responseText !== undefined){
415 var json = eval('('+o.responseText+')');
416 var properties = $jit.util.splat(json.properties)[0];
419 var pieChart = new $jit.PieChart({
420 //id of the visualization container
422 //whether to add animations
424 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
425 backgroundColor: 'rgb(255,255,255)',
426 colorStop1: 'rgba(255,255,255,.8)',
427 colorStop2: 'rgba(255,255,255,0)',
428 labelType: properties['labels'],
435 type: useGradients? chartConfig["pieType"]+':gradient' : chartConfig["pieType"],
436 //whether to show the labels for the slices
439 text: properties['title'],
445 text: properties['subtitle'],
458 onClick: function(node) {
459 if(!node || SUGAR.util.isTouchScreen()) return;
460 if(node.link == 'undefined' || node.link == '') return;
461 window.location.href=node.link;
466 type: labelType, //Native or HTML
468 family: css["font-family"],
474 onShow: function(tip, elem) {
475 if(elem.link != 'undefined' && elem.link != '') {
476 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
481 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
482 value = "elem.valuelabel";
484 value = "elem.value";
486 eval("tip.innerHTML = '<b>' + elem.label + '</b>: ' + "+ value +" + ' - ' + elem.percentage + '%' + drillDown");
491 pieChart.loadJSON(json);
493 //dynamically add legend to list
494 var list = $jit.id('legend'+chartId);
495 var legend = pieChart.getLegend(),
496 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
497 rows = Math.ceil(legend["name"].length/cols);
498 table = "<table cellpadding='0' cellspacing='0' align='left'>";
500 for(i=0;i<rows;i++) {
502 for(td=0;td<cols;td++) {
504 table += '<td width=\'16\' valign=\'top\'>';
505 if(legend["name"][j] != undefined) {
506 table += '<div class=\'query-color\' style=\'background-color:'
507 + legend["color"][j] +'\'> </div>';
511 table += '<td class=\'label\' valign=\'top\'>';
512 if(legend["name"][j] != undefined) {
513 table += legend["name"][j];
523 list.innerHTML = table;
526 //save canvas to image for pdf consumption
527 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
529 trackWindowResize(pieChart, chartId, json);
535 success:handleSuccess,
536 failure:handleFailure,
537 argument: { foo:'foo', bar:''}
540 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
547 var handleFailure = function(o){
549 if(o.responseText !== undefined){
553 var handleSuccess = function(o){
555 if(o.responseText !== undefined && o.responseText != "No Data"){
556 var json = eval('('+o.responseText+')');
558 var properties = $jit.util.splat(json.properties)[0];
561 var funnelChart = new $jit.FunnelChart({
562 //id of the visualization container
564 //whether to add animations
566 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
567 backgroundColor: 'rgb(255,255,255)',
568 colorStop1: 'rgba(255,255,255,.8)',
569 colorStop2: 'rgba(255,255,255,0)',
570 //orientation setting should not be changed
571 orientation: "vertical",
574 text: properties['title'],
580 text: properties['subtitle'],
587 //visualization offset
596 onClick: function(node) {
597 if(!node || SUGAR.util.isTouchScreen()) return;
598 if(node.link == 'undefined' || node.link == '') return;
599 window.location.href=node.link;
602 //labels offset position
605 type: useGradients? chartConfig["funnelType"]+':gradient' : chartConfig["funnelType"],
606 //whether to show the aggregation of the values
608 //whether to show the labels for the bars
612 type: labelType, //Native or HTML
614 family: css["font-family"],
621 onShow: function(tip, elem) {
622 if(elem.link != 'undefined' && elem.link != '') {
623 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
628 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
629 value = "elem.valuelabel";
631 value = "elem.value";
633 eval("tip.innerHTML = '<b>' + elem."+chartConfig["tip"]+" + '</b>: ' + "+value+" + ' - ' + elem.percentage + '%' + drillDown");
638 funnelChart.loadJSON(json);
642 var list = $jit.id('id-list'),
643 button = $jit.id('update'),
644 orn = $jit.id('switch-orientation');
645 //update json on click 'Update Data'
646 $jit.util.addEvent(button, 'click', function() {
647 var util = $jit.util;
648 if(util.hasClass(button, 'gray')) return;
649 util.removeClass(button, 'white');
650 util.addClass(button, 'gray');
651 barChart.updateJSON(json2);
654 //dynamically add legend to list
655 var list = $jit.id('legend'+chartId);
656 var legend = funnelChart.getLegend(),
657 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
658 rows = Math.ceil(legend["name"].length/cols);
659 table = "<table cellpadding='0' cellspacing='0' align='left'>";
661 for(i=0;i<rows;i++) {
663 for(td=0;td<cols;td++) {
665 table += '<td width=\'16\' valign=\'top\'>';
666 if(legend["name"][j] != undefined) {
667 table += '<div class=\'query-color\' style=\'background-color:'
668 + legend["color"][j] +'\'> </div>';
672 table += '<td class=\'label\' valign=\'top\'>';
673 if(legend["name"][j] != undefined) {
674 table += legend["name"][j];
684 list.innerHTML = table;
686 //save canvas to image for pdf consumption
687 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
689 trackWindowResize(funnelChart, chartId, json);
695 success:handleSuccess,
696 failure:handleFailure,
697 argument: { foo:'foo', bar:''}
700 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
707 var handleFailure = function(o){
709 if(o.responseText !== undefined){
713 var handleSuccess = function(o){
715 if(o.responseText !== undefined){
716 var json = eval('('+o.responseText+')');
717 var properties = $jit.util.splat(json.properties)[0];
720 var gaugeChart = new $jit.GaugeChart({
721 //id of the visualization container
723 //whether to add animations
725 renderBackground: chartConfig['imageExportType'] == "jpg" ? true: false,
726 backgroundColor: 'rgb(255,255,255)',
727 colorStop1: 'rgba(255,255,255,.8)',
728 colorStop2: 'rgba(255,255,255,0)',
729 labelType: properties['labels'],
732 text: properties['title'],
738 text: properties['subtitle'],
746 backgroundColor: '#aaaaaa',
747 borderColor: '#999999',
748 needleColor: 'rgba(255,0,0,.8)',
750 positionFontSize: 24,
754 type: useGradients? chartConfig["gaugeType"]+':gradient' : chartConfig["gaugeType"],
755 //whether to show the labels for the slices
759 onClick: function(node) {
760 if(!node || SUGAR.util.isTouchScreen()) return;
761 if(node.link == 'undefined' || node.link == '') return;
762 window.location.href=node.link;
767 type: labelType, //Native or HTML
769 family: css["font-family"],
775 onShow: function(tip, elem) {
776 if(elem.link != 'undefined' && elem.link != '') {
777 drillDown = (SUGAR.util.isTouchScreen()) ? "<br><a href='"+ elem.link +"'>Click to drilldown</a>" : "<br>Click to drilldown";
781 if(elem.valuelabel != 'undefined' && elem.valuelabel != undefined && elem.valuelabel != '') {
782 value = "elem.valuelabel";
784 value = "elem.value";
786 eval("tip.innerHTML = '<b>' + elem.label + '</b>: ' + "+ value +" + drillDown");
791 gaugeChart.loadJSON(json);
794 var list = $jit.id('legend'+chartId);
795 var legend = gaugeChart.getLegend(),
796 cols = (typeof SUGAR == 'undefined' || typeof SUGAR.mySugar == 'undefined') ? 8 : 4,
797 rows = Math.ceil(legend["name"].length/cols);
798 table = "<table cellpadding='0' cellspacing='0' align='left'>";
800 for(i=0;i<rows;i++) {
802 for(td=0;td<cols;td++) {
804 table += '<td width=\'16\' valign=\'top\'>';
805 if(legend["name"][j] != undefined) {
806 table += '<div class=\'query-color\' style=\'background-color:'
807 + legend["color"][j] +'\'> </div>';
811 table += '<td class=\'label\' valign=\'top\'>';
812 if(legend["name"][j] != undefined) {
813 table += legend["name"][j];
823 list.innerHTML = table;
826 //save canvas to image for pdf consumption
827 $jit.util.saveImageTest(chartId,jsonFilename,chartConfig["imageExportType"]);
829 trackWindowResize(gaugeChart, chartId, json);
835 success:handleSuccess,
836 failure:handleFailure,
837 argument: { foo:'foo', bar:''}
840 var request = YAHOO.util.Connect.asyncRequest('GET', jsonFilename + "?r=" + new Date().getTime(), callback);
846 function trackWindowResize(chart, chartId, json)
848 var origWindowWidth = document.documentElement.scrollWidth,
849 container = document.getElementById(chartId),
850 widget = document.getElementById(chartId + "-canvaswidget");
854 // refresh graph on window resize
855 YAHOO.util.Event.addListener(window, "resize", function()
859 clearTimeout(timeout);
862 timeout = setTimeout(function()
864 var newWindowWidth = document.documentElement.scrollWidth;
866 // if window width has changed during resize
867 if (newWindowWidth != origWindowWidth)
869 // hide widget in order to let it's container have
870 // width corresponding to current window size,
872 widget.style.display = "none";
874 // add one more timeout in order to let all widgets
876 setTimeout(function()
878 // measure container width
879 var width = container.offsetWidth;
881 // display widget before resize, otherwise
882 // it will be rendered incorrectly in IE
883 widget.style.display = "";
885 chart.resizeGraph(json, width);
886 origWindowWidth = newWindowWidth;