libre-jqgrid 4.17.2 → 4.17.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.tscache/all/hashes/free-jqgrid.d.ts-74303c8b076937117540c0cb798f2053 +1 -0
- package/.tscache/all/hashes/test.ts-0d81877a31bc5d7ac52dd35a66602f01 +1 -0
- package/.tscache/all/timestamp +0 -0
- package/dist/css/ui.jqgrid.css +1618 -0
- package/dist/css/ui.jqgrid.min.css +4 -0
- package/dist/css/ui.jqgrid.min.css.map +1 -0
- package/dist/i18n/grid.locale-ar.js +198 -0
- package/dist/i18n/grid.locale-bg.js +201 -0
- package/dist/i18n/grid.locale-bs.js +230 -0
- package/dist/i18n/grid.locale-ca.js +204 -0
- package/dist/i18n/grid.locale-cn.js +237 -0
- package/dist/i18n/grid.locale-cs.js +197 -0
- package/dist/i18n/grid.locale-da.js +196 -0
- package/dist/i18n/grid.locale-de.js +240 -0
- package/dist/i18n/grid.locale-el.js +195 -0
- package/dist/i18n/grid.locale-en.js +256 -0
- package/dist/i18n/grid.locale-es.js +202 -0
- package/dist/i18n/grid.locale-fa.js +211 -0
- package/dist/i18n/grid.locale-fi.js +201 -0
- package/dist/i18n/grid.locale-fr.js +197 -0
- package/dist/i18n/grid.locale-gl.js +197 -0
- package/dist/i18n/grid.locale-he.js +198 -0
- package/dist/i18n/grid.locale-hr.js +231 -0
- package/dist/i18n/grid.locale-hu.js +196 -0
- package/dist/i18n/grid.locale-id.js +238 -0
- package/dist/i18n/grid.locale-is.js +197 -0
- package/dist/i18n/grid.locale-it.js +189 -0
- package/dist/i18n/grid.locale-ja.js +203 -0
- package/dist/i18n/grid.locale-kr.js +194 -0
- package/dist/i18n/grid.locale-lt.js +199 -0
- package/dist/i18n/grid.locale-me.js +198 -0
- package/dist/i18n/grid.locale-nl.js +208 -0
- package/dist/i18n/grid.locale-no.js +180 -0
- package/dist/i18n/grid.locale-pl.js +204 -0
- package/dist/i18n/grid.locale-pt-br.js +210 -0
- package/dist/i18n/grid.locale-pt.js +196 -0
- package/dist/i18n/grid.locale-ro.js +210 -0
- package/dist/i18n/grid.locale-ru.js +196 -0
- package/dist/i18n/grid.locale-sk.js +198 -0
- package/dist/i18n/grid.locale-sl.js +230 -0
- package/dist/i18n/grid.locale-sr.js +199 -0
- package/dist/i18n/grid.locale-sv.js +198 -0
- package/dist/i18n/grid.locale-th.js +195 -0
- package/dist/i18n/grid.locale-tr.js +197 -0
- package/dist/i18n/grid.locale-tw.js +199 -0
- package/dist/i18n/grid.locale-ua.js +199 -0
- package/dist/i18n/grid.locale-vi.js +238 -0
- package/dist/i18n/min/grid.locale-ar.js +10 -0
- package/dist/i18n/min/grid.locale-ar.js.map +1 -0
- package/dist/i18n/min/grid.locale-bg.js +10 -0
- package/dist/i18n/min/grid.locale-bg.js.map +1 -0
- package/dist/i18n/min/grid.locale-ca.js +15 -0
- package/dist/i18n/min/grid.locale-ca.js.map +1 -0
- package/dist/i18n/min/grid.locale-cn.js +10 -0
- package/dist/i18n/min/grid.locale-cn.js.map +1 -0
- package/dist/i18n/min/grid.locale-cs.js +11 -0
- package/dist/i18n/min/grid.locale-cs.js.map +1 -0
- package/dist/i18n/min/grid.locale-da.js +10 -0
- package/dist/i18n/min/grid.locale-da.js.map +1 -0
- package/dist/i18n/min/grid.locale-de.js +21 -0
- package/dist/i18n/min/grid.locale-de.js.map +1 -0
- package/dist/i18n/min/grid.locale-el.js +10 -0
- package/dist/i18n/min/grid.locale-el.js.map +1 -0
- package/dist/i18n/min/grid.locale-en.js +11 -0
- package/dist/i18n/min/grid.locale-en.js.map +1 -0
- package/dist/i18n/min/grid.locale-es.js +16 -0
- package/dist/i18n/min/grid.locale-es.js.map +1 -0
- package/dist/i18n/min/grid.locale-fa.js +8 -0
- package/dist/i18n/min/grid.locale-fa.js.map +1 -0
- package/dist/i18n/min/grid.locale-fi.js +11 -0
- package/dist/i18n/min/grid.locale-fi.js.map +1 -0
- package/dist/i18n/min/grid.locale-fr.js +10 -0
- package/dist/i18n/min/grid.locale-fr.js.map +1 -0
- package/dist/i18n/min/grid.locale-gl.js +9 -0
- package/dist/i18n/min/grid.locale-gl.js.map +1 -0
- package/dist/i18n/min/grid.locale-he.js +10 -0
- package/dist/i18n/min/grid.locale-he.js.map +1 -0
- package/dist/i18n/min/grid.locale-hr.js +11 -0
- package/dist/i18n/min/grid.locale-hr.js.map +1 -0
- package/dist/i18n/min/grid.locale-hu.js +10 -0
- package/dist/i18n/min/grid.locale-hu.js.map +1 -0
- package/dist/i18n/min/grid.locale-id.js +10 -0
- package/dist/i18n/min/grid.locale-id.js.map +1 -0
- package/dist/i18n/min/grid.locale-is.js +9 -0
- package/dist/i18n/min/grid.locale-is.js.map +1 -0
- package/dist/i18n/min/grid.locale-it.js +2 -0
- package/dist/i18n/min/grid.locale-it.js.map +1 -0
- package/dist/i18n/min/grid.locale-ja.js +10 -0
- package/dist/i18n/min/grid.locale-ja.js.map +1 -0
- package/dist/i18n/min/grid.locale-kr.js +2 -0
- package/dist/i18n/min/grid.locale-kr.js.map +1 -0
- package/dist/i18n/min/grid.locale-lt.js +10 -0
- package/dist/i18n/min/grid.locale-lt.js.map +1 -0
- package/dist/i18n/min/grid.locale-me.js +10 -0
- package/dist/i18n/min/grid.locale-me.js.map +1 -0
- package/dist/i18n/min/grid.locale-nl.js +2 -0
- package/dist/i18n/min/grid.locale-nl.js.map +1 -0
- package/dist/i18n/min/grid.locale-no.js +2 -0
- package/dist/i18n/min/grid.locale-no.js.map +1 -0
- package/dist/i18n/min/grid.locale-pl.js +18 -0
- package/dist/i18n/min/grid.locale-pl.js.map +1 -0
- package/dist/i18n/min/grid.locale-pt-br.js +21 -0
- package/dist/i18n/min/grid.locale-pt-br.js.map +1 -0
- package/dist/i18n/min/grid.locale-pt.js +9 -0
- package/dist/i18n/min/grid.locale-pt.js.map +1 -0
- package/dist/i18n/min/grid.locale-ro.js +10 -0
- package/dist/i18n/min/grid.locale-ro.js.map +1 -0
- package/dist/i18n/min/grid.locale-ru.js +10 -0
- package/dist/i18n/min/grid.locale-ru.js.map +1 -0
- package/dist/i18n/min/grid.locale-sk.js +10 -0
- package/dist/i18n/min/grid.locale-sk.js.map +1 -0
- package/dist/i18n/min/grid.locale-sr.js +10 -0
- package/dist/i18n/min/grid.locale-sr.js.map +1 -0
- package/dist/i18n/min/grid.locale-sv.js +10 -0
- package/dist/i18n/min/grid.locale-sv.js.map +1 -0
- package/dist/i18n/min/grid.locale-th.js +10 -0
- package/dist/i18n/min/grid.locale-th.js.map +1 -0
- package/dist/i18n/min/grid.locale-tr.js +10 -0
- package/dist/i18n/min/grid.locale-tr.js.map +1 -0
- package/dist/i18n/min/grid.locale-tw.js +11 -0
- package/dist/i18n/min/grid.locale-tw.js.map +1 -0
- package/dist/i18n/min/grid.locale-ua.js +10 -0
- package/dist/i18n/min/grid.locale-ua.js.map +1 -0
- package/dist/i18n/min/grid.locale-vi.js +10 -0
- package/dist/i18n/min/grid.locale-vi.js.map +1 -0
- package/dist/jquery.jqgrid.min.js +11 -0
- package/dist/jquery.jqgrid.min.js.map +1 -0
- package/{js/jquery.jqgrid.src.js.1 → dist/jquery.jqgrid.src.js} +1 -1
- package/dist/modules/grid.base.js +8518 -0
- package/dist/modules/grid.celledit.js +673 -0
- package/dist/modules/grid.common.js +844 -0
- package/dist/modules/grid.custom.js +1795 -0
- package/dist/modules/grid.filter.js +897 -0
- package/dist/modules/grid.formedit.js +2537 -0
- package/dist/modules/grid.grouping.js +737 -0
- package/dist/modules/grid.import.js +251 -0
- package/dist/modules/grid.inlinedit.js +784 -0
- package/dist/modules/grid.jqueryui.js +965 -0
- package/dist/modules/grid.pivot.js +862 -0
- package/dist/modules/grid.subgrid.js +379 -0
- package/dist/modules/grid.tbltogrid.js +141 -0
- package/dist/modules/grid.treegrid.js +683 -0
- package/dist/modules/jqdnr.js +188 -0
- package/dist/modules/jqmodal.js +292 -0
- package/dist/modules/jquery.fmatter.js +1061 -0
- package/dist/modules/jsonxml.js +343 -0
- package/dist/modules/min/grid.base.js +11 -0
- package/dist/modules/min/grid.base.js.map +1 -0
- package/dist/modules/min/grid.celledit.js +2 -0
- package/dist/modules/min/grid.celledit.js.map +1 -0
- package/dist/modules/min/grid.common.js +2 -0
- package/dist/modules/min/grid.common.js.map +1 -0
- package/dist/modules/min/grid.custom.js +2 -0
- package/dist/modules/min/grid.custom.js.map +1 -0
- package/dist/modules/min/grid.filter.js +2 -0
- package/dist/modules/min/grid.filter.js.map +1 -0
- package/dist/modules/min/grid.formedit.js +2 -0
- package/dist/modules/min/grid.formedit.js.map +1 -0
- package/dist/modules/min/grid.grouping.js +2 -0
- package/dist/modules/min/grid.grouping.js.map +1 -0
- package/dist/modules/min/grid.import.js +2 -0
- package/dist/modules/min/grid.import.js.map +1 -0
- package/dist/modules/min/grid.inlinedit.js +2 -0
- package/dist/modules/min/grid.inlinedit.js.map +1 -0
- package/dist/modules/min/grid.jqueryui.js +2 -0
- package/dist/modules/min/grid.jqueryui.js.map +1 -0
- package/dist/modules/min/grid.pivot.js +2 -0
- package/dist/modules/min/grid.pivot.js.map +1 -0
- package/dist/modules/min/grid.subgrid.js +2 -0
- package/dist/modules/min/grid.subgrid.js.map +1 -0
- package/dist/modules/min/grid.tbltogrid.js +2 -0
- package/dist/modules/min/grid.tbltogrid.js.map +1 -0
- package/dist/modules/min/grid.treegrid.js +2 -0
- package/dist/modules/min/grid.treegrid.js.map +1 -0
- package/dist/modules/min/jqdnr.js +2 -0
- package/dist/modules/min/jqdnr.js.map +1 -0
- package/dist/modules/min/jqmodal.js +2 -0
- package/dist/modules/min/jqmodal.js.map +1 -0
- package/dist/modules/min/jquery.fmatter.js +2 -0
- package/dist/modules/min/jquery.fmatter.js.map +1 -0
- package/dist/modules/min/jsonxml.js +2 -0
- package/dist/modules/min/jsonxml.js.map +1 -0
- package/dist/plugins/css/ui.multiselect.css +30 -0
- package/dist/plugins/css/ui.multiselect.min.css +2 -0
- package/dist/plugins/css/ui.multiselect.min.css.map +1 -0
- package/dist/plugins/grid.odata.js +1313 -0
- package/dist/plugins/jqgrid_download.js +109 -0
- package/dist/plugins/jquery.contextmenu-ui.js +304 -0
- package/dist/plugins/jquery.contextmenu.js +174 -0
- package/dist/plugins/jquery.createcontexmenufromnavigatorbuttons.js +172 -0
- package/dist/plugins/jquery.jqgrid.showhidecolumnmenu.js +201 -0
- package/dist/plugins/min/grid.odata.js +11 -0
- package/dist/plugins/min/grid.odata.js.map +1 -0
- package/dist/plugins/min/jquery.contextmenu-ui.js +26 -0
- package/dist/plugins/min/jquery.contextmenu-ui.js.map +1 -0
- package/dist/plugins/min/jquery.contextmenu.js +19 -0
- package/dist/plugins/min/jquery.contextmenu.js.map +1 -0
- package/dist/plugins/min/jquery.createcontexmenufromnavigatorbuttons.js +12 -0
- package/dist/plugins/min/jquery.createcontexmenufromnavigatorbuttons.js.map +1 -0
- package/dist/plugins/min/jquery.jqgrid.showhidecolumnmenu.js +10 -0
- package/dist/plugins/min/jquery.jqgrid.showhidecolumnmenu.js.map +1 -0
- package/dist/plugins/min/ui.multiselect.js +30 -0
- package/dist/plugins/min/ui.multiselect.js.map +1 -0
- package/dist/plugins/ui.multiselect.js +389 -0
- package/dist/ts/free-jqgrid.d.ts +2132 -0
- package/js/jquery.jqgrid.min.js +1 -1
- package/js/jquery.jqgrid.min.js.map +1 -1
- package/js/jquery.jqgrid.src.js +8 -3
- package/libre-jqgrid-4.17.4.tgz +0 -0
- package/package.json +1 -1
- package/.github/workflows/npm.yml +0 -47
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* jqGrid pivot functions
|
|
3
|
+
* Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com, http://trirand.com/blog/
|
|
4
|
+
* Copyright (c) 2014-2019, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
|
|
5
|
+
* Copyright (c) 2023, rany2, ranygh@riseup.net
|
|
6
|
+
* The module is created initially by Tony Tomov and it's full rewritten
|
|
7
|
+
* for free jqGrid: https://github.com/free-jqgrid/jqGrid by Oleg Kiriljuk
|
|
8
|
+
* Dual licensed under the MIT and GPL licenses:
|
|
9
|
+
* http://www.opensource.org/licenses/mit-license.php
|
|
10
|
+
* http://www.gnu.org/licenses/gpl-2.0.html
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/*jshint eqeqeq:false */
|
|
14
|
+
/*global jQuery, define, exports, module, require */
|
|
15
|
+
/*jslint eqeq: true, plusplus: true, continue: true, white: true */
|
|
16
|
+
(function (factory) {
|
|
17
|
+
"use strict";
|
|
18
|
+
if (typeof define === "function" && define.amd) {
|
|
19
|
+
// AMD. Register as an anonymous module.
|
|
20
|
+
define([
|
|
21
|
+
"jquery",
|
|
22
|
+
"./jquery.fmatter",
|
|
23
|
+
"./grid.grouping"
|
|
24
|
+
], factory);
|
|
25
|
+
} else if (typeof module === "object" && module.exports) {
|
|
26
|
+
// Node/CommonJS
|
|
27
|
+
module.exports = function (root, $) {
|
|
28
|
+
if (!root) {
|
|
29
|
+
root = window;
|
|
30
|
+
}
|
|
31
|
+
if ($ === undefined) {
|
|
32
|
+
// require("jquery") returns a factory that requires window to
|
|
33
|
+
// build a jQuery instance, we normalize how we use modules
|
|
34
|
+
// that require this pattern but the window provided is a noop
|
|
35
|
+
// if it's defined (how jquery works)
|
|
36
|
+
$ = typeof window !== "undefined" ?
|
|
37
|
+
require("jquery") :
|
|
38
|
+
require("jquery")(root);
|
|
39
|
+
}
|
|
40
|
+
require("./jquery.fmatter");
|
|
41
|
+
require("./grid.grouping");
|
|
42
|
+
factory($);
|
|
43
|
+
return $;
|
|
44
|
+
};
|
|
45
|
+
} else {
|
|
46
|
+
// Browser globals
|
|
47
|
+
factory(jQuery);
|
|
48
|
+
}
|
|
49
|
+
}(function ($) {
|
|
50
|
+
"use strict";
|
|
51
|
+
var jgrid = $.jgrid;
|
|
52
|
+
// begin module grid.pivot
|
|
53
|
+
function Aggregation(aggregator, context, pivotOptions) {
|
|
54
|
+
if (!(this instanceof Aggregation)) {
|
|
55
|
+
return new Aggregation(aggregator);
|
|
56
|
+
}
|
|
57
|
+
//this.result = undefined;
|
|
58
|
+
//this.count = undefined;
|
|
59
|
+
this.aggregator = aggregator;
|
|
60
|
+
this.finilized = false;
|
|
61
|
+
this.context = context;
|
|
62
|
+
this.pivotOptions = pivotOptions;
|
|
63
|
+
}
|
|
64
|
+
Aggregation.prototype.calc = function (v, fieldName, row, iRow, rows) {
|
|
65
|
+
var self = this;
|
|
66
|
+
if (v !== undefined) {
|
|
67
|
+
self.result = self.result || 0; // change undefined to 0
|
|
68
|
+
v = parseFloat(v);
|
|
69
|
+
switch (self.aggregator) {
|
|
70
|
+
case "sum":
|
|
71
|
+
self.result += v;
|
|
72
|
+
break;
|
|
73
|
+
case "count":
|
|
74
|
+
self.result++;
|
|
75
|
+
break;
|
|
76
|
+
case "avg":
|
|
77
|
+
if (self.finilized) {
|
|
78
|
+
self.count = self.count || 0; // change undefined to 0
|
|
79
|
+
self.result = (self.result * self.count + v) / (self.count + 1);
|
|
80
|
+
self.count++;
|
|
81
|
+
} else {
|
|
82
|
+
self.result += v;
|
|
83
|
+
self.count = self.count || 0; // change undefined to 0
|
|
84
|
+
self.count++;
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
case "min":
|
|
88
|
+
self.result = Math.min(self.result, v);
|
|
89
|
+
break;
|
|
90
|
+
case "max":
|
|
91
|
+
self.result = Math.max(self.result, v);
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
if ($.jgrid.isFunction(self.aggregator)) {
|
|
95
|
+
self.result = self.aggregator.call(self.context, {
|
|
96
|
+
previousResult: self.result,
|
|
97
|
+
value: v,
|
|
98
|
+
fieldName: fieldName,
|
|
99
|
+
item: row,
|
|
100
|
+
iItem: iRow,
|
|
101
|
+
items: rows
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
Aggregation.prototype.getResult = function (obj, propName, forceSaving) {
|
|
109
|
+
var self = this;
|
|
110
|
+
if (self.result !== undefined || forceSaving) {
|
|
111
|
+
if (forceSaving) {
|
|
112
|
+
if (self.result !== undefined) {
|
|
113
|
+
self.result = 0;
|
|
114
|
+
self.count = 0;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (self.result !== undefined && !self.finilized && self.aggregator === "avg") {
|
|
118
|
+
self.result = self.result / self.count;
|
|
119
|
+
self.finilized = true;
|
|
120
|
+
}
|
|
121
|
+
obj[propName] = self.result;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
function ArrayOfFieldsets(trimByCollect, caseSensitive, skipSort, dimension, fieldName) {
|
|
126
|
+
var iField, dimensionLength = dimension.length, dimensionItem, self = this,
|
|
127
|
+
stringCompare = function (a, b) {
|
|
128
|
+
var a1 = a, b1 = b;
|
|
129
|
+
if (a1 == null) { a1 = ""; } // we will place undefined and null values as the lowest TOGETHER with ""
|
|
130
|
+
if (b1 == null) { b1 = ""; }
|
|
131
|
+
// be sure that we have no other input data (Number, Date and so on)
|
|
132
|
+
a1 = String(a1);
|
|
133
|
+
b1 = String(b1);
|
|
134
|
+
if (!this.caseSensitive) {
|
|
135
|
+
a1 = a1.toUpperCase();
|
|
136
|
+
b1 = b1.toUpperCase();
|
|
137
|
+
}
|
|
138
|
+
if (a1 === b1) {
|
|
139
|
+
if (a === b) {//typeof a === typeof b) {
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
// either a or b is undefined or null
|
|
143
|
+
if (a === undefined) { return -1; } // make undefined less as all other
|
|
144
|
+
if (b === undefined) { return 1; }
|
|
145
|
+
if (a === null) { return -1; } // make null less as all other with the exception undefined
|
|
146
|
+
if (b === null) { return 1; }
|
|
147
|
+
}
|
|
148
|
+
if (a1 < b1) {
|
|
149
|
+
return -1;
|
|
150
|
+
}
|
|
151
|
+
return 1;
|
|
152
|
+
},
|
|
153
|
+
numberCompare = function (a, b) {
|
|
154
|
+
a = Number(a);
|
|
155
|
+
b = Number(b);
|
|
156
|
+
if (a === b) {
|
|
157
|
+
return 0;
|
|
158
|
+
}
|
|
159
|
+
if (a < b) {
|
|
160
|
+
return -1;
|
|
161
|
+
}
|
|
162
|
+
return 1;
|
|
163
|
+
},
|
|
164
|
+
integerCompare = function (a, b) {
|
|
165
|
+
a = Math.floor(Number(a));
|
|
166
|
+
b = Math.floor(Number(b));
|
|
167
|
+
if (a === b) {
|
|
168
|
+
return 0;
|
|
169
|
+
}
|
|
170
|
+
if (a < b) {
|
|
171
|
+
return -1;
|
|
172
|
+
}
|
|
173
|
+
return 1;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
self.items = [];
|
|
177
|
+
self.indexesOfSourceData = [];
|
|
178
|
+
self.trimByCollect = trimByCollect;
|
|
179
|
+
self.caseSensitive = caseSensitive;
|
|
180
|
+
self.skipSort = skipSort;
|
|
181
|
+
self.fieldLength = dimensionLength;
|
|
182
|
+
self.fieldNames = new Array(dimensionLength);
|
|
183
|
+
self.fieldSortDirection = new Array(dimensionLength);
|
|
184
|
+
self.fieldCompare = new Array(dimensionLength); // 0 - number, 1 - integer, 2 - string, one can extend for Date and other
|
|
185
|
+
for (iField = 0; iField < dimensionLength; iField++) {
|
|
186
|
+
dimensionItem = dimension[iField];
|
|
187
|
+
self.fieldNames[iField] = dimensionItem[fieldName || "dataName"];
|
|
188
|
+
switch (dimensionItem.sorttype) {
|
|
189
|
+
case "integer":
|
|
190
|
+
case "int":
|
|
191
|
+
self.fieldCompare[iField] = integerCompare;
|
|
192
|
+
break;
|
|
193
|
+
case "number":
|
|
194
|
+
case "currency":
|
|
195
|
+
case "float":
|
|
196
|
+
self.fieldCompare[iField] = numberCompare;
|
|
197
|
+
break;
|
|
198
|
+
default:
|
|
199
|
+
self.fieldCompare[iField] = $.jgrid.isFunction(dimensionItem.compare) ? dimensionItem.compare : stringCompare;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
self.fieldSortDirection[iField] = dimensionItem.sortorder === "desc" ? -1 : 1;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
ArrayOfFieldsets.prototype.compareVectorsEx = function (vector1, vector2) {
|
|
206
|
+
var self = this, fieldLength = self.fieldLength, iField, compareResult;
|
|
207
|
+
for (iField = 0; iField < fieldLength; iField++) {
|
|
208
|
+
compareResult = self.fieldCompare[iField](vector1[iField], vector2[iField]);
|
|
209
|
+
if (compareResult !== 0) {
|
|
210
|
+
return {
|
|
211
|
+
index: iField,
|
|
212
|
+
result: compareResult
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
index: -1,
|
|
218
|
+
result: 0
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
ArrayOfFieldsets.prototype.getIndexOfDifferences = function (vector1, vector2) {
|
|
222
|
+
if (vector2 === null || vector1 === null) {
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
return this.compareVectorsEx(vector1, vector2).index;
|
|
226
|
+
};
|
|
227
|
+
ArrayOfFieldsets.prototype.compareVectors = function (vector1, vector2) {
|
|
228
|
+
var compareRestlts = this.compareVectorsEx(vector1, vector2),
|
|
229
|
+
sortDirection = compareRestlts.index >= 0 ? this.fieldSortDirection[compareRestlts.index] : 1;
|
|
230
|
+
return sortDirection > 0 ? compareRestlts.result : -compareRestlts.result;
|
|
231
|
+
};
|
|
232
|
+
ArrayOfFieldsets.prototype.getItem = function (index) {
|
|
233
|
+
return this.items[index];
|
|
234
|
+
};
|
|
235
|
+
ArrayOfFieldsets.prototype.getIndexLength = function () {
|
|
236
|
+
return this.items.length;
|
|
237
|
+
};
|
|
238
|
+
ArrayOfFieldsets.prototype.getIndexesOfSourceData = function (index) {
|
|
239
|
+
return this.indexesOfSourceData[index];
|
|
240
|
+
};
|
|
241
|
+
ArrayOfFieldsets.prototype.createDataIndex = function (data) {
|
|
242
|
+
var self = this, iRow, nRows = data.length, fieldLength = self.fieldLength, values, v,
|
|
243
|
+
fieldNames = self.fieldNames, indexesOfSourceData = self.indexesOfSourceData, iField, compareResult, i, item,
|
|
244
|
+
items = self.items, iMin, iMax;
|
|
245
|
+
|
|
246
|
+
for (iRow = 0; iRow < nRows; iRow++) {
|
|
247
|
+
item = data[iRow];
|
|
248
|
+
|
|
249
|
+
// build the set of fields with data of the current item
|
|
250
|
+
values = new Array(fieldLength);
|
|
251
|
+
for (iField = 0; iField < fieldLength; iField++) {
|
|
252
|
+
v = item[fieldNames[iField]];
|
|
253
|
+
if (v !== undefined) {
|
|
254
|
+
if (typeof v === "string" && self.trimByCollect) {
|
|
255
|
+
v = $.jgrid.trim(v);
|
|
256
|
+
}
|
|
257
|
+
values[iField] = v;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// compare values with items having index iMax and iMin
|
|
262
|
+
// If we use skipSort:true option then we compare always
|
|
263
|
+
// with iMax item only.
|
|
264
|
+
iMin = 0;
|
|
265
|
+
iMax = items.length - 1;
|
|
266
|
+
if (iMax < 0) {
|
|
267
|
+
items.push(values);
|
|
268
|
+
indexesOfSourceData.push([iRow]);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
compareResult = self.compareVectors(values, items[iMax]);
|
|
272
|
+
if (compareResult === 0) {
|
|
273
|
+
indexesOfSourceData[iMax].push(iRow);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (compareResult === 1 || self.skipSort) {
|
|
277
|
+
// in case of the empty array this.items or if the values is larger as the
|
|
278
|
+
// the max (last) element of this.items: append values to the array this.items
|
|
279
|
+
items.push(values);
|
|
280
|
+
indexesOfSourceData.push([iRow]);
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
compareResult = self.compareVectors(items[0], values);
|
|
284
|
+
if (compareResult === 1) {
|
|
285
|
+
// if the min (first) element values is larger as the values:
|
|
286
|
+
// insert the values as the first element of the array this.items
|
|
287
|
+
items.unshift(values);
|
|
288
|
+
indexesOfSourceData.unshift([iRow]);
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
if (compareResult === 0) {
|
|
292
|
+
indexesOfSourceData[0].push(iRow);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
// we are sure that items[iMin] < values < items[iMax]
|
|
296
|
+
while (true) {
|
|
297
|
+
if (iMax - iMin < 2) {
|
|
298
|
+
// no identical items are found we need to insert the item at i index
|
|
299
|
+
items.splice(iMax, 0, values); // insert after iMin
|
|
300
|
+
indexesOfSourceData.splice(iMax, 0, [iRow]);
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
i = Math.floor((iMin + iMax) / 2); // | 0 means Math.floor, but it's faster sometimes.
|
|
304
|
+
compareResult = self.compareVectors(items[i], values);
|
|
305
|
+
if (compareResult === 0) {
|
|
306
|
+
indexesOfSourceData[i].push(iRow);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
if (compareResult === 1) {
|
|
310
|
+
iMax = i;
|
|
311
|
+
} else {
|
|
312
|
+
iMin = i;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
jgrid.extend({
|
|
319
|
+
pivotSetup: function (data, options) {
|
|
320
|
+
// data should come in json format
|
|
321
|
+
// The function return the new colModel and the transformed data
|
|
322
|
+
// again with group setup options which then will be passed to the grid
|
|
323
|
+
var self = this[0], isArray = Array.isArray, summaries = {},
|
|
324
|
+
groupingView = {
|
|
325
|
+
groupField: [],
|
|
326
|
+
groupSummary: [],
|
|
327
|
+
groupSummaryPos: []
|
|
328
|
+
},
|
|
329
|
+
groupOptions = {
|
|
330
|
+
grouping: true,
|
|
331
|
+
groupingView: groupingView
|
|
332
|
+
},
|
|
333
|
+
o = $.extend({
|
|
334
|
+
totals: false, // replacement for rowTotals. totalText and totalHeader can be used additionally
|
|
335
|
+
useColSpanStyle: false,
|
|
336
|
+
trimByCollect: true,
|
|
337
|
+
skipSortByX: false,
|
|
338
|
+
skipSortByY: false,
|
|
339
|
+
caseSensitive: false,
|
|
340
|
+
footerTotals: false, // replacement colTotals. footerAggregator option and totalText properties of xDimension[i] can be used additionally
|
|
341
|
+
groupSummary: true,
|
|
342
|
+
groupSummaryPos: "header",
|
|
343
|
+
frozenStaticCols: false,
|
|
344
|
+
defaultFormatting: true,
|
|
345
|
+
data: data
|
|
346
|
+
}, options || {}),
|
|
347
|
+
row, i, k, nRows = data.length, x, y, cm, iRow, cmName, iXData, itemXData, pivotInfos, rows,
|
|
348
|
+
xDimension = o.xDimension, yDimension = o.yDimension, aggregates = o.aggregates, aggrContext,
|
|
349
|
+
isRowTotal = o.totalText || o.totals || o.rowTotals || o.totalHeader, aggrTotal, gi,
|
|
350
|
+
xlen = isArray(xDimension) ? xDimension.length : 0,
|
|
351
|
+
ylen = isArray(yDimension) ? yDimension.length : 0,
|
|
352
|
+
aggrlen = isArray(aggregates) ? aggregates.length : 0,
|
|
353
|
+
headerLevels = ylen - (aggrlen === 1 ? 1 : 0),
|
|
354
|
+
colHeaders = [], hasGroupTotal = [], colModel = [], outputItems = [],
|
|
355
|
+
additionalProperties = ["pivotInfos"],
|
|
356
|
+
aggrContextTotalRows = new Array(aggrlen), aggrContextGroupTotalRows = new Array(ylen),
|
|
357
|
+
xIndexLength, indexesOfDataWithTheSameXValues, iYData, itemYData, indexesOfDataWithTheSameYValues,
|
|
358
|
+
iRows, agr, outputItem, previousY, groupHeaders, iRowsY, xIndex, yIndex, yIndexLength,
|
|
359
|
+
indexDataBy = function (dimension, skipSort, compareVectors) {
|
|
360
|
+
var index = new ArrayOfFieldsets(o.trimByCollect, o.caseSensitive, skipSort, dimension);
|
|
361
|
+
if ($.jgrid.isFunction(compareVectors)) {
|
|
362
|
+
index.compareVectorsEx = compareVectors;
|
|
363
|
+
}
|
|
364
|
+
index.createDataIndex(data);
|
|
365
|
+
return index;
|
|
366
|
+
},
|
|
367
|
+
buildColModelItem = function (colType, agr1, iAggr, level, iyData) {
|
|
368
|
+
var label, name, cmItem;
|
|
369
|
+
switch (colType) {
|
|
370
|
+
case 1: // total group
|
|
371
|
+
label = yDimension[level].totalText || "{0} {1} {2}";
|
|
372
|
+
name = "y" + iyData + "t" + level;
|
|
373
|
+
break;
|
|
374
|
+
case 2: // grand total
|
|
375
|
+
label = o.totalText || "{0}";
|
|
376
|
+
name = "t";
|
|
377
|
+
break;
|
|
378
|
+
//case 0: // standard column
|
|
379
|
+
default:
|
|
380
|
+
label = aggrlen > 1 ?
|
|
381
|
+
agr1.label || "{0}" :
|
|
382
|
+
($.jgrid.isFunction(yDimension[level].label) ?
|
|
383
|
+
yDimension[level].label :
|
|
384
|
+
yIndex.getItem(iyData)[level]);
|
|
385
|
+
name = "y" + iyData;
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
cmItem = $.extend({}, agr1, {
|
|
389
|
+
name: name + (aggrlen > 1 ? "a" + iAggr : ""),
|
|
390
|
+
label: $.jgrid.isFunction(label) ?
|
|
391
|
+
(label.call(self, colType === 2 ?
|
|
392
|
+
{ aggregate: agr1, iAggregate: iAggr, pivotOptions: o } :
|
|
393
|
+
(colType === 1 ?
|
|
394
|
+
{ yIndex: yIndex.getItem(iyData), aggregate: agr1, iAggregate: iAggr, yLevel: level, pivotOptions: o } :
|
|
395
|
+
{ yData: yIndex.getItem(iyData)[level], yIndex: yIndex.getItem(iyData), yLevel: level, pivotOptions: o }))) :
|
|
396
|
+
(jgrid.template.apply(self, colType === 2 ?
|
|
397
|
+
[String(label), agr1.aggregator, agr1.member, iAggr] :
|
|
398
|
+
[String(label), agr1.aggregator, agr1.member, yIndex.getItem(iyData)[level], level]))
|
|
399
|
+
});
|
|
400
|
+
delete cmItem.member;
|
|
401
|
+
delete cmItem.aggregator;
|
|
402
|
+
return cmItem;
|
|
403
|
+
},
|
|
404
|
+
addColumnToColModel = function (colType, level, iyData) {
|
|
405
|
+
var iAggr, aggregate;
|
|
406
|
+
for (iAggr = 0; iAggr < aggrlen; iAggr++) {
|
|
407
|
+
aggregate = aggregates[iAggr];
|
|
408
|
+
if (aggregate.template === undefined && aggregate.formatter === undefined && o.defaultFormatting) {
|
|
409
|
+
aggregate.template = aggregate.aggregator === "count" ? "integer" : "number";
|
|
410
|
+
}
|
|
411
|
+
colModel.push(buildColModelItem(colType, aggregate, iAggr, level, iyData));
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
addGroupTotalHeaders = function (iyData, level, previousY1) {
|
|
415
|
+
var iLevel, j, totalHeader, headerOnTop;
|
|
416
|
+
for (iLevel = headerLevels - 1; iLevel >= level; iLevel--) {
|
|
417
|
+
if (hasGroupTotal[iLevel]) {
|
|
418
|
+
for (j = 0; j <= iLevel; j++) {
|
|
419
|
+
groupHeaders = colHeaders[j].groupHeaders;
|
|
420
|
+
groupHeaders[groupHeaders.length - 1].numberOfColumns += aggrlen;
|
|
421
|
+
}
|
|
422
|
+
y = yDimension[iLevel];
|
|
423
|
+
totalHeader = y.totalHeader;
|
|
424
|
+
headerOnTop = y.headerOnTop;
|
|
425
|
+
for (j = iLevel + 1; j <= headerLevels - 1; j++) {
|
|
426
|
+
colHeaders[j].groupHeaders.push({
|
|
427
|
+
titleText: ((headerOnTop && j === iLevel + 1) || (!headerOnTop && j === headerLevels - 1)) ?
|
|
428
|
+
($.jgrid.isFunction(totalHeader) ?
|
|
429
|
+
totalHeader.call(self, previousY1, iLevel) :
|
|
430
|
+
jgrid.template.call(self, String(totalHeader || ""), previousY1[iLevel], iLevel)) :
|
|
431
|
+
"",
|
|
432
|
+
startColumnName: "y" + (iyData - 1) + "t" + iLevel + (aggrlen === 1 ? "" : "a0"),
|
|
433
|
+
numberOfColumns: aggrlen
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
createTotalAggregation = function (iAggr) {
|
|
440
|
+
var aggrGroup = new Aggregation(aggregates[iAggr].aggregator === "count" ? "sum" : aggregates[iAggr].aggregator, self, options);
|
|
441
|
+
aggrGroup.groupInfo = { iRows: [], rows: [], ys: [], iYs: [] };
|
|
442
|
+
return aggrGroup;
|
|
443
|
+
},
|
|
444
|
+
initializeGroupTotals = function () {
|
|
445
|
+
var iLevel, iAggr;
|
|
446
|
+
for (iLevel = headerLevels - 1; iLevel >= 0; iLevel--) {
|
|
447
|
+
if (hasGroupTotal[iLevel]) {
|
|
448
|
+
if (aggrContextGroupTotalRows[iLevel] == null) {// first call
|
|
449
|
+
aggrContextGroupTotalRows[iLevel] = new Array(aggrlen);
|
|
450
|
+
}
|
|
451
|
+
for (iAggr = 0; iAggr < aggrlen; iAggr++) {
|
|
452
|
+
aggrContextGroupTotalRows[iLevel][iAggr] = createTotalAggregation(iAggr);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
finalizeGroupTotals = function (iyData, itemYData1, previousY1, iAggr) {
|
|
458
|
+
var iLevel, level = yIndex.getIndexOfDifferences(itemYData1, previousY1), fieldName, aggrGroup;
|
|
459
|
+
|
|
460
|
+
if (previousY1 !== null) {
|
|
461
|
+
// test whether the group is finished and one need to get results
|
|
462
|
+
level = Math.max(level, 0); // change -1 to 0 for the last call (itemYData === previousY)
|
|
463
|
+
for (iLevel = headerLevels - 1; iLevel >= level; iLevel--) {
|
|
464
|
+
fieldName = "y" + iyData + "t" + iLevel + (aggrlen > 1 ? "a" + iAggr : "");
|
|
465
|
+
if (hasGroupTotal[iLevel] && outputItem[fieldName] === undefined) {
|
|
466
|
+
aggrGroup = aggrContextGroupTotalRows[iLevel][iAggr];
|
|
467
|
+
aggrGroup.getResult(outputItem, fieldName);
|
|
468
|
+
outputItem.pivotInfos[fieldName] = {
|
|
469
|
+
colType: 1,
|
|
470
|
+
iA: iAggr,
|
|
471
|
+
a: aggregates[iAggr],
|
|
472
|
+
level: iLevel,
|
|
473
|
+
iRows: aggrGroup.groupInfo.iRows,
|
|
474
|
+
rows: aggrGroup.groupInfo.rows,
|
|
475
|
+
ys: aggrGroup.groupInfo.ys,
|
|
476
|
+
iYs: aggrGroup.groupInfo.iYs
|
|
477
|
+
};
|
|
478
|
+
if (itemYData1 !== previousY1) {
|
|
479
|
+
aggrContextGroupTotalRows[iLevel][iAggr] = createTotalAggregation(iAggr);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
calculateGroupTotals = function (itemYData1, previousY1, aggregate, iAggr, row1, iRow1, iyData) {
|
|
486
|
+
// the method will be called at the first time with previousY === null in every output row
|
|
487
|
+
// and finally with itemYData === previousY for getting results of all aggregation contexts
|
|
488
|
+
var iLevel, aggrGroup, groupInfo;
|
|
489
|
+
|
|
490
|
+
if (itemYData1 !== previousY1) { // not the last call in the row
|
|
491
|
+
for (iLevel = headerLevels - 1; iLevel >= 0; iLevel--) {
|
|
492
|
+
if (hasGroupTotal[iLevel]) {
|
|
493
|
+
aggrGroup = aggrContextGroupTotalRows[iLevel][iAggr];
|
|
494
|
+
aggrGroup.calc(row1[aggregate.member], aggregate.member, row1, iRow1, data);
|
|
495
|
+
groupInfo = aggrGroup.groupInfo;
|
|
496
|
+
if ($.inArray(iyData, groupInfo.iYs) < 0) {
|
|
497
|
+
groupInfo.iYs.push(iyData);
|
|
498
|
+
groupInfo.ys.push(itemYData1);
|
|
499
|
+
}
|
|
500
|
+
if ($.inArray(iRow1, groupInfo.iRows) < 0) {
|
|
501
|
+
groupInfo.iRows.push(iRow1);
|
|
502
|
+
groupInfo.rows.push(row1);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
if (xlen === 0 || aggrlen === 0) {
|
|
510
|
+
throw ("xDimension or aggregates options are not set!");
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// ****************************************************************
|
|
514
|
+
// The step 1: scan input data and build the list of unique indexes
|
|
515
|
+
// ****************************************************************
|
|
516
|
+
xIndex = indexDataBy(xDimension, o.skipSortByX, o.compareVectorsByX);
|
|
517
|
+
yIndex = indexDataBy(yDimension, o.skipSortByY, o.compareVectorsByY);
|
|
518
|
+
|
|
519
|
+
// save to be used probably later
|
|
520
|
+
options.xIndex = xIndex;
|
|
521
|
+
options.yIndex = yIndex;
|
|
522
|
+
|
|
523
|
+
// *******************************************
|
|
524
|
+
// The step 2: build colModel and groupOptions
|
|
525
|
+
// *******************************************
|
|
526
|
+
// fill the first xlen columns of colModel and fill the groupOptions
|
|
527
|
+
// the names of the first columns will be "x"+i. The first column have the name "x0".
|
|
528
|
+
for (i = 0; i < xlen; i++) {
|
|
529
|
+
x = xDimension[i];
|
|
530
|
+
cm = {
|
|
531
|
+
name: "x" + i,
|
|
532
|
+
label: x.label != null ?
|
|
533
|
+
($.jgrid.isFunction(x.label) ? x.label.call(self, x, i, o) : x.label) :
|
|
534
|
+
x.dataName,
|
|
535
|
+
frozen: o.frozenStaticCols
|
|
536
|
+
};
|
|
537
|
+
if (i < xlen - 1 && !x.skipGrouping && !x.additionalProperty) {
|
|
538
|
+
// based on xDimension levels build grouping
|
|
539
|
+
groupingView.groupField.push(cm.name);
|
|
540
|
+
groupingView.groupSummary.push(o.groupSummary);
|
|
541
|
+
groupingView.groupSummaryPos.push(o.groupSummaryPos);
|
|
542
|
+
}
|
|
543
|
+
cm = $.extend(cm, x);
|
|
544
|
+
delete cm.dataName;
|
|
545
|
+
delete cm.footerText;
|
|
546
|
+
if (!x.additionalProperty) {
|
|
547
|
+
colModel.push(cm);
|
|
548
|
+
groupOptions.sortname = cm.name;
|
|
549
|
+
} else {
|
|
550
|
+
additionalProperties.push(cm.name);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
if (xlen < 2) {
|
|
554
|
+
groupOptions.grouping = false; // no grouping is needed
|
|
555
|
+
}
|
|
556
|
+
groupingView.hideFirstGroupCol = true;
|
|
557
|
+
|
|
558
|
+
// Fill hasGroupTotal and groupColumnsPerLevel arrays
|
|
559
|
+
// The hasGroupTotal just shows whether one need create additional totals for every group.
|
|
560
|
+
for (i = 0; i < ylen; i++) {
|
|
561
|
+
y = yDimension[i];
|
|
562
|
+
hasGroupTotal.push(y.totals || y.rowTotals || y.totalText || y.totalHeader ? true : false);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// fill other columns of colModel based on collected uniqueYData and aggregates options
|
|
566
|
+
// the names of the first columns will be "y"+i in case of one aggregate and
|
|
567
|
+
// "y"+i+"a"+k in case of multiple aggregates. The name of the first "y"-column is "y0" or "y0a0"
|
|
568
|
+
// The next function build and insert item in colModel
|
|
569
|
+
// colType: 0 - means standard column, 1 - total group, 2 - grand total
|
|
570
|
+
previousY = yIndex.getItem(0);
|
|
571
|
+
addColumnToColModel(0, ylen - 1, 0); // add standard column
|
|
572
|
+
yIndexLength = yIndex.getIndexLength();
|
|
573
|
+
for (iYData = 1; iYData < yIndexLength; iYData++) {
|
|
574
|
+
itemYData = yIndex.getItem(iYData);
|
|
575
|
+
/*
|
|
576
|
+
* find where (on which level) the itemYData have the differences to
|
|
577
|
+
* the previous y (previousY). If the level has (totals:true/rowTotals:true) in yDimension
|
|
578
|
+
* then one should insert new total columns for all levels starting with the highest one
|
|
579
|
+
* (yDimension[yDimension.length-1]) and till the current one.
|
|
580
|
+
*/
|
|
581
|
+
i = yIndex.getIndexOfDifferences(itemYData, previousY);
|
|
582
|
+
for (k = headerLevels - 1; k >= i; k--) {
|
|
583
|
+
if (hasGroupTotal[k]) {
|
|
584
|
+
addColumnToColModel(1, k, iYData - 1); // add group total columns
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
previousY = itemYData;
|
|
588
|
+
addColumnToColModel(0, ylen - 1, iYData); // add standard column
|
|
589
|
+
}
|
|
590
|
+
// finalize of all totals
|
|
591
|
+
for (i = headerLevels - 1; i >= 0; i--) {
|
|
592
|
+
if (hasGroupTotal[i]) {
|
|
593
|
+
addColumnToColModel(1, i, yIndexLength - 1); // add the last group total columns
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
// add total columns calculated over all data of the row
|
|
597
|
+
if (isRowTotal) {
|
|
598
|
+
addColumnToColModel(2);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// ********************************
|
|
602
|
+
// The step 3: build column headers
|
|
603
|
+
// ********************************
|
|
604
|
+
// initialize colHeaders
|
|
605
|
+
previousY = yIndex.getItem(0);
|
|
606
|
+
for (k = 0; k < headerLevels; k++) {
|
|
607
|
+
colHeaders.push({
|
|
608
|
+
useColSpanStyle: o.useColSpanStyle,
|
|
609
|
+
groupHeaders: [{
|
|
610
|
+
titleText: ($.jgrid.isFunction(yDimension[k].label) ?
|
|
611
|
+
yDimension[k].label.call(self, { yData: previousY[k], yIndex: previousY, yLevel: k, pivotOptions: o }) :
|
|
612
|
+
previousY[k]),
|
|
613
|
+
startColumnName: aggrlen === 1 ? "y0" : "y0a0",
|
|
614
|
+
numberOfColumns: aggrlen
|
|
615
|
+
}]
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
for (iYData = 1; iYData < yIndexLength; iYData++) {
|
|
619
|
+
itemYData = yIndex.getItem(iYData);
|
|
620
|
+
i = yIndex.getIndexOfDifferences(itemYData, previousY);
|
|
621
|
+
// We placed QNIQUE data in uniqueYData array.
|
|
622
|
+
// So we always find a difference on one level
|
|
623
|
+
|
|
624
|
+
addGroupTotalHeaders(iYData, i, previousY);
|
|
625
|
+
// add column headers which corresponds the main data
|
|
626
|
+
for (k = headerLevels - 1; k >= i; k--) {
|
|
627
|
+
colHeaders[k].groupHeaders.push({
|
|
628
|
+
titleText: ($.jgrid.isFunction(yDimension[k].label) ?
|
|
629
|
+
yDimension[k].label.call(self, { yData: itemYData[k], yIndex: itemYData, yLevel: k, pivotOptions: o }) :
|
|
630
|
+
itemYData[k]),
|
|
631
|
+
startColumnName: "y" + iYData + (aggrlen === 1 ? "" : "a0"),
|
|
632
|
+
numberOfColumns: aggrlen
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
for (k = 0; k < i; k++) {
|
|
636
|
+
groupHeaders = colHeaders[k].groupHeaders;
|
|
637
|
+
groupHeaders[groupHeaders.length - 1].numberOfColumns += aggrlen;
|
|
638
|
+
}
|
|
639
|
+
previousY = itemYData;
|
|
640
|
+
}
|
|
641
|
+
addGroupTotalHeaders(yIndexLength, 0, previousY);
|
|
642
|
+
|
|
643
|
+
// fill groupHeaders without taking in consideration group total columns
|
|
644
|
+
if (isRowTotal) {
|
|
645
|
+
for (i = 0; i < headerLevels; i++) {
|
|
646
|
+
colHeaders[i].groupHeaders.push({
|
|
647
|
+
titleText: (i < headerLevels - 1 ? "" : o.totalHeader || ""),
|
|
648
|
+
startColumnName: "t" + (aggrlen === 1 ? "" : "a0"),
|
|
649
|
+
numberOfColumns: aggrlen
|
|
650
|
+
});
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// *****************************
|
|
655
|
+
// The step 4: fill data of grid
|
|
656
|
+
// *****************************
|
|
657
|
+
xIndexLength = xIndex.getIndexLength();
|
|
658
|
+
for (iXData = 0; iXData < xIndexLength; iXData++) {
|
|
659
|
+
itemXData = xIndex.getItem(iXData);
|
|
660
|
+
pivotInfos = { iX: iXData, x: itemXData };
|
|
661
|
+
outputItem = { pivotInfos: pivotInfos }; // item of output data
|
|
662
|
+
// itemXData corresponds to the row of output data
|
|
663
|
+
for (i = 0; i < xlen; i++) {
|
|
664
|
+
// fill first columns of data
|
|
665
|
+
outputItem["x" + i] = itemXData[i];
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
indexesOfDataWithTheSameXValues = xIndex.getIndexesOfSourceData(iXData);
|
|
669
|
+
// The rows of input data with indexes from indexesOfDataWithTheSameXValues contains itemXData
|
|
670
|
+
// Now we build columns of itemXData row
|
|
671
|
+
if (isRowTotal) {
|
|
672
|
+
for (k = 0; k < aggrlen; k++) {
|
|
673
|
+
aggrContextTotalRows[k] = createTotalAggregation(k);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
previousY = null;
|
|
677
|
+
initializeGroupTotals();
|
|
678
|
+
for (iYData = 0; iYData < yIndexLength; iYData++) {
|
|
679
|
+
itemYData = yIndex.getItem(iYData);
|
|
680
|
+
indexesOfDataWithTheSameYValues = yIndex.getIndexesOfSourceData(iYData);
|
|
681
|
+
// we calculate aggregate in every itemYData
|
|
682
|
+
for (k = 0; k < aggrlen; k++) {
|
|
683
|
+
if (previousY !== null) { // empty input data
|
|
684
|
+
finalizeGroupTotals(iYData - 1, itemYData, previousY, k);
|
|
685
|
+
}
|
|
686
|
+
iRows = [];
|
|
687
|
+
for (i = 0; i < indexesOfDataWithTheSameYValues.length; i++) {
|
|
688
|
+
iRowsY = indexesOfDataWithTheSameYValues[i];
|
|
689
|
+
if ($.inArray(iRowsY, indexesOfDataWithTheSameXValues) >= 0) {
|
|
690
|
+
iRows.push(iRowsY);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
if (iRows.length > 0) {
|
|
694
|
+
// iRows array have all indexes of input data which have both itemXData and itemYData
|
|
695
|
+
// We need calculate aggregate agr over all the items
|
|
696
|
+
rows = new Array(iRows.length);
|
|
697
|
+
agr = aggregates[k];
|
|
698
|
+
aggrContext = new Aggregation(agr.aggregator, self, options);
|
|
699
|
+
for (iRow = 0; iRow < iRows.length; iRow++) {
|
|
700
|
+
i = iRows[iRow];
|
|
701
|
+
row = data[i];
|
|
702
|
+
rows[iRow] = row;
|
|
703
|
+
aggrContext.calc(row[agr.member], agr.member, row, i, data);
|
|
704
|
+
if (isRowTotal) {
|
|
705
|
+
aggrTotal = aggrContextTotalRows[k];
|
|
706
|
+
aggrTotal.calc(row[agr.member], agr.member, row, i, data);
|
|
707
|
+
gi = aggrTotal.groupInfo;
|
|
708
|
+
if ($.inArray(i, gi.iYs) < 0) {
|
|
709
|
+
gi.iYs.push(iYData);
|
|
710
|
+
gi.ys.push(itemYData);
|
|
711
|
+
}
|
|
712
|
+
if ($.inArray(i, gi.iRows) < 0) {
|
|
713
|
+
gi.iRows.push(i);
|
|
714
|
+
gi.rows.push(row);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
calculateGroupTotals(itemYData, previousY, agr, k, row, i, iYData);
|
|
718
|
+
}
|
|
719
|
+
cmName = "y" + iYData + (aggrlen === 1 ? "" : "a" + k);
|
|
720
|
+
aggrContext.getResult(outputItem, cmName);
|
|
721
|
+
pivotInfos[cmName] = {
|
|
722
|
+
colType: 0, // standard row
|
|
723
|
+
iY: iYData,
|
|
724
|
+
y: itemYData,
|
|
725
|
+
iA: k,
|
|
726
|
+
a: agr,
|
|
727
|
+
iRows: iRows,
|
|
728
|
+
rows: rows
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
previousY = itemYData;
|
|
733
|
+
}
|
|
734
|
+
if (previousY !== null) { // if non-empty input data
|
|
735
|
+
for (k = 0; k < aggrlen; k++) {
|
|
736
|
+
finalizeGroupTotals(yIndexLength - 1, previousY, previousY, k);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (isRowTotal) {
|
|
740
|
+
for (k = 0; k < aggrlen; k++) {
|
|
741
|
+
cmName = "t" + (aggrlen === 1 ? "" : "a" + k);
|
|
742
|
+
aggrTotal = aggrContextTotalRows[k];
|
|
743
|
+
aggrTotal.getResult(outputItem, cmName);
|
|
744
|
+
gi = aggrTotal.groupInfo;
|
|
745
|
+
pivotInfos[cmName] = {
|
|
746
|
+
colType: 2, // row total
|
|
747
|
+
iA: k,
|
|
748
|
+
a: aggregates[k],
|
|
749
|
+
iRows: gi.iRows,
|
|
750
|
+
rows: gi.rows,
|
|
751
|
+
iYs: gi.iYs,
|
|
752
|
+
ys: gi.ys
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
outputItems.push(outputItem);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// *****************************
|
|
760
|
+
// The step 5: fill total footer
|
|
761
|
+
// *****************************
|
|
762
|
+
if (o.footerTotals || o.colTotals) {
|
|
763
|
+
nRows = outputItems.length;
|
|
764
|
+
for (i = 0; i < xlen; i++) {
|
|
765
|
+
summaries["x" + i] = xDimension[i].footerText || "";
|
|
766
|
+
}
|
|
767
|
+
for (i = xlen; i < colModel.length; i++) {
|
|
768
|
+
cmName = colModel[i].name;
|
|
769
|
+
aggrContext = new Aggregation(o.footerAggregator || "sum", self, options);
|
|
770
|
+
for (iRow = 0; iRow < nRows; iRow++) {
|
|
771
|
+
outputItem = outputItems[iRow];
|
|
772
|
+
aggrContext.calc(outputItem[cmName], cmName, outputItem, iRow, outputItems);
|
|
773
|
+
}
|
|
774
|
+
aggrContext.getResult(summaries, cmName);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// return the final result.
|
|
779
|
+
options.colHeaders = colHeaders;
|
|
780
|
+
return {
|
|
781
|
+
colModel: colModel,
|
|
782
|
+
additionalProperties: additionalProperties,
|
|
783
|
+
options: options,
|
|
784
|
+
rows: outputItems,
|
|
785
|
+
groupOptions: groupOptions,
|
|
786
|
+
groupHeaders: colHeaders,
|
|
787
|
+
summary: summaries
|
|
788
|
+
};
|
|
789
|
+
},
|
|
790
|
+
jqPivot: function (data, pivotOpt, gridOpt, ajaxOpt) {
|
|
791
|
+
return this.each(function () {
|
|
792
|
+
var $t = this, $self = $($t), $j = $.fn.jqGrid;
|
|
793
|
+
|
|
794
|
+
function pivot() {
|
|
795
|
+
var pivotGrid = $j.pivotSetup.call($self, data, pivotOpt),
|
|
796
|
+
gHead = pivotGrid.groupHeaders,
|
|
797
|
+
assocArraySize = function (obj) {
|
|
798
|
+
// http://stackoverflow.com/a/6700/11236
|
|
799
|
+
var size = 0, key;
|
|
800
|
+
for (key in obj) {
|
|
801
|
+
if (obj.hasOwnProperty(key)) {
|
|
802
|
+
size++;
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return size;
|
|
806
|
+
},
|
|
807
|
+
footerrow = assocArraySize(pivotGrid.summary) > 0 ? true : false,
|
|
808
|
+
groupingView = pivotGrid.groupOptions.groupingView,
|
|
809
|
+
query = jgrid.from.call($t, pivotGrid.rows), i;
|
|
810
|
+
if (!pivotOpt.skipSortByX) {
|
|
811
|
+
for (i = 0; i < groupingView.groupField.length; i++) {
|
|
812
|
+
query.orderBy(groupingView.groupField[i],
|
|
813
|
+
gridOpt != null && gridOpt.groupingView && gridOpt.groupingView.groupOrder != null && gridOpt.groupingView.groupOrder[i] === "desc" ? "d" : "a",
|
|
814
|
+
"text",
|
|
815
|
+
"");
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
pivotOpt.data = data;
|
|
819
|
+
$j.call($self, $.extend(true, {
|
|
820
|
+
datastr: $.extend(query.select(), footerrow ? { userdata: pivotGrid.summary } : {}),
|
|
821
|
+
datatype: "jsonstring",
|
|
822
|
+
footerrow: footerrow,
|
|
823
|
+
userDataOnFooter: footerrow,
|
|
824
|
+
colModel: pivotGrid.colModel,
|
|
825
|
+
additionalProperties: pivotGrid.additionalProperties,
|
|
826
|
+
pivotOptions: pivotGrid.options,
|
|
827
|
+
viewrecords: true,
|
|
828
|
+
sortname: pivotOpt.xDimension[0].dataName // ?????
|
|
829
|
+
}, pivotGrid.groupOptions, gridOpt || {}));
|
|
830
|
+
if (gHead.length) {
|
|
831
|
+
for (i = 0; i < gHead.length; i++) {
|
|
832
|
+
// Multiple calls of setGroupHeaders for one grid are wrong,
|
|
833
|
+
// but there are produces good results in case of usage
|
|
834
|
+
// useColSpanStyle: false option. The rowspan values
|
|
835
|
+
// needed be increased in case of usage useColSpanStyle: true
|
|
836
|
+
if (gHead[i] && gHead[i].groupHeaders.length) {
|
|
837
|
+
$j.setGroupHeaders.call($self, gHead[i]);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
if (pivotOpt.frozenStaticCols) {
|
|
842
|
+
$j.setFrozenColumns.call($self);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
if (typeof data === "string") {
|
|
847
|
+
$.ajax($.extend({
|
|
848
|
+
url: data,
|
|
849
|
+
dataType: "json",
|
|
850
|
+
success: function (data1) {
|
|
851
|
+
data = jgrid.getAccessor(data1, ajaxOpt && ajaxOpt.reader ? ajaxOpt.reader : "rows");
|
|
852
|
+
pivot();
|
|
853
|
+
}
|
|
854
|
+
}, ajaxOpt || {}));
|
|
855
|
+
} else {
|
|
856
|
+
pivot();
|
|
857
|
+
}
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
});
|
|
861
|
+
// end module grid.pivot
|
|
862
|
+
}));
|