PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.6
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.6
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / js / media / view.js

view.js in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.0.6, at js/media/view.js

515 lines 12.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*jshint scripturl:true*/
2 /* global google */
3 /* global visualizer */
4 /* global showNotice */
5 (function($, wpm) {
6 var libraryWidth, libraryHeight, wpmv, wpmV, wpmvv, wpmvvl, wpmvvb, l10n;
7
8 wpmv = wpm.view;
9 wpmV = wpm.View;
10 wpmvv = wpmv.visualizer = {};
11 l10n = wpmv.l10n.visualizer;
12
13 /**
14 * =========================================================================
15 * COMMON
16 * =========================================================================
17 */
18
19 if (!_.isFunction(wpmV.prototype.make)) {
20 wpmV.prototype.make = function(tag, attrs, val) {
21 var html, attr;
22
23 html = '<' + tag;
24 for (attr in attrs) {
25 html += ' ' + attr + '="' + attrs[attr] + '"';
26 }
27 html += '>' + val + '</' + tag + '>';
28
29 return html;
30 };
31 }
32
33 wpmvv.Chart = wpmV.extend({
34 className: 'visualizer-library-chart-canvas',
35
36 constructor: function(options) {
37 this.id = 'visualizer-chart-' + options.model.get('id');
38 wpmV.apply(this, arguments);
39 },
40
41 render: function() {
42 var self, model, chart, gv, type, series, data, table, settings, i, j, row, date, format, formatter, axis, property;
43
44 self = this;
45 gv = google.visualization;
46 model = self.model;
47
48 self.$el
49 .width(self.options.width)
50 .height(self.options.height)
51 .css('background-image', 'none');
52
53 type = model.get('type');
54 series = model.get('series');
55 data = model.get('data');
56 settings = model.get('settings');
57
58 settings.width = self.options.width;
59 settings.height = self.options.height;
60
61 table = new gv.DataTable({cols: series});
62
63 switch (type) {
64 case "gauge":
65 case "table":
66 case "timeline":
67 chart = type.charAt(0).toUpperCase() + type.slice(1);
68 break;
69 default:
70 chart = type.charAt(0).toUpperCase() + type.slice(1) + 'Chart';
71 break;
72 }
73
74 chart = new gv[chart](self.el);
75
76 switch (type) {
77 case 'pie':
78 if (settings.slices) {
79 for (i in settings.slices) {
80 if (settings.slices[i]['color'] === '') {
81 delete settings.slices[i]['color'];
82 }
83 }
84 }
85 break;
86 case 'line':
87 case 'bar':
88 case 'column':
89 case 'area':
90 case 'scatter':
91 case 'candlestick':
92 if (settings.series) {
93 for (i in settings.series) {
94 if (settings.series[i]['color'] === '') {
95 delete settings.series[i]['color'];
96 }
97 }
98 }
99 break;
100 case 'geo':
101 if (settings.region !== undefined && settings.region.replace(/^\s+|\s+$/g, '') === '') {
102 settings['region'] = 'world';
103 }
104 break;
105 case 'gauge':
106 break;
107 default:
108 return;
109 }
110
111 if (series[0] && (series[0].type === 'date' || series[0].type === 'datetime')) {
112 axis = false;
113 switch (type) {
114 case 'line':
115 case 'area':
116 case 'scatter':
117 case 'candlestick':
118 case 'column':
119 axis = settings.hAxis;
120 break;
121 case 'bar':
122 axis = settings.vAxis;
123 break;
124 }
125
126 if (axis) {
127 for (property in axis.viewWindow) {
128 date = new Date(axis.viewWindow[property]);
129 if (Object.prototype.toString.call(date) === "[object Date]") {
130 if (!isNaN(date.getTime())) {
131 axis.viewWindow[property] = date;
132 continue;
133 }
134 }
135
136 delete axis.viewWindow[property];
137 }
138 }
139 }
140
141 for (i = 0; i < data.length; i++) {
142 row = [];
143 for (j = 0; j < series.length; j++) {
144 if (series[j].type === 'date' || series[j].type === 'datetime') {
145 date = new Date(data[i][j]);
146 data[i][j] = null;
147 if (Object.prototype.toString.call(date) === "[object Date]") {
148 if (!isNaN(date.getTime())) {
149 data[i][j] = date;
150 }
151 }
152 }
153 row.push(data[i][j]);
154 }
155 table.addRow(row);
156 }
157
158 if (settings.series) {
159 for (i = 0; i < settings.series.length; i++) {
160 format = settings.series[i].format;
161 if (!format || format === '') {
162 continue;
163 }
164
165 formatter = null;
166 switch (series[i + 1].type) {
167 case 'number':
168 formatter = new gv.NumberFormat({pattern: format});
169 break;
170 case 'date':
171 case 'datetime':
172 case 'timeofday':
173 formatter = new gv.DateFormat({pattern: format});
174 break;
175 }
176
177 if (formatter) {
178 formatter.format(table, i + 1);
179 }
180 }
181 }
182
183 chart.draw(table, settings);
184 }
185 });
186
187 /**
188 * =========================================================================
189 * LIBRARY
190 * =========================================================================
191 */
192
193 wpmvvl = wpmvv.Library = wpmV.extend({
194 id: 'visualizer-library-view',
195 className: 'visualizer-clearfix',
196 template: wpm.template('visualizer-library-empty'),
197
198 initialize: function() {
199 var self = this;
200
201 _.defaults(self.options, {
202 filter: 'all',
203 page: 1
204 });
205
206 self.controller.on('visualizer:library:filter', self.onFilterChanged, self);
207 self.controller.on('visualizer:library:page', self.onPageChanged, self);
208 self.collection.on('reset', self.renderCollection, self);
209
210 self.resetCollection();
211 },
212
213 onFilterChanged: function(filter) {
214 this.options.filter = filter;
215 this.options.page = 1;
216 this.resetCollection();
217 },
218
219 onPageChanged: function(page) {
220 this.options.page = page;
221 this.resetCollection();
222 },
223
224 render: function() {},
225
226 renderCollection: function() {
227 var self = this;
228
229 if (self.collection.length > 0) {
230 self.$el.html('');
231 self.collection.each(self.addChart, self);
232 } else {
233 self.$el.html(self.template({}));
234 }
235 },
236
237 addChart: function(chart) {
238 var self = this,
239 view = new wpmvvl.Chart({ model: chart });
240
241 self.$el.append(view.$el);
242 self.views.set('#visualizer-chart-' + chart.get('id'), view, { silent: true });
243 view.render();
244 },
245
246 resetCollection: function() {
247 var self = this,
248 controller = self.controller,
249 content = controller.$el.find(controller.content.selector);
250
251 content.lock();
252 self.collection.fetch({
253 silent: false,
254 data: {
255 filter: self.options.filter,
256 page: self.options.page
257 },
258 statusCode: {
259 200: function(response) {
260 var paginationView = controller.toolbar.get('toolbar').get('pagination');
261
262 if (self.options.page > response.total) {
263 self.options.page = response.total;
264 self.resetCollection();
265 } else {
266 paginationView.options.page = self.options.page;
267 paginationView.options.total = response.total || 1;
268 paginationView.render();
269 }
270
271 self.renderCollection();
272 content.unlock();
273 }
274 }
275 });
276 }
277 });
278
279 wpmvvl.Chart = wpmV.extend({
280 className: 'visualizer-library-chart',
281 template: wpm.template('visualizer-library-chart'),
282
283 events: {
284 'click .visualizer-library-chart-delete': 'deleteChart',
285 'click .visualizer-library-chart-insert': 'insertChart',
286 'click .visualizer-library-chart-shortcode': 'selectShortcode'
287 },
288
289 initialize: function() {
290 var self = this;
291
292 if (!libraryWidth && !libraryHeight) {
293 libraryWidth = $('#visualizer-library-view').width() / 3 - 40;
294 libraryHeight = libraryWidth * 3 / 4;
295
296 libraryWidth = Math.floor(libraryWidth);
297 libraryHeight = Math.floor(libraryHeight);
298 }
299
300 self._view = new wpmvv.Chart({
301 model: self.model,
302 width: libraryWidth,
303 height: libraryHeight
304 });
305
306 self.$el.html(self.template(self.model.toJSON())).prepend(self._view.$el);
307 self.views.set('#' + self._view.id, self._view, { silent: true });
308 },
309
310 render: function() {
311 this._view.render();
312 },
313
314 deleteChart: function() {
315 var self = this;
316
317 if (showNotice.warn()) {
318 self.model.destroy({
319 wait: true,
320 success: function() {
321 self.views.parent.resetCollection();
322 }
323 });
324 }
325 },
326
327 insertChart: function() {
328 wpm.editor.insert('[visualizer id="' + this.model.get('id') + '"]');
329 },
330
331 selectShortcode: function(e) {
332 var range, selection;
333
334 if (window.getSelection && document.createRange) {
335 selection = window.getSelection();
336 range = document.createRange();
337 range.selectNodeContents(e.target);
338 selection.removeAllRanges();
339 selection.addRange(range);
340 } else if (document.selection && document.body.createTextRange) {
341 range = document.body.createTextRange();
342 range.moveToElementText(e.target);
343 range.select();
344 }
345 }
346 });
347
348 wpmvvl.Types = wpmV.extend({
349 tagName: 'select',
350 className: 'visualizer-library-filters',
351
352 events: {
353 change: 'onFilterChange'
354 },
355
356 initialize: function() {
357 var self = this;
358
359 self.createFilters();
360 self.$el.html(_.chain(self.filters).map(function(filter) {
361 return {
362 el: self.make('option', {value: filter.key}, filter.text),
363 priority: filter.priority || 50
364 };
365 }).sortBy('priority').pluck('el').value());
366 },
367
368 createFilters: function() {
369 var self = this;
370
371 self.filters = {};
372 _.each(l10n.library.types, function(type, i) {
373 self.filters[type] = {
374 text: l10n.library.filters[type],
375 key: type,
376 priority: (i + 1) * 10
377 };
378 });
379 },
380
381 onFilterChange: function() {
382 this.controller.trigger('visualizer:library:filter', this.el.value);
383 }
384 });
385
386 wpmvvl.Pagination = wpmV.extend({
387 id: 'visualizer-library-pagination',
388 tagName: 'ul',
389
390 events: {
391 'click a.visualizer-library-pagination-page': 'onPageChange'
392 },
393
394 initialize: function() {
395 _.defaults(this.options, {
396 total: 1,
397 page: 1
398 });
399 },
400
401 render: function() {
402 var self, items;
403
404 self = this;
405 if (self.options.page <= 1 && self.options.total <= 1) {
406 self.$el.html('');
407 return;
408 }
409
410 items = self._pagination(self.options.page, self.options.total, 7);
411
412 self.$el.html(_.chain(items).map(function(item) {
413 var content, className;
414
415 content = item === '...' || item === self.options.page ? self.make('span', { class: 'visualizer-library-pagination-page' }, item) : self.make('a', { class: 'visualizer-library-pagination-page', href: 'javascript:;', 'data-page': item }, item);
416
417 className = item === self.options.page ? 'visualizer-library-pagination-item visualizer-library-pagination-active' : 'visualizer-library-pagination-item';
418
419 return self.make('li', { class: className }, content);
420 }).value());
421 },
422
423 _pagination: function(current, total, max) {
424 var i, tmp, pagenation = [];
425
426 if ( total <= max ) {
427 for ( i = 1; i <= total; i++ ) {
428 pagenation.push(i);
429 }
430 } else {
431 tmp = current - Math.floor( max / 2 );
432
433 if ( max % 2 === 0 ) {
434 tmp++;
435 }
436
437 if ( tmp < 1 ) {
438 tmp = 1;
439 }
440
441 if ( tmp + max > total ) {
442 tmp = total - max + 1;
443 }
444
445 for ( i = 1; i <= max; i++ ) {
446 pagenation.push(tmp++);
447 }
448
449 if ( pagenation[0] !== 1 ) {
450 pagenation[0] = 1;
451 pagenation[1] = '...';
452 }
453
454 if ( pagenation[max - 1] !== total ) {
455 pagenation[max - 1] = total;
456 pagenation[max - 2] = '...';
457 }
458 }
459
460 return pagenation;
461 },
462
463 onPageChange: function(e) {
464 this.controller.trigger('visualizer:library:page', $(e.target).data('page'));
465 }
466 });
467 })(jQuery, wp.media);
468
469 (function($) {
470 $.fn.lock = function() {
471 $(this).each(function() {
472 var locker = $('<div class="locker"></div>'),
473 loader = $('<div class="locker-loader"></div>'),
474 $this = $(this),
475 position = $this.css('position');
476
477 if ($this.find('.locker').length > 0) {
478 return;
479 }
480
481 if (!position) {
482 position = 'static';
483 }
484
485 $this.css('overflow', 'hidden');
486 switch(position) {
487 case 'absolute':
488 case 'relative':
489 break;
490 default:
491 $this.css('position', 'relative');
492 break;
493 }
494 $this.data('position', position);
495
496 locker.css('top', $this.scrollTop() + 'px').append(loader);
497 $this.append(locker);
498 });
499
500 return $(this);
501 };
502
503 $.fn.unlock = function() {
504 $(this).each(function() {
505 var $this = $(this);
506
507 $this.css({
508 position: $this.data('position'),
509 overflow: 'auto'
510 }).find('.locker').remove();
511 });
512
513 return $(this);
514 };
515 })(jQuery);