PageSourceSearch

https://www.lalfas.es/wp-content/plugins/visualizer/js/render-google.js?ver=4.0.9

js lalfas.es collected 2026-10-02 06:46:50 UTC 26,047 bytes, 679 lines download raw bytes

1/* global google */
2/* global visualizer */
3/* global console */
4
5// this will store the images for each chart rendered.
6var __visualizer_chart_images   = [];
7var chartWrapperError = [];
8var isResizeRequest = false;
9
10(function($) {
11	var gv;
12    var all_charts, objects;
13    // so that we know which charts belong to our library.
14    var rendered_charts = [];
15
16	function renderChart(id) {
17        
18        if ( ! all_charts || 0 === Object.keys( all_charts ).length ) {
19            return;
20        }
21
22        var chart = all_charts[id];
23        var hasAnnotation = false;
24
25        if ( ! chart ) {
26            return;
27        }
28
29        if ( chart.library && chart.library !== 'google' && chart.library !== 'GoogleCharts' ) {
30            return;
31        }
32
33        // re-render the chart only if it doesn't have annotations and it is on the front-end
34        // this is to prevent the chart from showing "All series on a given axis must be of the same data type" during resize.
35        // remember, some charts do not support annotations so they should not be included in this.
36        var no_annotation_charts = ['tabular', 'timeline', 'gauge', 'geo', 'bubble', 'candlestick'];
37        if ( undefined !== chart.settings && undefined !== chart.settings.series && undefined === chart.settings.series.length ) {
38            var seriesKeys = Object.keys( chart.settings.series );
39            // Only convert when keys are numeric indices (PHP JSON-encoded array).
40            // String keys (e.g. named series from manual config) must be left as-is.
41            if ( seriesKeys.every( function( k ) { return ! isNaN( k ); } ) ) {
42                var chartSeries = [];
43                var chartSeriesValue = Object.values( chart.settings.series );
44                $.each( seriesKeys, function( index, element ) {
45                    chartSeries[ element ] = chartSeriesValue[ index ];
46                } );
47                chart.settings.series = chartSeries;
48            }
49        }
50        if(id !== 'canvas' && typeof chart.series !== 'undefined' && typeof chart.settings.series !== 'undefined' && ! no_annotation_charts.includes(chart.type) ) {
51            hasAnnotation = chart.series.length - chart.settings.series.length > 1;
52        }
53
54        if(! hasAnnotation){
55            renderSpecificChart(id, all_charts[id]);
56        }
57    }
58
59    function renderSpecificChart(id, chart) {
60        var render, container, series, data, table, settings, i, j, row, date, axis, property, format, formatter;
61
62        if( chart.library !== 'google' ) {
63            return;
64        }
65      
66        // Bail if the chart is already rendered or is being rendered.
67        if ( ! window.isResizeRequest && ( $('#' + id).hasClass('visualizer-chart-loaded') || ( 'canvas' !== id && $('#' + id).children( ':not(.loader, style)' ).length > 0 ) ) ) {
68            return;
69        }
70        rendered_charts[id] = 'yes';
71
72        series = chart.series;
73		data = chart.data;
74		settings = chart.settings;
75
76        container = document.getElementById(id);
77        if (container == null) {
78            return;
79        }
80		table = new gv.DataTable({cols: series});
81
82		render = objects[id] || null;
83		if (!render) {
84            switch (chart.type) {
85                case "tabular":
86                    render = "Table";
87                    break;
88                case "gauge":
89                case "table":
90                case "timeline":
91                    render  = chart.type.charAt(0).toUpperCase() + chart.type.slice(1);
92                    break;
93                default:
94			        render = chart.type.charAt(0).toUpperCase() + chart.type.slice(1) + 'Chart';
95                    break;
96            }
97
98            var controlWrapperElement = document.getElementById( "control_wrapper_" + id ) || null;
99            var withControlMode = ( typeof settings.controls !== 'undefined' && '' !== settings.controls.controlType ) && controlWrapperElement ? true : false;
100
101            if ( $( controlWrapperElement ).hasClass( 'no-filter' ) ) {
102                withControlMode = false;
103            }
104            if ( withControlMode ) {
105                // Chart wrapper.
106                render = new gv.ChartWrapper({
107                  'chartType': render,
108                  'containerId': id,
109                });
110                // Chart dashboard wrapper.
111                var chartWrapperElement   = document.getElementById( "chart_wrapper_" + id ) || null;
112                var chartWrapper          = new gv.Dashboard( chartWrapperElement );
113
114                // Error Handler.
115                gv.events.addListener(chartWrapper, 'error', function ( err ) {
116                    if ( chartWrapperError.length === 0 ) {
117                        chartWrapperError.push( err );
118                        gv.errors.removeError( err.id );
119                        var chartContainer = $( chartWrapperElement ).find( '.visualizer-front' );
120                        if ( chartContainer && chartContainer.is(':visible')) {
121                            if (chartContainer.parents('div').next( '#sidebar' ).length === 0) {
122                                chartContainer.addClass( 'visualizer-chart-loaded' ).addClass( 'visualizer-cw-error' );
123                                $( chartWrapperElement ).addClass( 'visualizer-cw-error' );
124                            }
125                        }
126                    } else {
127                        gv.errors.removeError( err.id );
128                    }
129                } );
130            } else {
131                render = new gv[render](container);
132            }
133		}
134
135        if (settings['animation'] && parseInt(settings['animation']['startup']) === 1)
136        {
137            settings['animation']['startup'] = true;
138            settings['animation']['duration'] = parseInt(settings['animation']['duration']);
139        }
140        if ( settings['controls'] ) {
141            settings['controls']['ui']['allowMultiple'] = 'true' === settings['controls']['allowMultiple'] ? true : false;
142            settings['controls']['ui']['allowTyping'] = 'true' === settings['controls']['allowTyping'] ? true : false;
143            settings['controls']['ui']['showRangeValues'] = 'true' === settings['controls']['showRangeValues'] ? true : false;
144        }
145
146        // mark roles for series that have specified a role
147        // and then remove them from future processing
148        // and also adjust the indices of the series array so that
149        // the ones with a role are ignored
150        // e.g. if there are 6 columns (0-5) out of which 1, 3 and 5 are annotations
151        // the final series will only include 0, 2, 4 (reindexed as 0, 1, 2)
152
153        // this will capture all the series indexes that became annotations.
154        var series_annotations = [];
155        if (settings.series) {
156            var adjusted_series = [];
157            for (i = 0; i < settings.series.length; i++) {
158                if (!series[i + 1] || typeof settings.series[i] === 'undefined') {
159                    continue;
160                }
161                if(typeof settings.series[i].role !== 'undefined'){
162                    table.setColumnProperty(i + 1, 'role', settings.series[i].role);
163                    if(settings.series[i].role === '') {
164                        adjusted_series.push(settings.series[i]);
165                    }else{
166                        series_annotations.push(i);
167                    }
168                }
169            }
170            if(adjusted_series.length > 0){
171                settings.series = adjusted_series;
172            }
173        }
174
175        if ( settings['explorer_enabled'] && settings['explorer_enabled'] 
175== 'true' ) { // jshint ignore:line
176            var $explorer = {};
177            $explorer['keepInBounds'] = true;
178
179            if ( settings['explorer_actions'] ) {
180                $explorer['actions'] = settings['explorer_actions'];
181            }
182            settings['explorer'] = $explorer;
183        }
184
185		switch (chart.type) {
186			case 'pie':
187				if (settings.slices) {
188					for (i in settings.slices) {
189						if (settings.slices[i]['color'] === '') {
190							delete settings.slices[i]['color'];
191						}
192					}
193				}
194				break;
195			case 'line':
196			case 'bar':
197			case 'column':
198			case 'area':
199			case 'scatter':
200			case 'candlestick':
201				if (settings.series) {
202					for (i in settings.series) {
203						if (settings.series[i]['color'] === '') {
204							delete settings.series[i]['color'];
205						}
206					}
207				}
208
209                if (settings.series && settings.legend && settings.legend.position === "left")
210                {
211                    settings.targetAxisIndex = 1;
212                }
213				break;
214			case 'geo':
215				if (settings.region !== undefined && settings.region.replace(/^\s+|\s+$/g, '') === '') {
216					settings['region'] = 'world';
217				}
218				break;
219			case 'table':
220			case 'tabular':
221                if (parseInt(settings['pagination']) !== 1)
222                {
223                    delete settings['pageSize'];
224                }
225				break;
226			case 'gauge':
227				break;
228			case 'bubble':
229                settings.sortBubblesBySize = settings.sortBubblesBySize ? settings.sortBubblesBySize == 1 : false; // jshint ignore:line
230				break;
231			case 'timeline':
232                settings['timeline'] = {};
233                settings['timeline']['groupByRowLabel'] = settings['groupByRowLabel'] ? true : false;
234                settings['timeline']['colorByRowLabel'] = settings['colorByRowLabel'] ? true : false;
235                settings['timeline']['showRowLabels']   = settings['showRowLabels'] ? true : false;
236                if(settings['singleColor'] !== '') {
237                    settings['timeline']['singleColor'] = settings['singleColor'];
238                }
239				break;
240			case 'combo':
241				if (settings.series) {
242					for (i in settings.series) {
243						if (settings.series[i]['type'] === '') {
244							delete settings.series[i]['type'];
245						}
246						if (settings.series[i]['color'] === '') {
247							delete settings.series[i]['color'];
248						}
249					}
250				}
251
252                if (settings.series && settings.legend && settings.legend.position === "left")
253                {
254                    settings.targetAxisIndex = 1;
255                }
256				break;
257			default:
258				return;
259		}
260
261		if (series[0] && (series[0].type === 'date' || series[0].type === 'datetime' || series[0].type === 'timeofday')) {
262			axis = false;
263			switch (chart.type) {
264				case 'line':
265				case 'area':
266				case 'scatter':
267				case 'candlestick':
268				case 'column':
269				case 'combo':
270					axis = settings.hAxis;
271					break;
272				case 'bar':
273					axis = settings.vAxis;
274					break;
275			}
276
277			if (axis) {
278				for (property in axis.viewWindow) {
279					date = new Date(axis.viewWindow[property]);
280					if (Object.prototype.toString.call(date) === "[object Date]") {
281						if (!isNaN(date.getTime())) {
282							axis.viewWindow[property] = date;
283							continue;
284						}
285					}
286
287					delete axis.viewWindow[property];
288				}
289			}
290
291            if(settings.hAxis && settings.hAxis.format == ''){
292                settings.hAxis.format = 'yyyy-MM-dd';
293            }
294		}
295
296        if(settings.hAxis){
297            if(settings.hAxis.textStyle && settings.hAxis.textStyle !== ''){
298                if(typeof(settings.hAxis.textStyle) === "string") {
299                    settings.hAxis.textStyle = {color: settings.hAxis.textStyle};
300                }
301            }
302        }
303
304        if(settings.vAxis){
305            if(settings.vAxis.textStyle && settings.vAxis.textStyle !== ''){
306                if(typeof(settings.vAxis.textStyle) === "string") {
307                    settings.vAxis.textStyle = {color: settings.vAxis.textStyle};
308                }
309            }
310        }
311
312        for (i = 0; i < data.length; i++) {
313			row = [];
314			for (j = 0; j < series.length; j++) {
315                switch(series[j].type) {
316                    case 'string':
317                        if(data[i][j] === ''){
318                            data[i][j] = null;
319                        }
320                        break;
321                    case 'boolean':
322                        if (typeof data[i][j] === 'string'){
323                            data[i][j] = data[i][j] === 'true';
324                        }
325                        break;
326                    case 'date':
327                        // fall-through.
328                    case 'datetime':
329                        if (typeof data[i][j] === 'string') {
330                            var dateParse = Date.parse(data[i][j].replace(/-/g, '/'));
331                            if ( isNaN( dateParse ) ) {
332                                dateParse = Date.parse(data[i][j]);
333                            }
334                            date = new Date( dateParse );
335                        } else if(typeof data[i][j] === 'object') {
336                            date = data[i][j];
337                        }
338                        data[i][j] = null;
339                        if (Object.prototype.toString.call(date) === "[object Date]") {
340                            if (!isNaN(date.getTime())) {
341                                data[i][j] = date;
342                            }
343                        }
344                        break;
345				}
346				row.push(data[i][j]);
347			}
348			table.addRow(row);
349        }
350
351		if (settings.series) {
352            switch(chart.type){
353                case 'table':
354                case 'tabular':
355                    for(i in settings.series){
356                        i = parseInt(i);
357                        if (!series[i + 1]) {
358                            continue;
359                        }
360                        format_data(id, table, series[i + 1].type, settings.series[i].format, i + 1);
361                    }
362                    break;
363                default:
364                    // Single-pass: walk columns, skip annotation/helper roles, apply formats in order.
365                    var k = 0; // index into settings.series (visible series)
366                    for (var c = 1; c < series.length && k < settings.series.length; c++) { // skip label at 0
367                        if (table.getColumnProperty(c, 'role')) continue; // helper/annotation column
368                        var s = settings.series[k++];
369                        if (!s || !s.format) continue;
370                        if (!series[c]) continue;
371                        format_data(id, table, series[c].type, s.format, c);
372                    }
373                    break;
374            }
375		} else if (chart.type === 'pie' && settings.format && settings.format !== '') {
376            format_data(id, table, 'number', settings.format, 1);
377        }
378
379        if(settings.hAxis && series[0]) {
380       	    format_data(id, table, series[0].type, settings.hAxis.format, 0);
381        }
382
383        override(settings);
384
385        gv.events.addListener(render, 'ready', function () {
386            var arr = id.split('-');
387            render = typeof render.getChart !== 'undefined' ? render.getChart() : render;
388            __visualizer_chart_images[ arr[0] + '-' + arr[1] ] = '';
389
390            if (render.container && $(render.container).is(':visible')) {
391                if ($(render.container).parents('div').next( '#sidebar' ).length === 0) {
392                    $(render.container).addClass( 'visualizer-chart-loaded' );
393                }
394            }
395
396            try{
397                if ( typeof render.getImageURI !== 'undefined' ) {
398                    var img = render.getImageURI();
399                    __visualizer_chart_images[ arr[0] + '-' + arr[1] ] = img;
400                    $('body').trigger('visualizer:render:chart', {id: arr[1], image: img});
401                    if ( $( '#chart-img' ).length ) {
402                        $( '#chart-img' ).val( img );
403                    }
404                }
405            }catch(error){
406                var canvas = document.getElementById( 'canvas' );
407                domtoimage.toPng(canvas)
408                .then(function ( img ) {
409                    __visualizer_chart_images[ arr[0] + '-' + arr[1] ] = img;
410                    $('body').trigger('visualizer:render:chart', {id: arr[1], image: img});
411                    if ( $( '#chart-img' ).length ) {
412                        $( '#chart-img' ).val( img );
413                    }
414                })
415                .catch(function (error) {
416                  console.warn('render.getImageURI not defined for ' + arr[0] + '-' + arr[1]);
417                });
418            }
419        });
420
421        if ( withControlMode ) {
422           // alert( chart.is_library_page );
423            // Create a control wrapper, passing some options.
424            var controlWrapper = new gv.ControlWrapper( {
425                containerId: 'control_wrapper_' + id,
426                controlType: settings.controls.controlType,
427                'options': settings.controls,
428            } );
429
430            $('body').trigger('visualizer:chart:settings:extend', {id: id, chart: chart, settings: settings, data: table});
431            render.setOptions(settings);
432            chartWrapper.bind(controlWrapper, render);
433            chartWrapper.draw(table);
434
435            gv.events.addListener(controlWrapper, 'ready', function ( err ) {
436                if ( 'vertical' === settings.controls.ui.orientation ) {
437                    if ( 'canvas' === id ) {
438                        jQuery( '#' + id ).addClass( 'vz-vertical' );
439                    }
440                } else {
441                    jQuery( '#' + id ).removeClass( 'vz-vertical' );
442                }
443            });
444        } else {
445            $('body').trigger('visualizer:chart:settings:extend', {id: id, chart: chart, settings: settings, data: table});
446            render.draw(table, settings);
447        }
448	}
449
450    function format_data(id, table, type, format, index) {
451        if (!format || format === '') {
452            return;
453        }
454
455        var formatter = null;
456        var $formatInput = $('input.control-text[name*="[format]"]').filter(function() {
457            return $(this).val() === format;
458        });
459        try {
460            switch (type) {
461                case 'number':
462                    formatter = new gv.NumberFormat({pattern: format});
463                    break;
464                case 'date':
465                case 'datetime':
466                case 'timeofday':
467                    formatter = new gv.DateFormat({pattern: format});
468                    break;
469            }
470
471            if (formatter) {
472                formatter.format(table, index);
473                $formatInput.nextAll('.visualizer-format-error').remove();
474            }
475        } catch (e) {
476            if ($formatInput.length) {
477                $formatInput.nextAll('.visualizer-format-error').remove();
478                $('<p class="visualizer-format-error" style="color:#cc0000;margin:4px 0 0"></p>').text(visualizer.l10n.invalid_format).insertAfter($formatInput);
479            }
480        }
481
482        var arr = id.split('-');
483        $('body').trigger('visualizer:format:chart', {id: parseInt(arr[1]), data: table, column: index});
484
485    }
486
487    function override(settings) {
488        if (settings.manual) {
489            try{
490                var options = JSON.parse(settings.manual);
491                $.extend(settings, options);
492                delete settings.manual;
493            }catch(error){
494                console.error("Error while adding manual configuration override " + settings.manual);
495            }
496        }
497    }
498
499	function render() {
500		for (var id in (all_charts || {})) {
501            var chartElement = document.getElementById( id );
502            if (chartElement && chartElement.offsetParent) {
503		      renderChart(id);
504            }
505		}
506	}
507
508    var resizeTimeout;
509
510	$(document).ready(function() {
511		$(window).resize(function(e) {
512			clearTimeout(resizeTimeout);
513            window.isResizeRequest = 'undefined' !== typeof e.originalEvent ? true : false;
514			resizeTimeout = setTimeout(render, 100);
515		});
516
517        resizeHiddenContainers(true);
518
519        if ( $( '.visualizer-hidden-container' ).length ) {
520            setInterval( function() {
521                $( '.visualizer-hidden-container' ).find(".visualizer-front:not(.visualizer-chart-loaded)").resize();
522            }, 500 );
523        }
524
525        window.addEventListener( 'orientationchange', function() {
526            $( '.visualizer-chart-loaded' ).removeClass( 'visualizer-chart-loaded' ).resize();
527        }, false);
528    });
529
530    $(window).on('load', function(){
531        $( '.visualizer-front:not(.visualizer-chart-loaded)' ).resize();
532        resizeHiddenContainers(true);
533    });
534
535    function resizeHiddenContainers(everytime){
536        $(".visualizer-front").parents().each(function(){
537            if(!$(this).is(":visible") && !$(this).hasClass("visualizer-hidden-container")){
538                $(this).addClass("visualizer-hidden-container");
539            }
540        });
541
542        var mutateObserver = new MutationObserver(function(records) {
543            records.forEach(function(record) {
544                if(record.attributeName === "style" || record.attributeName === "class"){
545                    var element         = $(record.target);
546                    var displayStyle    = window.getComputedStyle(element[0]).getPropertyValue("display");
547                    if(element.hasClass("visualizer-hidden-container-resized") || displayStyle === "none") { return ; }
548                    element.find(".visualizer-front").resize();
549                    if(!everytime) {
550                    	element.addClass("visualizer-hidden-container-resized");
551                    }
552                }
553            });
554        });
555
556        $('.visualizer-hidden-container').each(function(){
557            mutateObserver.observe($(this)[0], {attributes: true});
558        });
559	}
560
561    $('body').on('visualizer:render:chart:start', function(event, v){
562        var $chart_types = ['corechart', 'geochart', 'gauge', 'table', 'timeline'];
563        if(v.is_front == true){ // jshint ignore:line
564            // check what all chart types to load.
565            $chart_types = [];
566            $.each(v.charts, function(i, c){
567                // Only consider charts rendered by Google Charts.
568                if ( c.library && c.library !== 'google' && c.library !== 'GoogleCharts' ) {
569                    return;
570                }
571                var $type = c.type;
572                switch($type){
573                    case 'bar':
574                    case 'column':
575                    case 'line':
576                    case 'area':
577                    case 'stepped area':
578                    case 'bubble':
579                    case 'pie':
580                    case 'donut':
581                    case 'combo':
582                    case 'candlestick':
583                    case 'histogram':
584                    case 'scatter':
585                    case 'bubble':
586                        $type = 'corechart';
587                        break;
588                    case 'geo':
589                        $type = 'geochart';
590                        break;
591                    case 'tabular':
592                    case 'table':
593                        $type = 'table';
594                        break;
595                    case 'dataTable':
596                    case 'polarArea':
597                    case 'radar':
598                        $type = null;
599                        break;
600                }
601                if($type != null && $type !== ''){
602                    $chart_types.push($type);
603                }
604            });
605        }
606
607        objects = {};
608        if ( 'object' === typeof google ) {
609            $chart_types.push( 'controls' );
610            google.load( 'visualization', '51', {packages: $chart_types, mapsApiKey: v.map_api_key, 'language' : v.language,
611                callback: function () {
612                    gv = google.visualization;
613                    all_charts = v.charts;
614                    if(v.is_front == true && typeof v.id !== 'undefined'){ // jshint ignore:line
615                        if ( document.getElementById( v.id ).offsetParent !== null ) {
616                            renderChart(v.id);
617                        }
618                    } else {
619                        render();
620                    }
621                }
622            });
623        }
624    });
625
626    $('body').on('visualizer:render:specificchart:start', function(event, v){
627        objects = {};
628        gv = google.visualization;
629        renderSpecificChart(v.id, v.chart);
630    });
631
632    $('body').on('visualizer:render:currentchart:update', function(event, v){
633        renderChart('canvas');
634    });
635
636    // front end actions
637    // 'image' is also called from the library
638    $('body').on('visualizer:action:specificchart', function(event, v){
639        var id = v.id;
640        if(typeof rendered_charts[id] === 'undefined'){
641            return;
642        }
643        var arr = id.split('-');
644        var img = __visualizer_chart_images[ arr[0] + '-' + arr[1] ];
645        switch(v.action){
646            case 'print':
647                // for charts that have no rendered image defined, we print the data instead.
648                var html = v.data;
649                if(img !== ''){
650                    html = "<html><body><img src='" + img + "' /></body></html>";
651                }
652                $('body').trigger('visualizer:action:specificchart:defaultprint', {data: html});
653                break;
654            case 'image':
655                if(img !== ''){
656                    var $a = $("<a>"); // jshint ignore:line
657                    $a.attr("href", img);
658                    $("body").append($a);
659                    $a.attr("download", v.dataObj.name);
660                    $a[0].click();
661                    $a.remove();
662                }else{
663                    console.warn("No image generated");
664                }
665                break;
666        }
667    });
668
669    var timer = 0;
670    $( document ).on( 'input', '.series-linewidth', function() {
671        var seriesLineWidth = $( this );
672        clearTimeout( timer );
673        timer = setTimeout( function() {
674            if ( seriesLineWidth.val() != '' && seriesLineWidth.val() <= 0 ) {
675                seriesLineWidth.val( '0.1' );
676            }
677        }, 700 );
678    } );
679})(jQuery);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.