| 1 |
/* global console */ |
| 2 |
/* global visualizer */ |
| 3 |
|
| 4 |
(function($) { |
| 5 |
var all_charts; |
| 6 |
// so that we know which charts belong to our library. |
| 7 |
var rendered_charts = []; |
| 8 |
|
| 9 |
// save the settings corresponding to cssClassNames so that when a table is being edited, they stripes etc. don't get reset |
| 10 |
var cssClassNames; |
| 11 |
|
| 12 |
function renderChart(id, v) { |
| 13 |
var chart = all_charts[id]; |
| 14 |
if(chart.library !== 'datatables'){ |
| 15 |
return; |
| 16 |
} |
| 17 |
cssClassNames = null; |
| 18 |
renderSpecificChart(id, chart, v); |
| 19 |
} |
| 20 |
|
| 21 |
function renderSpecificChart(id, chart, v) { |
| 22 |
var render, container, series, data, table, settings, i, j, row, date, axis, property, format, formatter, type, rows, cols; |
| 23 |
|
| 24 |
if(chart.library !== 'datatables'){ |
| 25 |
return; |
| 26 |
} |
| 27 |
rendered_charts[id] = 'yes'; |
| 28 |
|
| 29 |
series = chart.series; |
| 30 |
data = chart.data; |
| 31 |
|
| 32 |
container = document.getElementById(id); |
| 33 |
if (container == null) { |
| 34 |
return; |
| 35 |
} |
| 36 |
|
| 37 |
if($('#' + id).find('table.visualizer-data-table').length > 0){ |
| 38 |
$('#' + id).empty(); |
| 39 |
} |
| 40 |
|
| 41 |
settings = { |
| 42 |
destroy: true, |
| 43 |
paging: false, |
| 44 |
searching: false, |
| 45 |
ordering: true, |
| 46 |
select: false, |
| 47 |
lengthChange: false, |
| 48 |
buttons: { |
| 49 |
buttons: [{ |
| 50 |
extend: 'print', |
| 51 |
text: '', |
| 52 |
title: '' |
| 53 |
}] |
| 54 |
}, |
| 55 |
dom: 'Bfrtip', |
| 56 |
}; |
| 57 |
|
| 58 |
var $classes = 'dataTable visualizer-data-table table table-striped'; |
| 59 |
|
| 60 |
if(typeof v.page_type !== 'undefined'){ |
| 61 |
switch(v.page_type){ |
| 62 |
case 'post': |
| 63 |
// fall-through. |
| 64 |
case 'library': |
| 65 |
// for smaller screens... |
| 66 |
if(window.innerWidth < 1500){ |
| 67 |
delete chart.settings['scrollX']; |
| 68 |
delete chart.settings['scrollY']; |
| 69 |
delete chart.settings['scrollY_int']; |
| 70 |
$.extend( settings, { |
| 71 |
scrollX: 150, |
| 72 |
scrollY: (( chart.settings['responsive_bool'] === 'true' ? 0.8 : 0.5 ) * parseInt($(container).css('height').replace('px',''))), |
| 73 |
scrollCollapse: true |
| 74 |
} ); |
| 75 |
}else{ |
| 76 |
if(parseInt(chart.settings['scrollY_int']) > 180){ |
| 77 |
chart.settings['scrollY_int']; |
| 78 |
} |
| 79 |
delete chart.settings['scrollX']; |
| 80 |
$.extend( settings, { |
| 81 |
scrollX: 150, |
| 82 |
scrollY: 180, |
| 83 |
} ); |
| 84 |
} |
| 85 |
break; |
| 86 |
case 'chart': |
| 87 |
delete chart.settings['scrollX']; // jshint ignore:line |
| 88 |
// fall-through. |
| 89 |
case 'frontend': |
| 90 |
// empty. |
| 91 |
break; |
| 92 |
} |
| 93 |
} |
| 94 |
|
| 95 |
if(typeof chart.settings['scrollX'] !== 'undefined'){ |
| 96 |
if(chart.settings['scrollX'] == 'true'){ // jshint ignore:line |
| 97 |
$classes = $classes + ' nowrap'; |
| 98 |
} |
| 99 |
} |
| 100 |
|
| 101 |
$('#' + id).append($('<table class="' + $classes + '"></table>')); |
| 102 |
|
| 103 |
var select = { |
| 104 |
info: false |
| 105 |
}; |
| 106 |
// we cannot use { select } below because https://github.com/Codeinwp/visualizer/issues/357 |
| 107 |
$.extend( settings, { info: false } ); // jshint ignore:line |
| 108 |
|
| 109 |
var stripe = ['', '']; |
| 110 |
|
| 111 |
if(cssClassNames !== null){ |
| 112 |
chart.settings['cssClassNames'] = cssClassNames; |
| 113 |
} |
| 114 |
|
| 115 |
// in preview mode, cssClassNames will not exist when a color is changed. |
| 116 |
if(typeof chart.settings['cssClassNames'] !== 'undefined'){ |
| 117 |
cssClassNames = chart.settings['cssClassNames']; |
| 118 |
if(typeof chart.settings['cssClassNames']['oddTableRow'] !== 'undefined'){ |
| 119 |
stripe[0] = chart.settings['cssClassNames']['oddTableRow']; |
| 120 |
} |
| 121 |
|
| 122 |
if(typeof chart.settings['cssClassNames']['evenTableRow'] !== 'undefined'){ |
| 123 |
stripe[1] = chart.settings['cssClassNames']['evenTableRow']; |
| 124 |
} |
| 125 |
|
| 126 |
if(typeof chart.settings['cssClassNames']['selectedTableItem'] !== 'undefined'){ |
| 127 |
$.extend( select, { |
| 128 |
className: chart.settings['cssClassNames']['selectedTableItem'] |
| 129 |
} ); |
| 130 |
} |
| 131 |
} |
| 132 |
|
| 133 |
// remove this so that the eval does not fail. |
| 134 |
delete chart.settings['internal_title']; |
| 135 |
|
| 136 |
var additional = []; |
| 137 |
for (i in chart.settings) { |
| 138 |
var valoo = chart.settings[i]; |
| 139 |
|
| 140 |
// remove the type suffix to get the name of the setting. |
| 141 |
i = i.replace(/_bool/g, '').replace(/_int/g, ''); |
| 142 |
|
| 143 |
switch(valoo){ |
| 144 |
case 'true': |
| 145 |
valoo = true; |
| 146 |
break; |
| 147 |
case 'false': |
| 148 |
valoo = false; |
| 149 |
break; |
| 150 |
default: |
| 151 |
if(parseInt(valoo) > 0){ |
| 152 |
valoo = parseInt(valoo); |
| 153 |
} |
| 154 |
if(i === 'pageLength' && (valoo === '' || parseInt(valoo) < 0)){ |
| 155 |
valoo = 1; |
| 156 |
} |
| 157 |
} |
| 158 |
|
| 159 |
// if the setting name has an '_' this means it is a sub-setting e.g. select_items means { select: { items: ... } }. |
| 160 |
var array = i.split('_'); |
| 161 |
if(array.length === 2){ |
| 162 |
i = eval( array[0] ); // jshint ignore:line |
| 163 |
i[ array[1] ] = valoo; |
| 164 |
additional[ array[0] ] = i; |
| 165 |
if(array[0] === 'select' && array[1] === 'info' ){ |
| 166 |
// enable main info or the selection info will not show. |
| 167 |
$.extend( settings, {info: true} ); |
| 168 |
} |
| 169 |
} else { |
| 170 |
settings[i] = valoo; |
| 171 |
} |
| 172 |
} |
| 173 |
$.extend( settings, additional ); |
| 174 |
|
| 175 |
cols = []; |
| 176 |
for (j = 0; j < series.length; j++) { |
| 177 |
type = series[j].type; |
| 178 |
switch(type){ |
| 179 |
case 'number': |
| 180 |
type = 'num'; |
| 181 |
break; |
| 182 |
case 'date': |
| 183 |
case 'datetime': |
| 184 |
case 'timeofday': |
| 185 |
type = 'date'; |
| 186 |
break; |
| 187 |
} |
| 188 |
render = addRenderer(series[j].type, settings.series, j); |
| 189 |
|
| 190 |
var col = { title: series[j].label, data: series[j].label, type: type, render: render }; |
| 191 |
if(typeof chart.settings['cssClassNames'] !== 'undefined' && typeof chart.settings['cssClassNames']['tableCell'] !== 'undefined'){ |
| 192 |
col['className'] = chart.settings['cssClassNames']['tableCell']; |
| 193 |
} |
| 194 |
cols.push(col); |
| 195 |
} |
| 196 |
|
| 197 |
rows = []; |
| 198 |
for (i = 0; i < data.length; i++) { |
| 199 |
row = []; |
| 200 |
for (j = 0; j < series.length; j++) { |
| 201 |
var datum = data[i][j]; |
| 202 |
// datum could be undefined for dynamic data (e.g. through json). |
| 203 |
if(typeof datum === 'undefined'){ |
| 204 |
datum = data[i][series[j].label]; |
| 205 |
} |
| 206 |
row[ series[j].label ] = datum; |
| 207 |
} |
| 208 |
rows.push(row); |
| 209 |
} |
| 210 |
|
| 211 |
$.extend( settings, { |
| 212 |
data: rows, |
| 213 |
columns: cols, |
| 214 |
stripeClasses: stripe, |
| 215 |
} ); |
| 216 |
|
| 217 |
// allow user to extend the settings. |
| 218 |
$('body').trigger('visualizer:chart:settings:extend', {id: id, chart: chart, settings: settings}); |
| 219 |
|
| 220 |
table = $('#' + id + ' table.visualizer-data-table'); |
| 221 |
table.DataTable( settings ); |
| 222 |
|
| 223 |
// header row is handled here as the class is added dynamically to it (after the table is rendered). |
| 224 |
if(typeof chart.settings['cssClassNames'] !== 'undefined'){ |
| 225 |
if(typeof chart.settings['cssClassNames']['headerRow'] !== 'undefined'){ |
| 226 |
$('#' + id + ' table thead tr').addClass( chart.settings['cssClassNames']['headerRow'] ); |
| 227 |
} |
| 228 |
} |
| 229 |
|
| 230 |
$('.loader').remove(); |
| 231 |
} |
| 232 |
|
| 233 |
function addRenderer(type, series, index){ |
| 234 |
var render = null; |
| 235 |
if(typeof series === 'undefined' || typeof series[index] === 'undefined' || typeof series[index].format === 'undefined' ){ |
| 236 |
return render; |
| 237 |
} |
| 238 |
|
| 239 |
series = series[index]; |
| 240 |
|
| 241 |
/* jshint ignore:start */ |
| 242 |
switch(type){ |
| 243 |
case 'number': |
| 244 |
var parts = ['', '', '', '', '']; |
| 245 |
if(typeof series.format.thousands !== ''){ |
| 246 |
parts[0] = series.format.thousands; |
| 247 |
} |
| 248 |
if(typeof series.format.decimal !== ''){ |
| 249 |
parts[1] = series.format.decimal; |
| 250 |
if ( '' === series.format.precision ) { |
| 251 |
series.format.precision = 2; |
| 252 |
} |
| 253 |
} |
| 254 |
if(typeof series.format.precision !== '' && parseInt(series.format.precision) > 0){ |
| 255 |
parts[2] = series.format.precision; |
| 256 |
} |
| 257 |
if(typeof series.format.prefix !== ''){ |
| 258 |
parts[3] = series.format.prefix; |
| 259 |
} |
| 260 |
if(typeof series.format.suffix !== ''){ |
| 261 |
parts[4] = series.format.suffix; |
| 262 |
} |
| 263 |
render = $.fn.dataTable.render.number(parts[0], parts[1], parts[2], parts[3], parts[4]); |
| 264 |
break; |
| 265 |
case 'date': |
| 266 |
case 'datetime': |
| 267 |
case 'timeofday': |
| 268 |
if(typeof series.format.to !== 'undefined' && typeof series.format.from !== 'undefined' && series.format.from != '' && series.format.to !== ''){ |
| 269 |
render = $.fn.dataTable.render.moment(series.format.from, series.format.to); |
| 270 |
} |
| 271 |
break; |
| 272 |
default: |
| 273 |
render = $.fn.dataTable.render.extra = function ( data, type, row ) { |
| 274 |
if((data === true || data === 'true') && typeof series.format !== 'undefined' && series.format.truthy !== ''){ |
| 275 |
data = series.format.truthy.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); |
| 276 |
} |
| 277 |
if((data === false || data === 'false') && typeof series.format !== 'undefined' && series.format.falsy !== ''){ |
| 278 |
data = series.format.falsy.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, ''); |
| 279 |
} |
| 280 |
return data; |
| 281 |
} |
| 282 |
} |
| 283 |
/* jshint ignore:end */ |
| 284 |
|
| 285 |
return render; |
| 286 |
} |
| 287 |
|
| 288 |
function render(v) { |
| 289 |
for (var id in (all_charts || {})) { |
| 290 |
renderChart(id, v); |
| 291 |
} |
| 292 |
} |
| 293 |
|
| 294 |
$('body').on('visualizer:render:chart:start', function(event, v){ |
| 295 |
all_charts = v.charts; |
| 296 |
|
| 297 |
if(v.is_front == true && typeof v.id !== 'undefined'){ // jshint ignore:line |
| 298 |
renderChart(v.id, v); |
| 299 |
} else { |
| 300 |
render(v); |
| 301 |
} |
| 302 |
}); |
| 303 |
|
| 304 |
$('body').on('visualizer:render:specificchart:start', function(event, v){ |
| 305 |
renderSpecificChart(v.id, v.chart, v.v); |
| 306 |
}); |
| 307 |
|
| 308 |
$('body').on('visualizer:render:currentchart:update', function(event, v){ |
| 309 |
var data = v || event.detail; |
| 310 |
renderSpecificChart('canvas', all_charts['canvas'], data.visualizer); |
| 311 |
}); |
| 312 |
|
| 313 |
// front end actions |
| 314 |
$('body').on('visualizer:action:specificchart', function(event, v){ |
| 315 |
switch(v.action){ |
| 316 |
case 'print': |
| 317 |
var id = v.id; |
| 318 |
if(typeof rendered_charts[id] === 'undefined'){ |
| 319 |
return; |
| 320 |
} |
| 321 |
$('#' + id + ' .buttons-print').trigger('click'); |
| 322 |
break; |
| 323 |
} |
| 324 |
}); |
| 325 |
|
| 326 |
})(jQuery); |
| 327 |
|
| 328 |
|
| 329 |
/* jshint ignore:start */ |
| 330 |
|
| 331 |
/** |
| 332 |
* Date / time formats often from back from server APIs in a format that you |
| 333 |
* don't wish to display to your end users (ISO8601 for example). This rendering |
| 334 |
* helper can be used to transform any source date / time format into something |
| 335 |
* which can be easily understood by your users when reading the table, and also |
| 336 |
* by DataTables for sorting the table. |
| 337 |
* |
| 338 |
* The [MomentJS library](http://momentjs.com/) is used to accomplish this and |
| 339 |
* you simply need to tell it which format to transfer from, to and specify a |
| 340 |
* locale if required. |
| 341 |
* |
| 342 |
* This function should be used with the `dt-init columns.render` configuration |
| 343 |
* option of DataTables. |
| 344 |
* |
| 345 |
* It accepts one, two or three parameters: |
| 346 |
* |
| 347 |
* $.fn.dataTable.render.moment( to ); |
| 348 |
* $.fn.dataTable.render.moment( from, to ); |
| 349 |
* $.fn.dataTable.render.moment( from, to, locale ); |
| 350 |
* |
| 351 |
* Where: |
| 352 |
* |
| 353 |
* * `to` - the format that will be displayed to the end user |
| 354 |
* * `from` - the format that is supplied in the data (the default is ISO8601 - |
| 355 |
* `YYYY-MM-DD`) |
| 356 |
* * `locale` - the locale which MomentJS should use - the default is `en` |
| 357 |
* (English). |
| 358 |
* |
| 359 |
* @name datetime |
| 360 |
* @summary Convert date / time source data into one suitable for display |
| 361 |
* @author [Allan Jardine](http://datatables.net) |
| 362 |
* @requires DataTables 1.10+ |
| 363 |
* |
| 364 |
* @example |
| 365 |
* // Convert ISO8601 dates into a simple human readable format |
| 366 |
* $('#example').DataTable( { |
| 367 |
* columnDefs: [ { |
| 368 |
* targets: 1, |
| 369 |
* render: $.fn.dataTable.render.moment( 'Do MMM YYYYY' ) |
| 370 |
* } ] |
| 371 |
* } ); |
| 372 |
* |
| 373 |
* @example |
| 374 |
* // Specify a source format - in this case a unix timestamp |
| 375 |
* $('#example').DataTable( { |
| 376 |
* columnDefs: [ { |
| 377 |
* targets: 2, |
| 378 |
* render: $.fn.dataTable.render.moment( 'X', 'Do MMM YY' ) |
| 379 |
* } ] |
| 380 |
* } ); |
| 381 |
* |
| 382 |
* @example |
| 383 |
* // Specify a source format and locale |
| 384 |
* $('#example').DataTable( { |
| 385 |
* columnDefs: [ { |
| 386 |
* targets: 2, |
| 387 |
* render: $.fn.dataTable.render.moment( 'YYYY/MM/DD', 'Do MMM YY', 'fr' ) |
| 388 |
* } ] |
| 389 |
* } ); |
| 390 |
*/ |
| 391 |
(function( factory ) { |
| 392 |
"use strict"; |
| 393 |
|
| 394 |
if ( typeof define === 'function' && define.amd ) { |
| 395 |
// AMD |
| 396 |
define( ['jquery'], function ( $ ) { |
| 397 |
return factory( $, window, document ); |
| 398 |
} ); |
| 399 |
} |
| 400 |
else if ( typeof exports === 'object' ) { |
| 401 |
// CommonJS |
| 402 |
module.exports = function (root, $) { |
| 403 |
if ( ! root ) { |
| 404 |
root = window; |
| 405 |
} |
| 406 |
|
| 407 |
if ( ! $ ) { |
| 408 |
$ = typeof window !== 'undefined' ? |
| 409 |
require('jquery') : |
| 410 |
require('jquery')( root ); |
| 411 |
} |
| 412 |
|
| 413 |
return factory( $, root, root.document ); |
| 414 |
}; |
| 415 |
} |
| 416 |
else { |
| 417 |
// Browser |
| 418 |
factory( jQuery, window, document ); |
| 419 |
} |
| 420 |
} |
| 421 |
(function( $, window, document ) { |
| 422 |
|
| 423 |
|
| 424 |
$.fn.dataTable.render.moment = function ( from, to, locale ) { |
| 425 |
// Argument shifting |
| 426 |
if ( arguments.length === 1 ) { |
| 427 |
locale = 'en'; |
| 428 |
to = from; |
| 429 |
from = 'YYYY-MM-DD'; |
| 430 |
} |
| 431 |
else if ( arguments.length === 2 ) { |
| 432 |
locale = 'en'; |
| 433 |
} |
| 434 |
|
| 435 |
return function ( d, type, row ) { |
| 436 |
if (!d) return null; |
| 437 |
var m = window.moment( d, from, locale, true ); |
| 438 |
|
| 439 |
// Order and type get a number value from Moment, everything else |
| 440 |
// sees the rendered value |
| 441 |
return m.format( type === 'sort' || type === 'type' ? 'x' : to ); |
| 442 |
}; |
| 443 |
}; |
| 444 |
|
| 445 |
|
| 446 |
})); |
| 447 |
|
| 448 |
/* jshint ignore:end */ |