PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.0.2
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.0.2
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 3.10.4 All 148 releases
visualizer / js / media / view.js

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

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