/
home
/
assocoweys
/
test
/
wp-content
/
plugins
/
visualizer
/
js
/
Upload File
HOME
/* global console */ /* global visualizer */ /* global Chart */ /* global numeral */ /* global moment */ (function($) { var all_charts; // so that we know which charts belong to our library. var rendered_charts = []; function renderChart(id, v) { renderSpecificChart(id, all_charts[id], v); } function renderSpecificChart(id, chart, v) { var render, container, series, data, datasets, settings, i, j, row, date, axis, property, format, formatter, type, rows, cols, labels; if(chart.library !== 'chartjs'){ return; } rendered_charts[id] = 'yes'; series = chart.series; data = chart.data; settings = chart.settings; container = document.getElementById(id); if (container == null) { return; } // eliminate the jitter/flicker while editing charts. if(v.is_front == false){ // jshint ignore:line $('#' + id).empty(); } if($('#' + id + ' canvas').length === 0){ $('#' + id).append($('<canvas width="100%" height="90%"></canvas>')); } var context = $('#' + id + ' canvas')[0].getContext('2d'); type = chart.type; switch (chart.type) { case 'column': type = 'bar'; break; case 'bar': type = 'bar'; settings.indexAxis = 'y'; break; case 'pie': // donut is not a setting but a separate chart type. if(typeof settings['custom'] !== 'undefined' && settings['custom']['donut'] === 'true'){ type = 'doughnut'; } break; } rows = []; datasets = []; labels = []; for (i = 0; i < data.length; i++) { row = []; for (j = 0; j < series.length; j++) { if (series[j].type === 'date' || series[j].type === 'datetime') { date = new Date(data[i][j]); data[i][j] = null; if (Object.prototype.toString.call(date) === "[object Date]") { if (!isNaN(date.getTime())) { data[i][j] = date; } } } row.push(format_data(data[i][j], j, settings, series)); } rows.push(row); } // transpose for (j = 0; j < series.length; j++) { row = []; for (i = 0; i < rows.length; i++) { if(j === 0){ labels.push(rows[i][j]); }else{ row.push(rows[i][j]); } } if(row.length > 0){ var $attributes = {label: series[j].label, data: row}; switch(chart.type){ case 'pie': case 'polarArea': $.extend($attributes, {label: labels}); handlePieSeriesSettings($attributes, rows, settings, chart); break; default: handleSeriesSettings($attributes, j - 1, settings, chart); } datasets.push($attributes); } } if(v.is_front == false){ // jshint ignore:line // this line needs to be included twice. This is not an error. // if this one is removed, the preview gets messed up. // if this line is included all the time, in this very place (out of the if), the front-end gets messed up. $.extend(settings, { responsive: true, maintainAspectRatio: false }); } handleSettings(settings, chart); const getChart = Chart.getChart(context); if ( getChart ) { return; } // Format series label. settings.plugins.tooltip = { callbacks: { label: function(context) { var label = ''; if ( 'object' === typeof context.dataset.label ) { label = context.label || ''; } else { label = context.dataset.label || ''; } if ( label ) { label += ': '; } var format = context.dataset.format || ''; if ( format ) { var lastSuffix = numeral(context.formattedValue).format(format).replace(/[0-9]/g, ''); label += context.formattedValue + lastSuffix; } else { format = 'undefined' !== typeof context.chart.config._config.options.format ? context.chart.config._config.options.format : ''; if ( format ) { label += format_datum( context.formattedValue, format ); } else { label += context.formattedValue; } } return label; } } }; var chartjs = new Chart(context, { type: type, data: { labels: labels, datasets: datasets }, options: settings, plugins: [{ afterRender: function () { var canvas = $( 'canvas' )[0]; if ( $( '#chart-img' ).length ) { $( '#chart-img' ).val( canvas.toDataURL() ); } } }], }); // this line needs to be included twice. This is not an error. $.extend(settings, { responsive: true, maintainAspectRatio: false }); // chart area if(v.is_front == true){ // jshint ignore:line $('#' + id).css('position', 'relative'); var height = settings.height.indexOf('%') === -1 ? ( settings.height + 'px' ) : settings.height; var width = settings.width.indexOf('%') === -1 ? ( settings.width + 'px' ) : settings.width; if(settings.height){ chartjs.canvas.parentNode.style.height = height; $('#' + id + ' canvas').css('height', height); } if(settings.width){ chartjs.canvas.parentNode.style.width = width; $('#' + id + ' canvas').css('width', width); } } // allow user to extend the settings. $('body').trigger('visualizer:chart:settings:extend', {id: id, chart: chart, settings: settings}); $('.loader').remove(); } function handleSettings(settings, chart){ if(typeof settings === 'undefined'){ return; } // handle some defaults/idiosyncrasies. if(typeof settings['animation'] !== 'undefined' && parseInt(settings['animation']['duration']) === 0){ settings['animation']['duration'] = 1000; } if(typeof settings['tooltip'] !== 'undefined' && typeof settings['tooltip']['intersect'] !== 'undefined'){ // jshint ignore:line settings['tooltip']['intersect'] = settings['tooltip']['intersect'] == true || parseInt(settings['tooltip']['intersect']) === 1; // jshint ignore:line } if(typeof settings['fontName'] !== 'undefined' && settings['fontName'] !== ''){ Chart.defaults.font.family = settings['fontName']; delete settings['fontName']; } if(typeof settings['fontSize'] !== 'undefined' && settings['fontSize'] !== ''){ Chart.defaults.font.size = parseInt(settings['fontSize']); delete settings['fontSize']; } // handle legend defaults. if(typeof settings['legend'] !== 'undefined' && typeof settings['legend']['labels'] !== 'undefined') { for(var i in settings['legend']['labels']){ if(settings['legend']['labels'][i] !== 'undefined' && settings['legend']['labels'][i] === ''){ delete settings['legend']['labels'][i]; } } } settings.plugins = { legend: settings.legend, }; if(typeof settings['title'] !== 'undefined' && settings['title']['text'] !== ''){ settings.plugins['title'] = {}; settings.plugins['title']['display'] = true; settings.plugins['title']['text'] = settings['title']['text']; } handleAxes(settings, chart); override(settings, chart); } function handleAxes(settings, chart){ if(typeof settings['yAxes'] !== 'undefined' && typeof settings['xAxes'] !== 'undefined'){ // stacking has to be defined on both axes. if(typeof settings['yAxes']['stacked_bool'] !== 'undefined'){ settings['yAxes']['stacked_bool'] = 'true'; } if(typeof settings['xAxes']['stacked_bool'] !== 'undefined'){ settings['xAxes']['stacked_bool'] = 'true'; } // Bar percentage. if (typeof settings['yAxes']['barPercentage_int'] !=='undefined' && ''!== settings['yAxes']['barPercentage_int']){ settings['barPercentage'] = settings['yAxes']['barPercentage_int']; } if (typeof settings['xAxes']['barPercentage_int'] !=='undefined' && ''!== settings['xAxes']['barPercentage_int']){ settings['barPercentage'] = settings['xAxes']['barPercentage_int']; } // Bar thickness. if (typeof settings['yAxes']['barThickness'] !=='undefined' && ''!== settings['yAxes']['barThickness']){ settings['barThickness'] = settings['yAxes']['barThickness']; } if (typeof settings['xAxes']['barThickness'] !=='undefined' && ''!== settings['xAxes']['barThickness']){ settings['barThickness'] = settings['xAxes']['barThickness']; } } configureAxes(settings, 'yAxes', chart); configureAxes(settings, 'xAxes', chart); } function configureAxes(settings, axis, chart) { if(typeof settings[axis] !== 'undefined'){ var $features = {}; for(var i in settings[axis]){ var $o = {}; if(Array.isArray(settings[axis][i]) || typeof settings[axis][i] === 'object'){ for(var j in settings[axis][i]){ var $val = ''; if(j === 'labelString'){ $o['display'] = true; $val = settings[axis][i][j]; }else if(i === 'ticks'){ // number values under ticks need to be converted to numbers or the library throws a JS error. $val = parseFloat(settings[axis][i][j]); if(isNaN($val)){ $val = ''; } } else { $val = settings[axis][i][j]; } if($val !== ''){ $o[j] = $val; } } }else{ // usually for attributes that have primitive values. var array = i.split('_'); var dataType = 'string'; var dataValue = settings[axis][i]; if(array.length === 2){ dataType = array[1]; } if(settings[axis][i] === ''){ continue; } switch(dataType){ case 'bool': dataValue = dataValue === 'true' ? true : false; break; case 'int': dataValue = parseFloat(dataValue); break; } $o = dataValue; // remove the type suffix to get the name of the setting. i = i.replace(/_bool/g, '').replace(/_int/g, ''); } $features[i] = $o; } var $scales = {}; $scales['scales'] = {}; $scales['scales'][axis] = []; if(typeof settings['scales'] !== 'undefined' && typeof settings[axis + 'set'] === 'undefined'){ $scales['scales'] = settings['scales']; if(typeof settings['scales'][axis] !== 'undefined'){ $scales['scales'][axis] = settings['scales'][axis]; } } if(typeof $scales['scales'][axis] === 'undefined'){ $scales['scales'][axis] = []; } var $axis = $scales['scales'][axis]; $axis.push($features); // Migrate xAxes settings to v3.0+ if ( $scales.scales && $scales.scales.xAxes ) { for (var x in $scales.scales.xAxes) { $scales.scales.x = { display: $scales.scales.xAxes[x].scaleLabel.display, title: { display:true, text: $scales.scales.xAxes[x].scaleLabel.labelString, color: $scales.scales.xAxes[x].scaleLabel.fontColor, font: { family: $scales.scales.xAxes[x].scaleLabel.fontFamily, size: $scales.scales.xAxes[x].scaleLabel.fontSize } }, suggestedMax: $scales.scales.xAxes[x].ticks.suggestedMax || '', suggestedMin: $scales.scales.xAxes[x].ticks.suggestedMin || '', ticks: { maxTicksLimit: $scales.scales.xAxes[x].ticks.maxTicksLimit }, stacked: $scales.scales.xAxes[x].stacked || false } } delete $scales.scales.xAxes; } // Migrate yAxes settings to v3.0+ if ( $scales.scales && $scales.scales.yAxes ) { for (var y in $scales.scales.yAxes) { $scales.scales.y = { display: $scales.scales.yAxes[y].scaleLabel.display, title: { display:true, text: $scales.scales.yAxes[y].scaleLabel.labelString, color: $scales.scales.yAxes[y].scaleLabel.fontColor, font: { family: $scales.scales.yAxes[y].scaleLabel.fontFamily, size: $scales.scales.yAxes[y].scaleLabel.fontSize } }, suggestedMax: $scales.scales.yAxes[y].ticks.suggestedMax || '', suggestedMin: $scales.scales.yAxes[y].ticks.suggestedMin || '', ticks: { maxTicksLimit: $scales.scales.yAxes[y].ticks.maxTicksLimit }, stacked: $scales.scales.yAxes[y].stacked || false } } delete $scales.scales.yAxes; } $.extend(settings, $scales); // to prevent duplication, indicates that the axis has been set. var $custom = {}; $custom[axis + 'set'] = 'yes'; $.extend(settings, $custom); } // format the axes labels. if(typeof settings[axis + '_format'] !== 'undefined' && settings[axis + '_format'] !== ''){ var format = settings[axis + '_format']; var isDateFormat = moment( moment().format( format ),format, true ).isValid(); if ( ! isDateFormat ) { switch(axis){ case 'xAxes': settings.scales.x.ticks.callback = function(value, index, values){ return format_datum(value, format); }; break; case 'yAxes': settings.scales.y.ticks.callback = function(value, index, values){ return format_datum(value, format); }; break; } delete settings[axis + '_format']; } } delete settings[axis]; } function handlePieSeriesSettings($attributes, rows, settings, chart){ if(typeof settings.slices === 'undefined'){ return; } var atts = []; // collect all the types of attributes for(var j in settings.slices[0]){ // weight screws up the rendering for some reason, so we will ignore it. if(j === 'weight') { continue; } atts.push(j); } for (j = 0; j < atts.length; j++) { var values = []; for (var i = 0; i < rows.length; i++) { if(typeof settings.slices[i] !== 'undefined' && typeof settings.slices[i][atts[j]] !== 'undefined'){ values.push(settings.slices[i][atts[j]]); } } var object = {}; object[ atts[ j ] ] = values; $.extend($attributes, object); } } function handleSeriesSettings($attributes, j, settings, chart){ if(typeof settings.series === 'undefined' || typeof settings.series[j] === 'undefined'){ return; } for(var i in settings.series[j]){ var $attribute = {}; if ( settings.series[j].backgroundColor == '' ) { delete settings.series[j].backgroundColor; } $attribute[i] = settings.series[j][i]; $.extend($attributes, $attribute); } } function format_datum(datum, format, type){ if(format === '' || format === null || typeof format === 'undefined'){ return datum; } // if there is no type, this is probably coming from the axes formatting. var removeDollar = true; if(typeof type === 'undefined' || type === null){ // we will determine type on the basis of the presence or absence of #. type = 'date'; if(format.indexOf('#') !== -1){ type = 'number'; } removeDollar = false; } switch(type) { case 'number': // numeral.js works on 0 instead of # so we just replace that in the ICU pattern set. format = format.replace(/#/g, '0').replace(/%/g, ''); // we also replace all instance of '$' as that is more relevant for ticks. if(removeDollar){ format = format.replace(/\$/g, ''); } datum = numeral(datum).format(format); break; case 'date': case 'datetime': case 'timeofday': datum = moment(datum).format(format); break; } return datum; } function format_data(datum, j, settings, series){ j = j - 1; var format = typeof settings.series !== 'undefined' && typeof settings.series[j] !== 'undefined' ? settings.series[j].format : ''; if ( '' === format && typeof settings.yAxes_format !== 'undefined' ) { format = settings.yAxes_format; } else if ( '' === format && typeof settings.xAxes_format !== 'undefined' ) { format = settings.xAxes_format; } return format_datum(datum, format, series[j + 1].type); } function override(settings, chart) { if (settings.manual) { try{ var options = JSON.parse(settings.manual); $.extend(settings, options); delete settings.manual; }catch(error){ console.error("Error while adding manual configuration override " + settings.manual); } } } function render(v) { for (var id in (all_charts || {})) { renderChart(id, v); } } $('body').on('visualizer:render:chart:start', function(event, v){ all_charts = v.charts; if(v.is_front == true && typeof v.id !== 'undefined'){ // jshint ignore:line renderChart(v.id, v); } else { render(v); } // for some reason this needs to be introduced here for dynamic preview updates to work. v.update = function(){ renderChart('canvas', v); }; }); $('body').on('visualizer:render:specificchart:start', function(event, v){ renderSpecificChart(v.id, v.chart, v.v); }); $('body').on('visualizer:render:currentchart:update', function(event, v){ var data = v || event.detail; renderChart('canvas', data.visualizer); }); // front end actions // 'image' is also called from the library $('body').on('visualizer:action:specificchart', function(event, v){ var id = v.id; if(typeof rendered_charts[id] === 'undefined'){ return; } var canvas = $('#' + id + ' canvas'); switch(v.action){ case 'print': var win = window.open(); win.document.write("<br><img src='" + canvas[0].toDataURL() + "'/>"); win.document.close(); win.onload = function () { win.print(); setTimeout(win.close, 500); }; break; case 'image': var img = canvas[0].toDataURL(); if(img !== ''){ var $a = $("<a>"); // jshint ignore:line $a.attr("href", img); $("body").append($a); $a.attr("download", v.dataObj.name); $a[0].click(); $a.remove(); }else{ console.warn("No image generated"); } break; } }); })(jQuery);