' +
56 | ' | ' +
57 | ' ' +
58 | ' ' +
59 | ' | ' +
60 | ' ' +
61 | ' ' +
62 | ' ' +
63 | ' ' +
64 | ' ' +
65 | ' ' +
66 | ' ' +
67 | ' ' +
68 | ' ' +
69 | ' '
70 | );
71 |
72 |
73 | // Size/scroll synchronization init
74 | $this.find('.' + opts.div22Class).on('scroll', function(){
75 | syncScrollAndSize($this, opts);
76 | });
77 | $this.find('.' + opts.cell22Class).resize(function(){
78 | syncScrollAndSize($this, opts);
79 | });
80 | $this.find('.' + opts.div11Class).on('click', function(){
81 | toggleConfig($this, opts);
82 | });
83 | createConfigDialog($this, opts);
84 | $this.find('#' + opts.pivotConfigDialogId).dialog({
85 | modal : false,
86 | title : 'Pivot Table Configuration',
87 | position:["right", "50px"],
88 | beforeClose : function() {
89 | var $div11 = $this.find('.' + opts.div11Class);
90 | $div11.removeClass(opts.configWindowActivatedClass);
91 | },
92 | });
93 | jQuery('#' + opts.pivotConfigDialogId).dialog('close');
94 |
95 | syncScrollAndSize($this, opts);
96 | incrementalDraw($this, [], [opts.verticalDimensions[0], opts.horizontalDimensions[0]], 0, 0, opts);
97 | initExpandListeners($this, opts);
98 | /*
99 | redraw($this, opts);
100 | */
101 | });
102 | if(opts.resizable) {
103 | if(opts.resizableWidth) {
104 | doResizeWidth(outThis);
105 | }
106 | if(opts.resizableHeight) {
107 | doResizeHeight(outThis);
108 | }
109 | }
110 | return res;
111 | },
112 |
113 | options : function(newData, reasonCell) {
114 | var $this = $(this);
115 | var data = $this.data('cypivot');
116 | return data.options;
117 | },
118 |
119 | reload : function(newData, reasonCell) {
120 | return this.each(function(){
121 | var $this = $(this),
122 | data = $this.data('cypivot');
123 | if(newData)
124 | data.options.data=newData;
125 |
126 | if(reasonCell) {
127 | var $dataTable = $this.find('.' + data.options.div22Class + ' .' + data.options.pivotDataTableClass);
128 | var dataTable = $dataTable[0];
129 | var rowItems;
130 | for(var rowIdx = 0; rowIdx < dataTable.rows.length; rowIdx++) {
131 | var row = dataTable.rows[rowIdx];
132 | for(var colIdx = 0; colIdx < row.cells.length; colIdx++) {
133 | var cell = row.cells[colIdx];
134 | if(isSubContext(cell.colContext, reasonCell.colContext) &&
135 | isSubContext(cell.rowContext, reasonCell.rowContext)) {
136 | cell.isCalculated = false;
137 | }
138 | }
139 | }
140 | fillDataValues($this, data.options);
141 | } else {
142 | fillDataValues($this, data.options, true);
143 | }
144 | });
145 | },
146 |
147 | reconfig : function(newOpts) {
148 | var opts = $.extend({}, $.fn.cypivot.defaults, newOpts);
149 | var $this = $(this);
150 | redraw($this, opts);
151 | }
152 |
153 | }
154 |
155 |
156 | $.fn.cypivot = function(method) {
157 | // Method calling logic
158 | if ( methods[method] ) {
159 | return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
160 | } else if ( typeof method === 'object' || ! method ) {
161 | return methods.init.apply( this, arguments );
162 | } else {
163 | $.error( 'Method ' + method + ' does not exist on jQuery.tooltip' );
164 | }
165 | }
166 |
167 | function incrementalDraw($table, dimensions, context, row, col, opts) {
168 | // Prepare callback that will be invoked when data is ready
169 | var callBack = function(curData){
170 | var dimName = opts.verticalDimensions[0];
171 | var values = getDataValues(curData, context, dimName, '');
172 | console.log("curData", curData);
173 | console.log("values", values);
174 | // drawDimension($div, opts, dimensions, context, curData) // fffff
175 |
176 | $pivotDataTable = $table.find('.' + opts.div22Class + ' .' + opts.pivotDataTableClass);
177 |
178 | var $horizontalDimDiv = $table.find('.' + opts.div21Class);
179 | var values = drawDimension($horizontalDimDiv, opts, opts.horizontalDimensions, [], curData);
180 | insertRows($pivotDataTable[0], opts, 0, values.length);
181 |
182 |
183 | var $verticalDimDiv = $table.find('.' + opts.div12Class);
184 | values = drawDimension($verticalDimDiv, opts, opts.verticalDimensions, [], curData);
185 | insertColumns($pivotDataTable[0], opts, 0, values.length, curData);
186 |
187 | syncDimensionsSizes($table, opts);
188 | };
189 |
190 | // Trying to get current data
191 | var curData = opts.dataProvider(opts, dimensions, context, callBack);
192 |
193 | if(curData) {
194 | // If method returns data - display it
195 | callBack(curData);
196 | }
197 | }
198 |
199 | function createConfigDialog($table, opts) {
200 | var $dialog = $table.find('.' + opts.configDialogClass);
201 | var busyDims = {};
202 |
203 | var verticalDimensionsHtml = ' ' + opts.verticalDimensionListTitle + '';
204 | for(var i = 0; i < opts.verticalDimensions.length; i++) {
205 | var key = opts.verticalDimensions[i];
206 | busyDims[key] = true;
207 | var dim = opts.dimensions[key];
208 | verticalDimensionsHtml = verticalDimensionsHtml + ' ' + dim.label + '';
209 | }
210 | if(!opts.configuration || !opts.configuration.verticalDimensions) {
211 | verticalDimensionsHtml = '';
212 | }
213 |
214 | var horizontalDimensionsHtml = ' ' + opts.horizontalDimensionListTitle + '';
215 | for(var i = 0; i < opts.horizontalDimensions.length; i++) {
216 | var key = opts.horizontalDimensions[i];
217 | busyDims[key] = true;
218 | var dim = opts.dimensions[key];
219 | horizontalDimensionsHtml = horizontalDimensionsHtml + ' ' + dim.label + '';
220 | }
221 | if(!opts.configuration || !opts.configuration.horizontalDimensions) {
222 | var horizontalDimensionsHtml = '';
223 | }
224 |
225 | var filterDimensionsHtml = ' ' + opts.filterDimensionListTitle + '';
226 | for(var i = 0; i < opts.filterDimensions.length; i++) {
227 | var key = opts.filterDimensions[i];
228 | busyDims[key] = true;
229 | var dim = opts.dimensions[key];
230 | var filterValues = getDataValues(opts, [], key, '');
231 |
232 | var filterValuesHtml = ' ';
239 |
240 |
241 | filterDimensionsHtml = filterDimensionsHtml + ' ' + dim.label +
242 | filterValuesHtml +
243 | '';
244 | }
245 | if(!opts.configuration || !opts.configuration.filterDimensions) {
246 | filterDimensionsHtml = '';
247 | }
248 |
249 | var dimensionsHtml = '';
250 | for(var key in opts.dimensions) {
251 | if(busyDims[key] != true) {
252 | var dim = opts.dimensions[key];
253 | dimensionsHtml = dimensionsHtml + ' ' + dim.label + '';
254 | }
255 | }
256 |
257 | $dialog.append(
258 | ' ' +
259 | '- ' + opts.dimensionListTitle + '
' +
260 | ' ' +
261 | ' ' +
262 | dimensionsHtml +
263 | horizontalDimensionsHtml +
264 | verticalDimensionsHtml +
265 | filterDimensionsHtml +
266 | ' '
267 | );
268 | $dialog.find('ul.' + opts.dimensionListClass).sortable({
269 | cancel: '.' + opts.dimensionListTitleClass,
270 | update : function() {
271 | // Update pivot table when dimensions has been changed
272 | var vdims = [], hdims = [], fdims=[], curdims=[];
273 | $dialog.find('.' + opts.dimensionListClass + ' li').each(function(){
274 |
275 | var dim = jQuery(this).attr('dim');
276 | if(dim) {
277 | curdims[curdims.length] = dim;
278 | }
279 | if(jQuery(this).attr('vdims') == 'true') {
280 | curdims = vdims;
281 | }
282 | if(jQuery(this).attr('hdims') == 'true') {
283 | curdims = hdims;
284 | }
285 | if(jQuery(this).attr('fdims') == 'true') {
286 | curdims = fdims;
287 | }
288 | });
289 | if(opts.configuration && opts.configuration.verticalDimensions == true) {
290 | opts.verticalDimensions = vdims;
291 | }
292 | if(opts.configuration && opts.configuration.horizontalDimensions == true) {
293 | opts.horizontalDimensions = hdims;
294 | }
295 | if(opts.configuration && opts.configuration.filterDimensions == true) {
296 | opts.filterDimensions = fdims;
297 | }
298 | if(opts.cookiePrefix && opts.storeDimConfig) {
299 | var sHorizontalDims = opts.horizontalDimensions.join(';');
300 | var sVerticalDims = opts.verticalDimensions.join(';');
301 | var sFilterDims = opts.filterDimensions.join(';');
302 | $.cookie(opts.cookiePrefix + 'horizontalDims', sHorizontalDims, {expires:15});
303 | $.cookie(opts.cookiePrefix + 'verticalDims', sVerticalDims, {expires:15});
304 | $.cookie(opts.cookiePrefix + 'filterDims', sFilterDims, {expires:15});
305 | }
306 | redraw($table, opts);
307 | }
308 | });
309 | }
310 |
311 | function toggleConfig($table, opts) {
312 | if(opts.configuration) {
313 | var $div11 = $table.find('.' + opts.div11Class);
314 | $div11.toggleClass(opts.configWindowActivatedClass);
315 | if($div11.hasClass(opts.configWindowActivatedClass)) {
316 | jQuery('#' + opts.pivotConfigDialogId).dialog('open');
317 | } else {
318 | var $dialog = jQuery('#' + opts.pivotConfigDialogId);
319 | $dialog.dialog('close');
320 | }
321 | }
322 | }
323 |
324 | function getColIndex($div, opts) {
325 | // Find Top level dimension div
326 | var $top;
327 | if($div.hasClass(opts.levelClassPrefix + '0')) {
328 | $top = $div.parent();
329 | } else {
330 | $top = $div.parents('.' + opts.levelClassPrefix + '0').parent();
331 | }
332 | var index = 0;
333 | var found = false;
334 | $top.find('.' + opts.dimLabelClass).each(function() {
335 | if(!found) {
336 | var $div0 = $div[0];
337 | if(this == $div0) {
338 | found = true;
339 | return false;
340 | } else {
341 | var $this = $(this);
342 | if($this.parent().children('.' + opts.dimCellClass).size() == 0) {
343 | index++;
344 | }
345 | }
346 | }
347 | });
348 | return index;
349 | }
350 |
351 | function getRowIndex($div, opts) {
352 | // Find Top level dimension div
353 | var $top;
354 | if($div.hasClass(opts.levelClassPrefix + '0')) {
355 | $top = $div.parent();
356 | } else {
357 | $top = $div.parents('.' + opts.levelClassPrefix + '0').parent();
358 | }
359 | var index = 0;
360 | var found = false;
361 | $top.find('.' + opts.dimLabelClass).each(function() {
362 | if(!found) {
363 | var $div0 = $div[0];
364 | if(this == $div0) {
365 | found = true;
366 | return false;
367 | } else {
368 | var $this = $(this);
369 | index++;
370 | }
371 | }
372 | });
373 | return index;
374 | }
375 |
376 | function getRowContexts($table, opts) {
377 | var contexts = [];
378 | $table.find('.' + opts.div21Class + ' .' + opts.dimCellClass).each(function(){
379 | contexts[contexts.length] = this.pivotContext;
380 | });
381 | return contexts;
382 | }
383 |
384 | function getColContexts($table, opts) {
385 | var contexts = [];
386 | $table.find('.' + opts.div12Class + ' .' + opts.dimCellClass).not('.' + opts.expandedDimCellClass).each(function(){
387 | contexts[contexts.length] = this.pivotContext;
388 | });
389 | return contexts;
390 | }
391 |
392 | function dimColSubLevelCount($div, opts) {
393 | // Find Top level dimension div
394 | var $top = $div.parent();
395 | var index = 0;
396 | var $div0 = $div[0];
397 | $top.find('.' + opts.dimLabelClass).each(function() {
398 | var $this = $(this);
399 | if($this.parent().children('.' + opts.dimCellClass).size() == 0) {
400 | index++;
401 | }
402 | });
403 | return index;
404 | }
405 |
406 | function dimRowSubLevelCount($div, opts) {
407 | // Find Top level dimension div
408 | var $top = $div.parent();
409 | var index = 0;
410 | var $div0 = $div[0];
411 | index = $top.find('.' + opts.dimLabelClass).not($div0).size();
412 | /*
413 | $top.find('.' + opts.dimLabelClass).each(function() {
414 | if($div[0] != this) {
415 | index++;
416 | }
417 | });
418 | //*/
419 | return index;
420 | }
421 |
422 | function redraw($table, opts) {
423 | var $horizontalDimDiv = $table.find('.' + opts.div21Class);
424 | $horizontalDimDiv.html('');
425 | // var curData = opts.dataProvider(opts, [], [opts.verticalDimensions[0], opts.horizontalDimensions[0]]);// TODO
426 |
427 | // drawDimension($horizontalDimDiv, opts, opts.horizontalDimensions, [], curData);
428 |
429 | var $verticalDimDiv = $table.find('.' + opts.div12Class);
430 | $verticalDimDiv.html('');
431 | var $dataDimDiv = $table.find('.' + opts.div22Class);
432 | $dataDimDiv.html(' ');
433 | /*
434 | drawDimension($verticalDimDiv, opts, opts.verticalDimensions, [], curData);
435 |
436 | drawDataTable($table, opts, curData)
437 | */
438 | incrementalDraw($table, [], [opts.verticalDimensions[0], opts.horizontalDimensions[0]], 0, 0, opts);
439 | }
440 |
441 | function drawDataTable($table, opts, curData) {
442 | $pivotDataTable = $table.find('.' + opts.div22Class + ' .' + opts.pivotDataTableClass);
443 | $pivotDataTable.html('');
444 |
445 | drawDataRows($table, $pivotDataTable, opts, [], curData);
446 |
447 | fillDataValues($table, opts);
448 | syncDimensionsSizes($table, opts);
449 | }
450 |
451 | function initExpandListeners($table, opts) {
452 | // Expand/Collapse column/row
453 | // Columns
454 | $table.on('click', '.' + opts.div12Class + ' .' + opts.dimLabelClass, function(event){
455 | var $pivotDataTable = $table.find('.' + opts.div22Class + ' .' + opts.pivotDataTableClass);
456 | var t1 = new Date();
457 | var onExpand, onCollapse;
458 | var $this = $(this);
459 | var resync = false;
460 | if($this.hasClass(opts.expandedDimLabelClass)) {
461 | // Collapse columns
462 | var countToDelete = dimColSubLevelCount($this, opts);
463 | if(countToDelete > 0) {
464 | var firstColumn = getColIndex($this, opts);
465 | var pivotDataTable = $pivotDataTable[0];
466 | var totalWidth = getTotalWidth(pivotDataTable, firstColumn, countToDelete - 1);
467 |
468 | // $this.parent().find('.' + opts.dimCellClass).animate({opacity:0}, 200);
469 |
470 | deleteColumns(pivotDataTable, firstColumn, countToDelete - 1, function(){
471 | $this.parent().find('.' + opts.dimCellClass).remove();
472 |
473 | $this.width(totalWidth + "px")
474 |
475 | var width = -1;
476 | for(var rowIdx = 0; rowIdx < pivotDataTable.rows.length; rowIdx++) {
477 | var row = pivotDataTable.rows[rowIdx];
478 | cell = row.cells[firstColumn];
479 | if(width < 0) {
480 | width = jQuery(cell).width();
481 | }
482 | }
483 |
484 | $this.removeClass(opts.expandedDimLabelClass).addClass(opts.collapsedDimLabelClass);
485 | $this.parent().removeClass(opts.expandedDimCellClass).addClass(opts.collapsedDimCellClass);
486 |
487 | fillDataValues($table, opts);
488 | syncDimensionsSizes($table, opts);
489 | });
490 | }
491 | onCollapse = opts.onCollapse;
492 | } else if($this.hasClass(opts.collapsedDimLabelClass)){
493 | // Expand columns
494 | var pivotContext = this.parentElement.pivotContext;
495 | var colIdx = getColIndex($this, opts);
496 | var $parent = $this.parent();
497 |
498 | var callBack = function(curData) {
499 | drawDimension($parent, opts, opts.verticalDimensions, null, curData);
500 | var colCount = dimColSubLevelCount($this, opts);
501 | if(colCount > 0) {
502 | $this.addClass(opts.expandedDimLabelClass).removeClass(opts.collapsedDimLabelClass);
503 | $this.parent().addClass(opts.expandedDimCellClass).removeClass(opts.collapsedDimCellClass);
504 | if(colCount > 0) {
505 | insertColumns($pivotDataTable[0], opts, colIdx, colCount - 1, curData);
506 | }
507 | resync = true;
508 | }
509 | syncDimensionsSizes($table, opts);
510 |
511 | onExpand = opts.onExpand;
512 | };
513 | // Create context
514 | var context = createProviderContext(pivotContext, opts.verticalDimensions);
515 | var visibleDims = getVisibleDimensions($table, opts);
516 | var maxLevel = getCurrentVerticalMaxLevel($table, opts);
517 | if(pivotContext.length == maxLevel) {
518 | visibleDims.push(opts.verticalDimensions[pivotContext.length]);
519 | }
520 |
521 | var data = opts.dataProvider(opts, context, visibleDims, callBack);// TODO
522 | if(data) {
523 | callBack(data);
524 | }
525 | }
526 | if(resync) {
527 | fillDataValues($table, opts);
528 | if(opts.resizable) {
529 | if(opts.resizableWidth) {
530 | doResizeWidth($table);
531 | }
532 | if(opts.resizableHeight) {
533 | doResizeHeight($table);
534 | }
535 | // doResize($table);
536 | }
537 | if(onCollapse) {
538 | onCollapse(this);
539 | }
540 | if(onExpand) {
541 | onExpand(this);
542 | }
543 | syncDimensionsSizes($table, opts);
544 | }
545 | return false;
546 | });
547 | // Rows
548 | $table.on('click', '.' + opts.div21Class + ' .' + opts.dimLabelClass, function(event){
549 | var t1 = new Date();
550 | var onExpand, onCollapse;
551 | if(event.isPropagationStopped())
552 | return;
553 |
554 | var $this = $(this);
555 | var $parent = $this.parent();
556 | var resync = false;
557 | if($this.hasClass(opts.expandedDimLabelClass)) {
558 | var countToDelete = dimRowSubLevelCount($this, opts);
559 | var firstRow = getRowIndex($this, opts);
560 | var pivotDataTable = $pivotDataTable[0];
561 | if(countToDelete > 0) {
562 | deleteRows(pivotDataTable, firstRow + 1, countToDelete);
563 | $parent.find('.' + opts.dimCellClass).remove();
564 | $this.removeClass(opts.expandedDimLabelClass);
565 | $this.addClass(opts.collapsedDimLabelClass);
566 | $parent.removeClass(opts.expandedDimCellClass);
567 | $parent.addClass(opts.collapsedDimCellClass);
568 | resync = true;
569 | }
570 | onCollapse = opts.onCollapse;
571 | } else if($this.hasClass(opts.collapsedDimLabelClass)){
572 | // Expand row
573 | var pivotContext = this.parentElement.pivotContext;
574 |
575 | var rowIdx = getRowIndex($this, opts);
576 | var callBack = function(curData) {
577 | drawDimension($parent, opts, opts.horizontalDimensions, null, curData);
578 | $this.addClass(opts.expandedDimLabelClass).removeClass(opts.collapsedDimLabelClass);
579 | $parent.addClass(opts.expandedDimCellClass).removeClass(opts.collapsedDimCellClass);
580 | var rowCount = dimRowSubLevelCount($this, opts);
581 | if(rowCount > 0) {
582 | insertRows($pivotDataTable[0], opts, rowIdx + 1, rowCount, curData);
583 | resync = true;
584 | }
585 | syncDimensionsSizes($table, opts);
586 |
587 | onExpand = opts.onExpand;
588 |
589 | };
590 |
591 | // Create context
592 | var context = createProviderContext(pivotContext, opts.horizontalDimensions);
593 | var visibleDims = getVisibleDimensions($table, opts);
594 | var maxLevel = getCurrentHorizontalMaxLevel($table, opts);
595 | if(pivotContext.length == maxLevel) {
596 | visibleDims.push(opts.horizontalDimensions[pivotContext.length]);
597 | }
598 |
599 | var data = opts.dataProvider(opts, context, visibleDims, callBack);// TODO
600 | if(data) {
601 | callBack(data);
602 | }
603 |
604 | onExpand = opts.onExpand;
605 | }
606 | if(resync) {
607 | if(opts.resizable) {
608 | if(opts.resizableWidth) {
609 | doResizeWidth($table);
610 | }
611 | if(opts.resizableHeight) {
612 | doResizeHeight($table);
613 | }
614 | // doResize($table);
615 | }
616 | fillDataValues($table, opts);
617 | if(onCollapse) {
618 | onCollapse(this);
619 | }
620 | if(onExpand) {
621 | onExpand(this);
622 | }
623 | syncDimensionsSizes($table, opts);
624 | }
625 | var t2 = new Date();
626 | // jQuery('#log').html("Time = " + (t2.valueOf() - t1.valueOf()));
627 | return false;
628 | });
629 | }
630 |
631 | function createProviderContext(pivotContext, dimensions) {
632 | var res = {};
633 | for(var i = 0; i < pivotContext.length; i++) {
634 | res[dimensions[i]] = pivotContext[i];
635 | }
636 | return res;
637 | }
638 |
639 | function getVisibleDimensions($table, opts) {
640 | var res = [];
641 | getInnerVisibleDimensions($table, opts, opts.div21Class, opts.horizontalDimensions, res);
642 | getInnerVisibleDimensions($table, opts, opts.div12Class, opts.verticalDimensions, res);
643 | return res;
644 | }
645 |
646 | function getInnerVisibleDimensions($table, opts, selector, dimensions, res) {
647 | var max = 0;
648 | $table.find('.' + selector + ' .' + opts.dimCellClass).each(function(){
649 | if(max < this.pivotContext.length)
650 | max = this.pivotContext.length;
651 | });
652 | for(var i = 0; i < max; i++) {
653 | res.push(dimensions[i]);
654 | }
655 | }
656 |
657 | /**
658 | * Calclulates max expanded level for vertical dimensions
659 | */
660 | function getCurrentVerticalMaxLevel($table, opts) {
661 | var max = 0;
662 | $table.find('.' + opts.div12Class + ' .' + opts.dimCellClass).each(function(){
663 | if(max < this.pivotContext.length)
664 | max = this.pivotContext.length;
665 | });
666 | return max;
667 | }
668 |
669 | /**
670 | * Calclulates max expanded level for horizontal dimensions
671 | */
672 | function getCurrentHorizontalMaxLevel($table, opts) {
673 | var max = 0;
674 | $table.find('.' + opts.div21Class + ' .' + opts.dimCellClass).each(function(){
675 | if(max < this.pivotContext.length)
676 | max = this.pivotContext.length;
677 | });
678 | return max;
679 | }
680 |
681 | function getTotalWidth(table, firstColumn, columnCount) {
682 | var res = 0;
683 | var row = table.rows[0];
684 | for(var i = 0; i < columnCount; i++) {
685 | cell = row.cells[firstColumn + i];
686 | var width = jQuery(cell).width();
687 | res += width;
688 | }
689 | return res;
690 | }
691 |
692 | function fillDataValues($table, opts, force) {
693 | var rowContexts = getRowContexts($table, opts);
694 | var colContexts = getColContexts($table, opts);
695 | var $dataTable = $table.find('.' + opts.div22Class + ' .' + opts.pivotDataTableClass);
696 | var dataTable = $dataTable[0];
697 | var rowItems;
698 | for(var rowIdx = 0; rowIdx < dataTable.rows.length; rowIdx++) {
699 | var row = dataTable.rows[rowIdx];
700 | var rowContext = rowContexts[rowIdx];
701 | rowItems = null;
702 | for(var colIdx = 0; colIdx < row.cells.length; colIdx++) {
703 | var colContext = colContexts[colIdx];
704 | var cell = row.cells[colIdx];
705 | cell.colContext = colContext;
706 | cell.rowContext = rowContext;
707 | if(cell.isCalculated != true || force == true) {
708 | if(rowItems == null) {
709 | rowItems = opts.map(rowContext, [], opts.data);
710 | }
711 | var maps = opts.map(rowContext, colContext, rowItems['default']);
712 | var reduces = opts.reduce(maps);
713 | var html = "";
714 | if(opts.dataCellRenderer) {
715 | html = opts.dataCellRenderer(reduces, colContext, rowContext, opts);
716 | } else if($("#cellTemplate").size() > 0){
717 | //*
718 | var template = $("#cellTemplate").html();
719 | html = _.template(template,{items:reduces, rowContext:rowContext, colContext:colContext, options:opts})
720 | // var html = "555";
721 | //*/
722 | }
723 | jQuery(cell).html('' + html + ' ');
724 | cell.isCalculated = true;
725 | }
726 | }
727 | }
728 | }
729 |
730 | function contextToString(context) {
731 | var s = '[';
732 | for(var i = 0; i < context.length; i++) {
733 | var item = context[i];
734 | if(i > 0) {
735 | s = s + ', ';
736 | }
737 | s = s + item.label;
738 | }
739 | s = s + ']';
740 | return s;
741 | }
742 |
743 | function insertColumns(table, opts, startColumnIdx, columnCount, curData) {
744 | var $table = $(table);
745 | var rowContexts = getRowContexts($table.parents('.cypivot'), opts);
746 | var colContexts = getColContexts($table.parents('.cypivot'), opts);
747 |
748 | for(var rowIdx = 0; rowIdx < table.rows.length; rowIdx++) {
749 | var row = table.rows[rowIdx];
750 | var rowContext = rowContexts[rowIdx];
751 | for(var colCount = 0; colCount < columnCount; colCount++) {
752 | var colContext = colContexts[startColumnIdx + colCount];
753 |
754 | var cell = row.insertCell(startColumnIdx + colCount);
755 | cell.className = opts.dataCellClass;
756 | var cellDiv = document.createElement('div');
757 | cell.appendChild(cellDiv);
758 | cellDiv.className = opts.divDataCellClass;
759 |
760 | var maps = opts.map(rowContext, colContext, curData);
761 | var reduces = opts.reduce(maps);
762 | var html = "";
763 | if(opts.dataCellRenderer) {
764 | html = opts.dataCellRenderer(reduces, colContext, rowContext, opts);
765 | }
766 | $(cellDiv).html(html);
767 |
768 | }
769 | }
770 | }
771 |
772 | function insertRows(table, opts, startRowIdx, rowCount, curData) {
773 | var $table = $(table);
774 | var rowContexts = getRowContexts($table.parents('.cypivot'), opts);
775 | var colContexts = getColContexts($table.parents('.cypivot'), opts);
776 |
777 | var firstRow = table.rows.length > 0 ? table.rows[0] : null;
778 | for(var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
779 | var row = table.insertRow(startRowIdx + rowIdx);
780 | var rowContext = rowContexts[startRowIdx + rowIdx];
781 | var html = [];
782 | if(firstRow) { // When we add to empty table firstRow is null
783 | for(var colIdx = 0; colIdx < firstRow.cells.length; colIdx++) {
784 | var colContext = colContexts[colIdx];
785 |
786 | var maps = opts.map(rowContext, colContext, curData);
787 | var reduces = opts.reduce(maps);
788 | var cellHtml = "";
789 | if(opts.dataCellRenderer) {
790 | cellHtml = opts.dataCellRenderer(reduces, colContext, rowContext, opts);
791 | }
792 |
793 | html.push('' + cellHtml + ' | ');
794 | }
795 | }
796 | jQuery(row).html(html.join(""));
797 | }
798 | // fillDataValues($table, opts);
799 | }
800 |
801 | function deleteColumns(table, startColumnIdx, columnCount, finalizer) {
802 | for(var rowIdx = 0; rowIdx < table.rows.length; rowIdx++) {
803 | var row = table.rows[rowIdx];
804 | for(var colCount = 0; colCount < columnCount; colCount++) {
805 | var cell = row.cells[startColumnIdx + colCount];
806 | // jQuery(cell).addClass("___animation-cypivot");
807 | row.deleteCell(startColumnIdx);
808 | }
809 | }
810 |
811 | if(finalizer) {
812 | finalizer();
813 | }
814 |
815 | // Case when closed empty level (no children)
816 | if(columnCount == 0 && finalizer) {
817 | // finalizer();
818 | }
819 | }
820 |
821 | function deleteRows(table, startRowIdx, rowCount) {
822 | for(var rowIdx = 0; rowIdx < rowCount; rowIdx++) {
823 | table.deleteRow(startRowIdx);
824 | }
825 | }
826 |
827 | function syncRowHeight($table, opts, newContext, $row) {
828 | var selector = '.' + opts.div21Class;
829 | for(var i = 0; i < newContext.length; i++) {
830 | selector = selector + ' .' + opts.levelClassPrefix + i + '.' + opts.pivotIdClassPrefix + newContext[i].id;
831 | }
832 | selector = selector + ' .' + opts.dimLabelClass;
833 | var $dimLabelDiv = $table.find(selector).first();
834 | $row.resize(function() {
835 | $dimLabelDiv.css({height :($row.height() - 2 )+ "px"});
836 | });
837 | $dimLabelDiv.css({height :($row.height() -2) + "px"});
838 | }
839 |
840 | function syncDimensionsSizes($table, opts) {
841 | if(opts.syncDimensionCellSizes == true) {
842 | syncRowsHeight($table, opts);
843 | syncColumnsWidth($table, opts);
844 | }
845 | }
846 |
847 | function syncColumnsWidth($table, opts) {
848 | var $pivotDataTable = $table.find('.' + opts.div22Class + ' .' + opts.pivotDataTableClass);
849 | var pivotDataTable = $pivotDataTable[0];
850 | var firstRow = pivotDataTable.rows[0];
851 |
852 | var i = 0;
853 | if(firstRow) {
854 | // $table.find('.' + opts.dimLabelClass).not('.' + opts.expandedDimLabelClass).each(function(){
855 | $table.find('.' + opts.dimLabelClass).each(function(){
856 |
857 | /*
858 | var cell = firstRow.cells[i];
859 | var $td = jQuery(cell);
860 | var $dimLabelDiv = jQuery(this);
861 | var newWidth = ($td.width())+ "px";
862 | $dimLabelDiv.css({width :newWidth});
863 | i++;
864 | //*/
865 | var $dimLabelDiv = jQuery(this);
866 | if($dimLabelDiv.hasClass(opts.expandedDimLabelClass)) {
867 | $dimLabelDiv.parent().css({width :'auto'});
868 | } else {
869 | var cell = firstRow.cells[i];
870 | var $td = jQuery(cell);
871 | // $dimLabelDiv.parent().css('width', '');
872 | $dimLabelDiv.css('width', 'auto');
873 | var newWidth = ($td.outerWidth())+ "px";
874 |
875 | if(i < firstRow.cells.length - 1) {
876 | var nextCell = firstRow.cells[i + 1];
877 | var $nextTd = jQuery(nextCell);
878 |
879 | var position = $td.position();
880 | var nextPosition = $nextTd.position();
881 | newWidth = nextPosition.left - position.left;
882 | // console.log("newWidth = " + newWidth);
883 | }
884 |
885 | $dimLabelDiv.parent().css({width :newWidth});
886 | i++;
887 | }
888 | });
889 | }
890 | }
891 |
892 | function syncRowsHeight($table, opts) {
893 | var $pivotDataTable = $table.find('.' + opts.div22Class + ' .' + opts.pivotDataTableClass);
894 | var pivotDataTable = $pivotDataTable[0];
895 | var firstRow = pivotDataTable.rows[0];
896 |
897 | var i = 0;
898 | $table.find('.' + opts.div21Class + ' .' + opts.dimLabelClass)/*.not('.' + opts.expandedDimLabelClass)*/.each(function(){
899 | var row = pivotDataTable.rows[i];
900 | var $tr = jQuery(row);
901 | var $dimLabelDiv = jQuery(this);
902 | var newHeight = ($tr.innerHeight() - 2)+ "px";
903 | $dimLabelDiv.css({height:newHeight});
904 | i++;
905 | });
906 | }
907 |
908 | function drawDataRows($table, $pivotDataTable, opts, context, curData) {
909 | var dimName = opts.horizontalDimensions[context.length];
910 | var newContext = clone(context);
911 |
912 | var dim = opts.dimensions[dimName];
913 | if(dim) {
914 | var onDataLoad = function(values) {
915 | for(var valIdx = 0; valIdx < values.length; valIdx++) {
916 | var value = values[valIdx];
917 | newContext[context.length] = value;
918 | var pivotDataTable = $pivotDataTable[0];
919 | var row = pivotDataTable.insertRow(-1);
920 | var $row = jQuery(row);
921 | $row.addClass(opts.dataRowClass + ' ' +
922 | opts.levelClassPrefix + context.length + ' ' + opts.pivotIdClassPrefix + value.id + ' ' +
923 | '" pivotId = "' + value.id);
924 |
925 | drawDataCells($table, $pivotDataTable, $row, opts, newContext, []);
926 |
927 | if(opts.isExpanded(newContext) && newContext.length < opts.horizontalDimensions.length) {
928 | drawDataRows($table, $pivotDataTable, opts, newContext, curData);
929 | if(dim.showTotal && false) {
930 | $pivotDataTable.append('' + 'Total ' + value.label + ' ')
934 | }
935 | }
936 | }
937 | $table.css({height:'10px'});
938 | $table.css({height:'auto'});
939 | syncDimensionsSizes($table, opts);
940 | }
941 | var values;
942 | if(dim.values) {
943 | values = dim.values(context, onDataLoad);
944 | } else {
945 | // curData = opts.dataProvider(opts, [], [opts.verticalDimensions[0], opts.horizontalDimensions[0]]);
946 | values = getDataValues(curData, context, dimName, dim.sortFieldName);
947 | }
948 | if(values != undefined) {
949 | onDataLoad(values);
950 | }
951 |
952 | }
953 | }
954 |
955 | function getDataValues(dimData, context, dimName, sortFieldName) {
956 | var items = [];
957 | // var dimData = opts.dimData ? opts.dimData : opts.data;
958 | for(var i = 0; i < dimData.length; i++) {
959 | var item = dimData[i];
960 | if(applyDataFilter(item, context)) {
961 | items.push(item);
962 | }
963 | }
964 | var res = [];
965 | var exist = {};
966 | for(var i = 0; i < items.length; i++) {
967 | var item = items[i];
968 | var apply = applyDataFilter(item, context);
969 | var value = item[dimName];
970 | var valueId = typeof(value) == 'object' ? value.id : value;
971 | if(value && value != Number.POSITIVE_INFINITY && exist[valueId] != true) {
972 | exist[valueId] = true;
973 | res.push(value);
974 | }
975 | }
976 |
977 | if(sortFieldName != undefined) {
978 | res = res.sort(function(o1, o2){
979 | if(o1[sortFieldName] < o2[sortFieldName])
980 | return -1;
981 | if(o1[sortFieldName] > o2[sortFieldName])
982 | return 1;
983 | return 0;
984 | });
985 | }
986 | return res;
987 | }
988 |
989 | function applyDataFilter(test, filter) {
990 | for(var key in filter) {
991 | var filterItem = filter[key];
992 | var dimName = filterItem.dimName;
993 | var o1 = filterItem.id;
994 | var testItem = test[dimName];
995 | if(testItem != undefined) {
996 | var o2;
997 | if(typeof testItem === "number") {
998 | o2 = testItem;
999 | } else if(typeof testItem === "string") {
1000 | o2 = testItem;
1001 | } else {
1002 | o2 = testItem.id;
1003 | }
1004 | if(o2 != null && o2 != undefined) {
1005 | if(o1 != o2 && o2 != Number.POSITIVE_INFINITY) {
1006 | return false;
1007 | }
1008 | }
1009 | }
1010 | }
1011 | return true;
1012 | }
1013 |
1014 | function applyDimDataFilter(test, filter) {
1015 | for(var key in filter) {
1016 | var filterItem = filter[key];
1017 | var dimName = filterItem.dimName;
1018 | var o1 = filterItem.id;
1019 | var testItem = test[dimName];
1020 | if(testItem != undefined) {
1021 | var o2 = testItem.id;
1022 | if(o2 != null && o2 != undefined) {
1023 | if(o1 != o2 && o2 != -1) {
1024 | return false;
1025 | }
1026 | }
1027 | }
1028 | }
1029 | return true;
1030 | }
1031 |
1032 |
1033 | /**
1034 | * The function adds data cells into certain row in pivot data table
1035 | */
1036 | function drawDataCells($table, $pivotDataTable, $row, opts, rowContext, colContext, curData) {
1037 | var dimName = opts.verticalDimensions[colContext.length];
1038 | var newContext = clone(colContext);
1039 |
1040 | var dim = opts.dimensions[dimName];
1041 | var rowValue = rowContext[rowContext.length - 1];
1042 | var row = $row[0];
1043 | if(dim) {
1044 | // var values = dim.values(colContext);
1045 | // var curData = opts.dataProvider(opts, [], [opts.verticalDimensions[0], opts.horizontalDimensions[0]]);// TODO
1046 | // opts.dataProvider()fffffffffff
1047 | var values = dim.values ? dim.values(colContext) : getDataValues(curData, colContext, dimName, dim.sortFieldName);
1048 | for(var valIdx = 0; valIdx < values.length; valIdx++) {
1049 | var value = values[valIdx];
1050 | newContext[colContext.length] = value;
1051 |
1052 | if(opts.isExpanded(newContext) && newContext.length < opts.verticalDimensions.length) {
1053 | drawDataCells($table, $pivotDataTable, $row, opts, rowContext, newContext);
1054 | if(dim.showTotal) {
1055 | var cell = row.insertCell(row.cells.length);
1056 | var $cell = jQuery(cell);
1057 | cell.className = opts.dataCellClass + " " + opts.dataTotalCellClass + " " +
1058 | opts.levelClassPrefix + colContext.length + " " + opts.pivotIdClassPrefix + value.id;
1059 | $cell.attr('pivotId', value.id);
1060 |
1061 | $cell.html('' + 'Total ' + value.label + ' ');
1062 | cell.rowContext = rowContext;
1063 | cell.colContext = colContext;
1064 | }
1065 | } else {
1066 | var cell = row.insertCell(row.cells.length);
1067 | var $cell = jQuery(cell);
1068 | $cell.addClass(opts.dataCellClass + " " + opts.levelClassPrefix + colContext.length +
1069 | " " + opts.pivotIdClassPrefix + value.id);
1070 | $cell.attr('pivotId', value.id);
1071 | var rowLabel = typeof(rowValue) == 'object' ? rowValue.label : rowValue;
1072 | $cell.html('' + rowLabel + ' - ' + rowLabel + ' ');
1073 | }
1074 | }
1075 | }
1076 | }
1077 |
1078 | /**
1079 | * Draws dimensions.
1080 | * @param $div - jQuery html element which is clicked and should be displayed or whole dimensions panel so root dimensions will be displayed
1081 | * @param opts - pivot table options
1082 | * @param dimensions - dimensions
1083 | * @param context - context
1084 | * @param curData - current data array
1085 | * @returns values which were added as dimension labels
1086 | */
1087 | function drawDimension($div, opts, dimensions, context, curData) {
1088 | var res;
1089 | if(!context) {
1090 | context = $div[0].pivotContext;
1091 | } else {
1092 | $div[0].pivotContext = clone(context);
1093 | }
1094 | var dimName = dimensions[context.length];
1095 | var newContext = clone(context);
1096 |
1097 | var dim = opts.dimensions[dimName];
1098 | var $totalDiv = $div.find('.' + opts.dimTotalCellClass);
1099 | if(dim) {
1100 | // var values = dim.values(context);
1101 | // var curData = opts.dataProvider(opts, [], [opts.verticalDimensions[0], opts.horizontalDimensions[0]]);// TODO
1102 | var values = dim.values ? dim.values(context) : getDataValues(curData, context, dimName, dim.sortFieldName);
1103 | res = values;
1104 | if(values.length > 0) {
1105 | $div.children('.' + opts.dimLabelClass).css({width: ''});
1106 | }
1107 | for(var valIdx = 0; valIdx < values.length; valIdx++) {
1108 | var value = values[valIdx];
1109 | var valueId = typeof(value) == 'object' ? value.id : value;
1110 | var valueLabel = typeof(value) == 'object' ? value.label : value;
1111 | value = typeof(value) == 'object' ? value : {id:value, label:value};
1112 | value.dimName = dimName;
1113 | newContext[context.length] = value;
1114 | var dimCellDiv = document.createElement('div');
1115 | if($totalDiv.size() > 0) {
1116 | dimCellDiv = $div[0].insertBefore(dimCellDiv, $totalDiv[0]);
1117 | } else {
1118 | dimCellDiv = $div[0].appendChild(dimCellDiv);
1119 | }
1120 | var $dimCellDiv = jQuery(dimCellDiv);
1121 | $dimCellDiv.addClass(opts.dimCellClass + " " + opts.dimCellClass + "-" + dimName + " " + opts.levelClassPrefix + context.length + " " +
1122 | opts.pivotIdClassPrefix + valueId);
1123 | $dimCellDiv.attr({
1124 | 'pivotId' : valueId,
1125 | 'dimName': dimName,
1126 | 'title':dim.label + " : " + unescape(valueLabel)
1127 | });
1128 | var cellHtml = opts.dimensionCellRenderer ? opts.dimensionCellRenderer(opts, newContext, false) : ""+ "" + valueLabel + "";
1130 | $dimCellDiv.append('' + cellHtml +
1134 | ' ');
1135 |
1136 | var $divLabel = $dimCellDiv.children('.' + opts.dimLabelClass);
1137 | dimCellDiv.pivotContext = clone(newContext);
1138 |
1139 | if(opts.isExpanded(newContext) && newContext.length < dimensions.length) {
1140 | $divLabel.addClass(opts.expandedDimLabelClass);
1141 | $divLabel.parent().addClass(opts.expandedDimCellClass);
1142 | var $childDiv = $div.children('.' + opts.pivotIdClassPrefix + valueId);
1143 | drawDimension($childDiv, opts, dimensions, newContext, curData);
1144 | } else {
1145 | if(newContext.length < dimensions.length) {
1146 | $divLabel.addClass(opts.collapsedDimLabelClass);
1147 | $divLabel.parent().addClass(opts.collapsedDimCellClass);
1148 | }
1149 | }
1150 | }
1151 |
1152 | // Show total column if it does not exist, if it's not top level and it's vertical
1153 | if($totalDiv.size() == 0 && context.length > 0 && dimensions == opts.verticalDimensions) {
1154 | var dimCellDiv = document.createElement('div');
1155 | dimCellDiv = $div[0].appendChild(dimCellDiv);
1156 | var $dimCellDiv = jQuery(dimCellDiv);
1157 | $dimCellDiv.addClass(opts.dimCellClass);
1158 | $dimCellDiv.addClass(opts.dimTotalCellClass);
1159 | $dimCellDiv.addClass(opts.levelClassPrefix + context.length);
1160 | // $dimCellDiv.addClass(opts.pivotIdClassPrefix + value.id);
1161 | // $dimCellDiv.attr('pivotId', value.id);
1162 | $dimCellDiv.attr('dimName', dimName);
1163 | dimCellDiv.pivotContext = clone(context);
1164 |
1165 | var cellHtml = opts.dimensionCellRenderer ? opts.dimensionCellRenderer(opts, newContext, true) : "";
1166 | $dimCellDiv.append('' + 'Total' + ' ');
1168 | }
1169 | }
1170 | return res;
1171 | }
1172 |
1173 | /**
1174 | * Synchronizes sizes and scroll position of fixed columns with pivot itself.
1175 | */
1176 | function syncScrollAndSize($table, opts) {
1177 | var scrollBarWidth = getScrollBarWidth();
1178 | var $div22 = $table.find('.' + opts.div22Class);
1179 |
1180 | if(!opts.autoSize) {
1181 | $table.find('.' + opts.div12Class).css({
1182 | 'width' : ($div22.width() - scrollBarWidth) + 'px'
1183 | });
1184 | }
1185 |
1186 | var newHeight = $div22.height() - scrollBarWidth;
1187 | if(!opts.autoSize) {
1188 | $table.find('.' + opts.div21Class).css({
1189 | 'height' : newHeight + 'px',
1190 | 'margin-bottom' : scrollBarWidth + 'px'
1191 | });
1192 | }
1193 | $table.find('.' + opts.div12Class).scrollLeft($div22.scrollLeft());
1194 | $table.find('.' + opts.div21Class).scrollTop($div22.scrollTop());
1195 | }
1196 |
1197 | $.fn.cypivot.defaults = {
1198 |
1199 | // Specifies if size of dimension sizes must be synced. Sometimes it should be false, if block sizes are equals
1200 | // and specified in CSS. In this case pivot table works faster.
1201 | syncDimensionCellSizes : true,
1202 |
1203 | //Specifies if pivot table should be resize when window is resized.
1204 | resizable : true,
1205 | resizableWidth : true,
1206 | resizableHeight : true,
1207 | autoSize : false,
1208 |
1209 | // Default classes
1210 | tableClass : 'cypivot',
1211 | topRowClass : 'top-row',
1212 | bottomRowClass : 'bottom-row',
1213 | cell11Class : 'cell11',
1214 | cell12Class : 'cell12',
1215 | cell21Class : 'cell21',
1216 | cell22Class : 'cell22',
1217 |
1218 | div11Class : 'div11',
1219 | div12Class : 'div12',
1220 | div21Class : 'div21',
1221 | div22Class : 'div22',
1222 |
1223 | pivotDataTableClass : 'pivot-data-table',
1224 | dimLabelClass : 'dim-label',
1225 | dimCellIconClass : 'dim-cell-icon',
1226 |
1227 | dimCellClass : 'dim-cell',
1228 | expandableDimLabelClass : 'expandable-dim-label',
1229 | expandedDimLabelClass : 'expanded-dim-label',
1230 | collapsedDimLabelClass : 'collapsed-dim-label',
1231 | expandedDimCellClass : 'expanded-dim-cell',
1232 | collapsedDimCellClass : 'collapsed-dim-cell',
1233 | dimTotalCellClass : 'dim-total-cell',
1234 | dataTotalCellClass : 'data-total-cell',
1235 | levelClassPrefix : 'level-',
1236 |
1237 | dataRowClass : 'data-row',
1238 | dataCellClass : 'data-cell',
1239 | divDataCellClass : 'div-data-cell',
1240 | configDialogClass : 'config-dialog',
1241 |
1242 | dimensionListTitle : 'Dimensions',
1243 | horizontalDimensionListTitle : 'Rows',
1244 | verticalDimensionListTitle : 'Columns',
1245 | filterDimensionListTitle : 'Filters',
1246 |
1247 | configWindowActivatedClass : 'config-window-activated',
1248 | dimensionListClass : 'dimension-list',
1249 | firstDimensionListClass : 'first-dimension-list',
1250 | dimensionListTitleClass : 'dimension-list-title',
1251 | verticalDimensionListClass : 'vertical-dimension-list',
1252 | horizontalDimensionListClass: 'horizontal-dimension-list',
1253 | filterDimensionListClass : 'filter-dimension-list',
1254 |
1255 | pivotIdClassPrefix : 'pivot-id-',
1256 | pivotConfigDialogId : 'pivot-config-dialog',
1257 |
1258 | isExpanded : function(context){
1259 | return context.length == 0;
1260 | },
1261 |
1262 | configuration : {
1263 | horizontalDimensions : true,
1264 | verticalDimensions : true,
1265 | filterDimensions : false,
1266 | },
1267 |
1268 | configLabel : 'Config',
1269 |
1270 | cookiePrefix : 'cy-pivot-',
1271 | storeDimConfig : true,
1272 |
1273 | dataCellRenderer : function(items, colContext, rowContext, opts) {
1274 |
1275 | var value = "";
1276 | for(var i = 0; i < opts.valueDataFields.length; i++) {
1277 | var valueDataField = opts.valueDataFields[i];
1278 | value = value + "" + items['default'].sum[valueDataField] + " ";
1279 | }
1280 | return value;
1281 | },
1282 |
1283 | dataProvider : // null,
1284 | function(opts, context, visibleDims)
1285 | {
1286 | return opts.data;
1287 | },
1288 |
1289 | dimensionCellRenderer : null // This function(opts, context, isTotal) should render dimension cell
1290 | /* Example
1291 | function(opts, context, isTotal) {
1292 | return '' + context[context.length - 1].label + '';
1293 | }*/
1294 | ,
1295 |
1296 | dimensions : {
1297 | dim1 :
1298 | {
1299 | label :'Colors',
1300 | values : function(context) {
1301 | return [{id:1, label:'Red'}, {id:2, label:'Blue'}, {id:3, label:'Green'}];
1302 | },
1303 | showTotal : true,
1304 | },
1305 | dim2 :
1306 | {
1307 | label :'Cities',
1308 | values : function(context) {
1309 | return [{id:1, label:'Saint-Petersburg'}, {id:2, label:'Moscow'}, {id:3, label:'London'}, {id:4, label:'Paris'}];
1310 | },
1311 | showTotal : true,
1312 | },
1313 | dim3 :
1314 | {
1315 | label :'Shapes',
1316 | values : function(context) {
1317 | return [{id:1, label:'Round'}, {id:2, label:'Square'}, {id:3, label:'Star'}, {id:4, label:'Ellipse'}];
1318 | },
1319 | showTotal : true,
1320 | },
1321 | dim4 :
1322 | {
1323 | label :'Planets',
1324 | values : function(context) {
1325 | return [{id:1, label:'Earth'}, {id:2, label:'Moon'}, {id:3, label:'Mars'}, {id:4, label:'Neptune'}];
1326 | },
1327 | showTotal : true,
1328 | },
1329 | dim5 :
1330 | {
1331 | label :'Geo',
1332 | values : function(context) {
1333 | return [{id:1, label:'Asia'}, {id:2, label:'Africa'}, {id:3, label:'Europe'}, {id:4, label:'America'}];
1334 | },
1335 | showTotal : true,
1336 | },
1337 | dim6 :
1338 | {
1339 | label :'Lessons',
1340 | values : function(context) {
1341 | return [{id:1, label:'Phisics'}, {id:2, label:'Chemistry'}, {id:3, label:'Math'}, {id:4, label:'Geography'}];
1342 | },
1343 | showTotal : true,
1344 | },
1345 | },
1346 |
1347 | horizontalDimensions: ['dim1', 'dim3', 'dim5'],
1348 | // verticalDimensions : ['dim2', 'dim4', 'dim6'],
1349 | // horizontalDimensions: ['dim1'],
1350 | verticalDimensions : ['dim2'],
1351 | filterDimensions : [],
1352 |
1353 | data : [
1354 | {
1355 | dim1 : 'Red',
1356 | dim2 : 'Saint-Petersburg',
1357 | dim3 : 'Round',
1358 | dim4 : 'Earth',
1359 | dim5 : 'Asia',
1360 | dim6 : 'Phisics',
1361 | value : 1,
1362 | },
1363 | {
1364 | dim1 : 'Red',
1365 | dim2 : 'Saint-Petersburg',
1366 | dim3 : 'Round',
1367 | dim4 : 'Earth',
1368 | dim5 : 'Asia',
1369 | dim6 : 'Chemistry',
1370 | value : 1,
1371 | },
1372 | {
1373 | dim1 : 'Blue',
1374 | dim2 : 'Saint-Petersburg',
1375 | dim3 : 'Round',
1376 | dim4 : 'Earth',
1377 | dim5 : 'Asia',
1378 | dim6 : 'Chemistry',
1379 | value : 1,
1380 | },
1381 | {
1382 | dim1 : 'Green',
1383 | dim2 : 'Moscow',
1384 | dim3 : 'Round',
1385 | dim4 : 'Earth',
1386 | dim5 : 'Asia',
1387 | dim6 : 'Chemistry',
1388 | value : 1,
1389 | },
1390 | ],
1391 |
1392 | map : function(rowContext, colContext, data) {
1393 | var res = [];
1394 | var strictedItems = [];
1395 | /*
1396 | var filter = {};
1397 | for(var i = 0; i < rowContext.length; i++) {
1398 | var value = rowContext[i];
1399 | filter[value.dimName] = value;
1400 | }
1401 | for(var i = 0; i < colContext.length; i++) {
1402 | var value = colContext[i];
1403 | filter[value.dimName] = value;
1404 | }
1405 | */
1406 | var filter = [];
1407 | for(var i = 0; i < rowContext.length; i++) {
1408 | var value = rowContext[i];
1409 | filter.push(value);
1410 | }
1411 | for(var i = 0; i < colContext.length; i++) {
1412 | var value = colContext[i];
1413 | filter.push(value);
1414 | }
1415 |
1416 | for(var i = 0; i < data.length; i++) {
1417 | var item = data[i];
1418 | if(applyFilter2(item, filter)) {
1419 | res.push(item);
1420 | }
1421 | //*
1422 | if(strictApplyFilter(this, item, filter)) {
1423 | strictedItems[strictedItems.length] = item;
1424 | }
1425 | //*/
1426 |
1427 | }
1428 | return {
1429 | 'default':res,
1430 | stricted:strictedItems
1431 | };
1432 | },
1433 |
1434 | valueDataFields : ['value'],
1435 |
1436 | /* Reduces is an array of objects. Each object specifies what 'map' items it requires and it puts result(s) into reduces map.
1437 | * So the only reduce function can calculate 'sum', 'max', 'min', 'avg', 'count' etc. values.
1438 | */
1439 | reduce : function(mapItems) {
1440 | var reduces = {};
1441 |
1442 | for(itemsKey in mapItems) {
1443 | var items = mapItems[itemsKey];
1444 | var sum = {};
1445 | var count = {};
1446 | var max = {}, min = {};
1447 |
1448 | /*
1449 | for(var i = 0; i < this.valueDataFields.length; i++) {
1450 | var valueDataField = this.valueDataFields[i];
1451 | sum[valueDataField] = 0;
1452 | count[valueDataField] = items.length;
1453 | }
1454 | */
1455 |
1456 | for(var j = 0; j < this.valueDataFields.length; j++) {
1457 | var valueDataField = this.valueDataFields[j];
1458 | var curSum = 0;
1459 | var curMax = Number.NEGATIVE_INFINITY
1460 | var curMin = Number.POSITIVE_INFINITY
1461 | for(var i = 0; i < items.length; i++) {
1462 | var item = items[i];
1463 | var itemValue = item[valueDataField];
1464 |
1465 | curSum += itemValue;
1466 | if(curMin > itemValue) {
1467 | curMin = itemValue;
1468 | }
1469 | if(curMax < itemValue) {
1470 | curMax = itemValue;
1471 | }
1472 | }
1473 | sum[valueDataField] = curSum;
1474 | max[valueDataField] = curMax;
1475 | min[valueDataField] = curMin;
1476 |
1477 | }
1478 | /*
1479 | *
1480 | for(var i = 0; i < items.length; i++) {
1481 | var item = items[i];
1482 | for(var j = 0; j < this.valueDataFields.length; j++) {
1483 | var valueDataField = this.valueDataFields[j];
1484 | var itemValue = item[valueDataField];
1485 | if(isNumber(itemValue)) {
1486 | sum[valueDataField] += itemValue;
1487 | var curMin = min[valueDataField];
1488 | if(curMin) {
1489 | if(curMin > itemValue) {
1490 | min[valueDataField] = itemValue;
1491 | }
1492 | } else {
1493 | min[valueDataField] = itemValue;
1494 | }
1495 | var curMax = max[valueDataField];
1496 | if(curMax) {
1497 | if(curMax > itemValue) {
1498 | max[valueDataField] = itemValue;
1499 | }
1500 | } else {
1501 | max[valueDataField] = itemValue;
1502 | }
1503 | }
1504 | }
1505 | }
1506 | */
1507 | reduces[itemsKey] = {};
1508 | reduces[itemsKey]['sum'] = sum;
1509 | reduces[itemsKey]['count'] = items.length;
1510 | reduces[itemsKey]['avg'] = sum / items.length;
1511 | reduces[itemsKey]['max'] = max;
1512 | reduces[itemsKey]['min'] = min;
1513 | }
1514 | return reduces;
1515 | },
1516 |
1517 | reduces : [
1518 | {
1519 | valueDataFields : ['value'],
1520 | map : 'default',
1521 | reduce : function(items, reduces) {
1522 | var sum = {};
1523 | var count = {};
1524 | for(var i = 0; i < this.valueDataFields.length; i++) {
1525 | var valueDataField = this.valueDataFields[i];
1526 | sum[valueDataField] = 0;
1527 | count[valueDataField] = items.length;
1528 | }
1529 | var max = {}, min = {};
1530 | for(var i = 0; i < items.length; i++) {
1531 | var item = items[i];
1532 | for(var j = 0; j < this.valueDataFields.length; j++) {
1533 | var valueDataField = this.valueDataFields[j];
1534 | sum[valueDataField] += item[valueDataField];
1535 | if(min[valueDataField]) {
1536 | if(min[valueDataField] > item[valueDataField]) {
1537 | min[valueDataField] = item[valueDataField];
1538 | }
1539 | } else {
1540 | min[valueDataField] = item[valueDataField];
1541 | }
1542 | if(max[valueDataField]) {
1543 | if(max[valueDataField] > item[valueDataField]) {
1544 | max[valueDataField] = item[valueDataField];
1545 | }
1546 | } else {
1547 | max[valueDataField] = item[valueDataField];
1548 | }
1549 | }
1550 | }
1551 | if(reduces) {
1552 | reduces['sum'] = sum;
1553 | reduces['count'] = items.length;
1554 | reduces['avg'] = sum / items.length;
1555 | reduces['max'] = max;
1556 | reduces['min'] = min;
1557 | }
1558 | return sum;
1559 | }
1560 | },
1561 | ],
1562 | };
1563 |
1564 | function clone(o) {
1565 | if(!o || 'object' !== typeof o) {
1566 | return o;
1567 | }
1568 | var c = 'function' === typeof o.pop ? [] : {};
1569 | var p, v;
1570 | for(p in o) {
1571 | if(o.hasOwnProperty(p)) {
1572 | v = o[p];
1573 | if(v && 'object' === typeof v) {
1574 | c[p] = clone(v);
1575 | }
1576 | else {
1577 | c[p] = v;
1578 | }
1579 | }
1580 | }
1581 | return c;
1582 | }
1583 |
1584 | function applyFilter(test, filter) {
1585 | for(var key in filter) {
1586 | var filterItem = filter[key];
1587 | // var dimName = filterItem.dimName;
1588 | // var o1 = filterItem.id;
1589 | var o2 = test[filterItem.dimName];
1590 | //if(o1 != Number.POSITIVE_INFINITY) {
1591 | if(filterItem.id != o2) {// && o2 != -1) {
1592 | return false;
1593 | }
1594 | //}
1595 | }
1596 | return true;
1597 | }
1598 |
1599 | function applyFilter2(test, filter) {
1600 | for(var i = 0; i < filter.length; i++) {
1601 | var filterItem = filter[i];
1602 | // var dimName = filterItem.dimName;
1603 | // var o1 = filterItem.id;
1604 | var o2 = test[filterItem.dimName];
1605 | if(typeof(o2) == "object" && o2 != null) {
1606 | o2 = o2.id;
1607 | }
1608 | //if(o1 != Number.POSITIVE_INFINITY) {
1609 | if(filterItem.id != o2) {// && o2 != -1) {
1610 |
1611 | return false;
1612 | }
1613 | //}
1614 | }
1615 | return true;
1616 | }
1617 |
1618 | /**
1619 | * This function check if the test value contain ONLY filter values (so it's not on sublevel- it's on the same level)
1620 | * @param test
1621 | * @param filter
1622 | * @returns {Boolean}
1623 | */
1624 | function strictApplyFilter(opts, test, filter) {
1625 | var testFilter = {};
1626 | for(var key in filter) {
1627 | var filterItem = filter[key];
1628 | var dimName = filterItem.dimName;
1629 | var o1 = filterItem.id;
1630 | var o2 = test[dimName];
1631 | if(o1 != o2) {
1632 | return false;
1633 | }
1634 | testFilter[dimName] = o1;
1635 | }
1636 | for(var key in opts.dimensions) {
1637 | if(testFilter[key] == undefined) {
1638 | if(test[key] != undefined)
1639 | return false;
1640 | }
1641 | }
1642 | return true;
1643 | }
1644 |
1645 | /**
1646 | * Calculate width of scroll bar
1647 | */
1648 | function getScrollBarWidth () {
1649 | var inner = document.createElement('p');
1650 | inner.style.width = "100%";
1651 | inner.style.height = "200px";
1652 |
1653 | var outer = document.createElement('div');
1654 | outer.style.position = "absolute";
1655 | outer.style.top = "0px";
1656 | outer.style.left = "0px";
1657 | outer.style.visibility = "hidden";
1658 | outer.style.width = "200px";
1659 | outer.style.height = "150px";
1660 | outer.style.overflow = "hidden";
1661 | outer.appendChild (inner);
1662 |
1663 | document.body.appendChild (outer);
1664 | var w1 = inner.offsetWidth;
1665 | outer.style.overflow = 'scroll';
1666 | var w2 = inner.offsetWidth;
1667 | if (w1 == w2)
1668 | w2 = outer.clientWidth;
1669 |
1670 | document.body.removeChild (outer);
1671 |
1672 | return (w1 - w2);
1673 | }
1674 |
1675 | function doResizeWidth($table) {
1676 | var left = $table.find('.div22').offset().left;
1677 | $table.find('.div22').css({
1678 | width:(window.innerWidth - left) + 'px',
1679 | });
1680 | $table.find('.div12').css({
1681 | width:(window.innerWidth - left ) + 'px',
1682 | });
1683 | }
1684 |
1685 | function doResizeHeight($table) {
1686 | var top = $table.find('.div22').offset().top;
1687 | $table.find('.div22').css({
1688 | height:(window.innerHeight - top) + 'px',
1689 | });
1690 | $table.find('.div21').css({
1691 | height:(window.innerHeight - top) + 'px',
1692 | });
1693 | }
1694 |
1695 | function isNumber(o) {
1696 | return typeof o === 'number' && isFinite(o);
1697 | }
1698 |
1699 | // Checks if c2 is subcontext for c1 (all fields from c1 are equals to fields in c2)
1700 | function isSubContext(c1, c2) {
1701 | if(c2.length < c1.length) {
1702 | return false;
1703 | }
1704 | for(var i = 0; i < c1.length; i++) {
1705 | if(c1[i].id != c2[i].id)
1706 | return false;
1707 | }
1708 | return true;
1709 | }
1710 |
1711 | function hasAllDims(allDims, dims) {
1712 | dims = dims.split(";");
1713 | for(var i = 0; i < dims.length; i++) {
1714 | var dimName = dims[i]; //.trim();
1715 | var value = allDims[dimName];
1716 | if(value == undefined) {
1717 | return false;
1718 | }
1719 | }
1720 | return true;
1721 | }
1722 |
1723 | })( jQuery );
--------------------------------------------------------------------------------
/js/jquery.cy-pivot.min.js:
--------------------------------------------------------------------------------
1 | (function(B){var C={init:function(W){var Y=B.extend({},B.fn.cypivot.defaults,W);var V=this;if(Y.resizable){B(window).resize(function(){if(Y.resizableWidth){d(V)}if(Y.resizableHeight){U(V)}})}var X=this.each(function(){var ad=B(this);ad.data("cypivot",{target:ad,options:Y});if(Y.cookiePrefix&&Y.storeDimConfig){var ac=B.cookie(Y.cookiePrefix+"horizontalDims");var aa=B.cookie(Y.cookiePrefix+"verticalDims");var ab=B.cookie(Y.cookiePrefix+"filterDims");if(ac&&m(Y.dimensions,ac)&&m(Y.dimensions,aa)){Y.horizontalDimensions=ac.split(";")}if(aa&&m(Y.dimensions,ac)&&m(Y.dimensions,aa)){Y.verticalDimensions=aa.split(";")}if(ab&&m(Y.dimensions,ab)&&m(Y.dimensions,ab)){Y.filterDimensions=ab.split(";")}}var Z=''+Y.configLabel+" ";if(!Y.configuration){Z=""}ad.html(' | '+Z+' | | | | ');ad.find("."+Y.div22Class).on("scroll",function(){M(ad,Y)});ad.find("."+Y.cell22Class).resize(function(){M(ad,Y)});ad.find("."+Y.div11Class).on("click",function(){h(ad,Y)});H(ad,Y);ad.find("#"+Y.pivotConfigDialogId).dialog({modal:false,title:"Pivot Table Configuration",position:["right","50px"],beforeClose:function(){var ae=ad.find("."+Y.div11Class);ae.removeClass(Y.configWindowActivatedClass)}});jQuery("#"+Y.pivotConfigDialogId).dialog("close");M(ad,Y);o(ad,[],[Y.verticalDimensions[0],Y.horizontalDimensions[0]],0,0,Y);w(ad,Y)});if(Y.resizable){if(Y.resizableWidth){d(V)}if(Y.resizableHeight){U(V)}}return X},options:function(W,V){var Y=B(this);var X=Y.data("cypivot");return X.options},reload:function(W,V){return this.each(function(){var ac=B(this),ab=ac.data("cypivot");if(W){ab.options.data=W}if(V){var X=ac.find("."+ab.options.div22Class+" ."+ab.options.pivotDataTableClass);var Z=X[0];var ad;for(var Y=0;Y '+W.verticalDimensionListTitle+"";for(var ab=0;ab'+ac.label+""}if(!W.configuration||!W.configuration.verticalDimensions){ai=""}var ad=''+W.horizontalDimensionListTitle+"";for(var ab=0;ab'+ac.label+""}if(!W.configuration||!W.configuration.horizontalDimensions){var ad=""}var V=''+W.filterDimensionListTitle+"";for(var ab=0;ab"+ae.label+""}Z=Z+"";V=V+''+ac.label+Z+""}if(!W.configuration||!W.configuration.filterDimensions){V=""}var aa="";for(var ah in W.dimensions){if(ag[ah]!=true){var ac=W.dimensions[ah];aa=aa+''+ac.label+""}}X.append('");X.find("ul."+W.dimensionListClass).sortable({cancel:"."+W.dimensionListTitleClass,update:function(){var an=[],ap=[],ao=[],al=[];X.find("."+W.dimensionListClass+" li").each(function(){var ar=jQuery(this).attr("dim");if(ar){al[al.length]=ar}if(jQuery(this).attr("vdims")=="true"){al=an}if(jQuery(this).attr("hdims")=="true"){al=ap}if(jQuery(this).attr("fdims")=="true"){al=ao}});if(W.configuration&&W.configuration.verticalDimensions==true){W.verticalDimensions=an}if(W.configuration&&W.configuration.horizontalDimensions==true){W.horizontalDimensions=ap}if(W.configuration&&W.configuration.filterDimensions==true){W.filterDimensions=ao}if(W.cookiePrefix&&W.storeDimConfig){var aq=W.horizontalDimensions.join(";");var ak=W.verticalDimensions.join(";");var am=W.filterDimensions.join(";");B.cookie(W.cookiePrefix+"horizontalDims",aq,{expires:15});B.cookie(W.cookiePrefix+"verticalDims",ak,{expires:15});B.cookie(W.cookiePrefix+"filterDims",am,{expires:15})}f(aj,W)}})}function h(W,X){if(X.configuration){var V=W.find("."+X.div11Class);V.toggleClass(X.configWindowActivatedClass);if(V.hasClass(X.configWindowActivatedClass)){jQuery("#"+X.pivotConfigDialogId).dialog("open")}else{var Y=jQuery("#"+X.pivotConfigDialogId);Y.dialog("close")}}}function b(V,X){var Z;if(V.hasClass(X.levelClassPrefix+"0")){Z=V.parent()}else{Z=V.parents("."+X.levelClassPrefix+"0").parent()}var W=0;var Y=false;Z.find("."+X.dimLabelClass).each(function(){if(!Y){var aa=V[0];if(this==aa){Y=true;return false}else{var ab=B(this);if(ab.parent().children("."+X.dimCellClass).size()==0){W++}}}});return W}function P(V,X){var Z;if(V.hasClass(X.levelClassPrefix+"0")){Z=V.parent()}else{Z=V.parents("."+X.levelClassPrefix+"0").parent()}var W=0;var Y=false;Z.find("."+X.dimLabelClass).each(function(){if(!Y){var aa=V[0];if(this==aa){Y=true;return false}else{var ab=B(this);W++}}});return W}function c(V,W){var X=[];V.find("."+W.div21Class+" ."+W.dimCellClass).each(function(){X[X.length]=this.pivotContext});return X}function L(V,W){var X=[];V.find("."+W.div12Class+" ."+W.dimCellClass).not("."+W.expandedDimCellClass).each(function(){X[X.length]=this.pivotContext});return X}function p(V,Y){var Z=V.parent();var X=0;var W=V[0];Z.find("."+Y.dimLabelClass).each(function(){var aa=B(this);if(aa.parent().children("."+Y.dimCellClass).size()==0){X++}});return X}function I(V,Y){var Z=V.parent();var X=0;var W=V[0];X=Z.find("."+Y.dimLabelClass).not(W).size();return X}function f(X,Y){var V=X.find("."+Y.div21Class);V.html("");var Z=X.find("."+Y.div12Class);Z.html("");var W=X.find("."+Y.div22Class);W.html('');o(X,[],[Y.verticalDimensions[0],Y.horizontalDimensions[0]],0,0,Y)}function F(V,X,W){$pivotDataTable=V.find("."+X.div22Class+" ."+X.pivotDataTableClass);$pivotDataTable.html("");i(V,$pivotDataTable,X,[],W);A(V,X);n(V,X)}function w(V,W){V.on("click","."+W.div12Class+" ."+W.dimLabelClass,function(aj){var ae=V.find("."+W.div22Class+" ."+W.pivotDataTableClass);var ac=new Date();var ab,an;var aa=B(this);var ai=false;if(aa.hasClass(W.expandedDimLabelClass)){var al=p(aa,W);if(al>0){var ao=b(aa,W);var am=ae[0];var Y=N(am,ao,al-1);k(am,ao,al-1,function(){aa.parent().find("."+W.dimCellClass).remove();aa.width(Y+"px");var aq=-1;for(var ar=0;ar0){aa.addClass(W.expandedDimLabelClass).removeClass(W.collapsedDimLabelClass);aa.parent().addClass(W.expandedDimCellClass).removeClass(W.collapsedDimCellClass);if(aq>0){R(ae[0],W,af,aq-1,ar)}ai=true}n(V,W);ab=W.onExpand};var X=a(ah,W.verticalDimensions);var ak=q(V,W);var Z=G(V,W);if(ah.length==Z){ak.push(W.verticalDimensions[ah.length])}var ap=W.dataProvider(W,X,ak,ad);if(ap){ad(ap)}}}if(ai){A(V,W);if(W.resizable){if(W.resizableWidth){d(V)}if(W.resizableHeight){U(V)}}if(an){an(this)}if(ab){ab(this)}n(V,W)}return false});V.on("click","."+W.div21Class+" ."+W.dimLabelClass,function(aj){var ae=new Date();var ac,an;if(aj.isPropagationStopped()){return}var ab=B(this);var ag=ab.parent();var ai=false;if(ab.hasClass(W.expandedDimLabelClass)){var al=I(ab,W);var X=P(ab,W);var am=$pivotDataTable[0];if(al>0){x(am,X+1,al);ag.find("."+W.dimCellClass).remove();ab.removeClass(W.expandedDimLabelClass);ab.addClass(W.collapsedDimLabelClass);ag.removeClass(W.expandedDimCellClass);ag.addClass(W.collapsedDimCellClass);ai=true}an=W.onCollapse}else{if(ab.hasClass(W.collapsedDimLabelClass)){var ah=this.parentElement.pivotContext;var Y=P(ab,W);var af=function(aq){J(ag,W,W.horizontalDimensions,null,aq);ab.addClass(W.expandedDimLabelClass).removeClass(W.collapsedDimLabelClass);ag.addClass(W.expandedDimCellClass).removeClass(W.collapsedDimCellClass);var ap=I(ab,W);if(ap>0){K($pivotDataTable[0],W,Y+1,ap,aq);ai=true}n(V,W);ac=W.onExpand};var Z=a(ah,W.horizontalDimensions);var ak=q(V,W);var aa=g(V,W);if(ah.length==aa){ak.push(W.horizontalDimensions[ah.length])}var ao=W.dataProvider(W,Z,ak,af);if(ao){af(ao)}ac=W.onExpand}}if(ai){if(W.resizable){if(W.resizableWidth){d(V)}if(W.resizableHeight){U(V)}}A(V,W);if(an){an(this)}if(ac){ac(this)}n(V,W)}var ad=new Date();return false})}function a(Y,X){var W={};for(var V=0;V0){var am=B("#cellTemplate").html();ad=_.template(am,{items:ab,rowContext:Y,colContext:af,options:ah})}}jQuery(V).html(''+ad+" ");V.isCalculated=true}}}}function j(W){var X="[";for(var V=0;V0){X=X+", "}X=X+Y.label}X=X+"]";return X}function R(ak,ag,al,am,W){var ad=B(ak);var aj=c(ad.parents(".cypivot"),ag);var aa=L(ad.parents(".cypivot"),ag);for(var Y=0;Y0?al.rows[0]:null;for(var X=0;X'+am+" ")}}jQuery(aa).html(ae.join(""))}}function k(Z,ac,aa,Y){for(var X=0;XTotal '+aj.label+" ")}}}ae.css({height:"10px"});ae.css({height:"auto"});n(ae,V)};var ad;if(aa.values){ad=aa.values(X,W)}else{ad=y(ac,X,Z,aa.sortFieldName)}if(ad!=undefined){W(ad)}}}function y(ad,W,Y,V){var ab=[];for(var Z=0;Zah[V]){return 1}return 0})}return aa}function v(ac,X){for(var W in X){var aa=X[W];var ab=aa.dimName;var Z=aa.id;var V=ac[ab];if(V!=undefined){var Y;if(typeof V==="number"){Y=V}else{if(typeof V==="string"){Y=V}else{Y=V.id}}if(Y!=null&&Y!=undefined){if(Z!=Y&&Y!=Number.POSITIVE_INFINITY){return false}}}}return true}function t(ac,X){for(var W in X){var aa=X[W];var ab=aa.dimName;var Z=aa.id;var V=ac[ab];if(V!=undefined){var Y=V.id;if(Y!=null&&Y!=undefined){if(Z!=Y&&Y!=-1){return false}}}}return true}function D(ae,ah,ak,ai,Y,ag,V){var ad=ai.verticalDimensions[ag.length];var Z=s(ag);var al=ai.dimensions[ad];var am=Y[Y.length-1];var ab=ak[0];if(al){var X=al.values?al.values(ag):y(V,ag,ad,al.sortFieldName);for(var ac=0;acTotal '+aj.label+"");W.rowContext=Y;W.colContext=ag}}else{var W=ab.insertCell(ab.cells.length);var aa=jQuery(W);aa.addClass(ai.dataCellClass+" "+ai.levelClassPrefix+ag.length+" "+ai.pivotIdClassPrefix+aj.id);aa.attr("pivotId",aj.id);var af=typeof(am)=="object"?am.label:am;aa.html(''+af+" - "+af+" ")}}}}function J(am,ah,ac,Z,V){var ao;if(!Z){Z=am[0].pivotContext}else{am[0].pivotContext=s(Z)}var ag=ac[Z.length];var aa=s(Z);var ak=ah.dimensions[ag];var Y=am.find("."+ah.dimTotalCellClass);if(ak){var X=ak.values?ak.values(Z):y(V,Z,ag,ak.sortFieldName);ao=X;if(X.length>0){am.children("."+ah.dimLabelClass).css({width:""})}for(var ae=0;ae0){al=am[0].insertBefore(al,Y[0])}else{al=am[0].appendChild(al)}var W=jQuery(al);W.addClass(ah.dimCellClass+" "+ah.dimCellClass+"-"+ag+" "+ah.levelClassPrefix+Z.length+" "+ah.pivotIdClassPrefix+af);W.attr({pivotId:af,dimName:ag,title:ak.label+" : "+unescape(ad)});var an=ah.dimensionCellRenderer?ah.dimensionCellRenderer(ah,aa,false):""+ad+"";W.append(''+an+" ");var ai=W.children("."+ah.dimLabelClass);al.pivotContext=s(aa);if(ah.isExpanded(aa)&&aa.length0&&ac==ah.verticalDimensions){var al=document.createElement("div");al=am[0].appendChild(al);var W=jQuery(al);W.addClass(ah.dimCellClass);W.addClass(ah.dimTotalCellClass);W.addClass(ah.levelClassPrefix+Z.length);W.attr("dimName",ag);al.pivotContext=s(Z);var an=ah.dimensionCellRenderer?ah.dimensionCellRenderer(ah,aa,true):"";W.append('Total ')}}return ao}function M(X,Y){var Z=u();var W=X.find("."+Y.div22Class);if(!Y.autoSize){X.find("."+Y.div12Class).css({width:(W.width()-Z)+"px"})}var V=W.height()-Z;if(!Y.autoSize){X.find("."+Y.div21Class).css({height:V+"px","margin-bottom":Z+"px"})}X.find("."+Y.div12Class).scrollLeft(W.scrollLeft());X.find("."+Y.div21Class).scrollTop(W.scrollTop())}B.fn.cypivot.defaults={syncDimensionCellSizes:true,resizable:true,resizableWidth:true,resizableHeight:true,autoSize:false,tableClass:"cypivot",topRowClass:"top-row",bottomRowClass:"bottom-row",cell11Class:"cell11",cell12Class:"cell12",cell21Class:"cell21",cell22Class:"cell22",div11Class:"div11",div12Class:"div12",div21Class:"div21",div22Class:"div22",pivotDataTableClass:"pivot-data-table",dimLabelClass:"dim-label",dimCellIconClass:"dim-cell-icon",dimCellClass:"dim-cell",expandableDimLabelClass:"expandable-dim-label",expandedDimLabelClass:"expanded-dim-label",collapsedDimLabelClass:"collapsed-dim-label",expandedDimCellClass:"expanded-dim-cell",collapsedDimCellClass:"collapsed-dim-cell",dimTotalCellClass:"dim-total-cell",dataTotalCellClass:"data-total-cell",levelClassPrefix:"level-",dataRowClass:"data-row",dataCellClass:"data-cell",divDataCellClass:"div-data-cell",configDialogClass:"config-dialog",dimensionListTitle:"Dimensions",horizontalDimensionListTitle:"Rows",verticalDimensionListTitle:"Columns",filterDimensionListTitle:"Filters",configWindowActivatedClass:"config-window-activated",dimensionListClass:"dimension-list",firstDimensionListClass:"first-dimension-list",dimensionListTitleClass:"dimension-list-title",verticalDimensionListClass:"vertical-dimension-list",horizontalDimensionListClass:"horizontal-dimension-list",filterDimensionListClass:"filter-dimension-list",pivotIdClassPrefix:"pivot-id-",pivotConfigDialogId:"pivot-config-dialog",isExpanded:function(V){return V.length==0},configuration:{horizontalDimensions:true,verticalDimensions:true,filterDimensions:false},configLabel:"Config",cookiePrefix:"cy-pivot-",storeDimConfig:true,dataCellRenderer:function(V,ab,Z,Y){var aa="";for(var W=0;W"+V["default"].sum[X]+" "}return aa},dataProvider:function(X,W,V){return X.data},dimensionCellRenderer:null,dimensions:{dim1:{label:"Colors",values:function(V){return[{id:1,label:"Red"},{id:2,label:"Blue"},{id:3,label:"Green"}]},showTotal:true},dim2:{label:"Cities",values:function(V){return[{id:1,label:"Saint-Petersburg"},{id:2,label:"Moscow"},{id:3,label:"London"},{id:4,label:"Paris"}]},showTotal:true},dim3:{label:"Shapes",values:function(V){return[{id:1,label:"Round"},{id:2,label:"Square"},{id:3,label:"Star"},{id:4,label:"Ellipse"}]},showTotal:true},dim4:{label:"Planets",values:function(V){return[{id:1,label:"Earth"},{id:2,label:"Moon"},{id:3,label:"Mars"},{id:4,label:"Neptune"}]},showTotal:true},dim5:{label:"Geo",values:function(V){return[{id:1,label:"Asia"},{id:2,label:"Africa"},{id:3,label:"Europe"},{id:4,label:"America"}]},showTotal:true},dim6:{label:"Lessons",values:function(V){return[{id:1,label:"Phisics"},{id:2,label:"Chemistry"},{id:3,label:"Math"},{id:4,label:"Geography"}]},showTotal:true}},horizontalDimensions:["dim1","dim3","dim5"],verticalDimensions:["dim2"],filterDimensions:[],data:[{dim1:"Red",dim2:"Saint-Petersburg",dim3:"Round",dim4:"Earth",dim5:"Asia",dim6:"Phisics",value:1},{dim1:"Red",dim2:"Saint-Petersburg",dim3:"Round",dim4:"Earth",dim5:"Asia",dim6:"Chemistry",value:1},{dim1:"Blue",dim2:"Saint-Petersburg",dim3:"Round",dim4:"Earth",dim5:"Asia",dim6:"Chemistry",value:1},{dim1:"Green",dim2:"Moscow",dim3:"Round",dim4:"Earth",dim5:"Asia",dim6:"Chemistry",value:1}],map:function(W,V,Y){var aa=[];var ac=[];var X=[];for(var Z=0;ZX){ag=X}if(Wad[ac]){W[ac]=ad[ac]}}else{W[ac]=ad[ac]}if(ab[ac]){if(ab[ac]>ad[ac]){ab[ac]=ad[ac]}}else{ab[ac]=ad[ac]}}}if(ae){ae.sum=Z;ae.count=aa.length;ae.avg=Z/aa.length;ae.max=ab;ae.min=W}return Z}}]};function s(X){if(!X||"object"!==typeof X){return X}var Y="function"===typeof X.pop?[]:{};var W,V;for(W in X){if(X.hasOwnProperty(W)){V=X[W];if(V&&"object"===typeof V){Y[W]=s(V)}else{Y[W]=V}}}return Y}function l(Z,W){for(var V in W){var Y=W[V];var X=Z[Y.dimName];if(Y.id!=X){return false}}return true}function Q(Z,W){for(var V=0;V | |