subtotal
Version:
Subtotal.js is a JavaScript plugin for PivotTable.js. It renders subtotals of rows and columns with the ability to expand and collapse rows.
1,108 lines (1,097 loc) • 46.1 kB
JavaScript
(function() {
var callWithJQuery,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty,
slice = [].slice;
callWithJQuery = function(pivotModule) {
if (typeof exports === "object" && typeof module === "object") {
return pivotModule(require("jquery"));
} else if (typeof define === "function" && define.amd) {
return define(["jquery"], pivotModule);
} else {
return pivotModule(jQuery);
}
};
callWithJQuery(function($) {
var SubtotalPivotData, SubtotalRenderer, aggregatorTemplates, subtotalAggregatorTemplates, usFmtPct;
SubtotalPivotData = (function(superClass) {
var processKey;
extend(SubtotalPivotData, superClass);
function SubtotalPivotData(input, opts) {
SubtotalPivotData.__super__.constructor.call(this, input, opts);
}
processKey = function(record, totals, keys, attrs, getAggregator) {
var addKey, attr, flatKey, k, key, len, ref;
key = [];
addKey = false;
for (k = 0, len = attrs.length; k < len; k++) {
attr = attrs[k];
key.push((ref = record[attr]) != null ? ref : "null");
flatKey = key.join(String.fromCharCode(0));
if (!totals[flatKey]) {
totals[flatKey] = getAggregator(key.slice());
addKey = true;
}
totals[flatKey].push(record);
}
if (addKey) {
keys.push(key);
}
return key;
};
SubtotalPivotData.prototype.processRecord = function(record) {
var colKey, fColKey, fRowKey, flatColKey, flatRowKey, i, j, k, m, n, ref, results, rowKey;
rowKey = [];
colKey = [];
this.allTotal.push(record);
rowKey = processKey(record, this.rowTotals, this.rowKeys, this.rowAttrs, (function(_this) {
return function(key) {
return _this.aggregator(_this, key, []);
};
})(this));
colKey = processKey(record, this.colTotals, this.colKeys, this.colAttrs, (function(_this) {
return function(key) {
return _this.aggregator(_this, [], key);
};
})(this));
m = rowKey.length - 1;
n = colKey.length - 1;
if (m < 0 || n < 0) {
return;
}
results = [];
for (i = k = 0, ref = m; 0 <= ref ? k <= ref : k >= ref; i = 0 <= ref ? ++k : --k) {
fRowKey = rowKey.slice(0, i + 1);
flatRowKey = fRowKey.join(String.fromCharCode(0));
if (!this.tree[flatRowKey]) {
this.tree[flatRowKey] = {};
}
results.push((function() {
var l, ref1, results1;
results1 = [];
for (j = l = 0, ref1 = n; 0 <= ref1 ? l <= ref1 : l >= ref1; j = 0 <= ref1 ? ++l : --l) {
fColKey = colKey.slice(0, j + 1);
flatColKey = fColKey.join(String.fromCharCode(0));
if (!this.tree[flatRowKey][flatColKey]) {
this.tree[flatRowKey][flatColKey] = this.aggregator(this, fRowKey, fColKey);
}
results1.push(this.tree[flatRowKey][flatColKey].push(record));
}
return results1;
}).call(this));
}
return results;
};
return SubtotalPivotData;
})($.pivotUtilities.PivotData);
$.pivotUtilities.SubtotalPivotData = SubtotalPivotData;
SubtotalRenderer = function(pivotData, opts) {
var addClass, adjustAxisHeader, allTotal, arrowCollapsed, arrowExpanded, buildAxisHeader, buildColAxisHeaders, buildColHeader, buildColTotals, buildColTotalsHeader, buildGrandTotal, buildRowAxisHeaders, buildRowHeader, buildRowTotalsHeader, buildValues, classColCollapsed, classColExpanded, classColHide, classColShow, classCollapsed, classExpanded, classRowCollapsed, classRowExpanded, classRowHide, classRowShow, clickStatusCollapsed, clickStatusExpanded, colAttrs, colKeys, colTotals, collapseAxis, collapseAxisHeaders, collapseChildCol, collapseChildRow, collapseCol, collapseHiddenColSubtotal, collapseRow, collapseShowColSubtotal, collapseShowRowSubtotal, createElement, defaults, expandAxis, expandChildCol, expandChildRow, expandCol, expandHideColSubtotal, expandHideRowSubtotal, expandRow, expandShowColSubtotal, expandShowRowSubtotal, getHeaderText, getTableEventHandlers, hasClass, hideChildCol, hideChildRow, main, processKeys, removeClass, replaceClass, rowAttrs, rowKeys, rowTotals, setAttributes, showChildCol, showChildRow, tree;
defaults = {
table: {
clickCallback: null
},
localeStrings: {
totals: "Totals",
subtotalOf: "Subtotal of"
},
arrowCollapsed: "\u25B6",
arrowExpanded: "\u25E2",
rowSubtotalDisplay: {
displayOnTop: true,
disableFrom: 99999,
collapseAt: 99999,
hideOnExpand: false,
disableExpandCollapse: false
},
colSubtotalDisplay: {
displayOnTop: true,
disableFrom: 99999,
collapseAt: 99999,
hideOnExpand: false,
disableExpandCollapse: false
}
};
opts = $.extend(true, {}, defaults, opts);
if (opts.rowSubtotalDisplay.disableSubtotal) {
opts.rowSubtotalDisplay.disableFrom = 0;
}
if (typeof opts.rowSubtotalDisplay.disableAfter !== 'undefined' && opts.rowSubtotalDisplay.disableAfter !== null) {
opts.rowSubtotalDisplay.disableFrom = opts.rowSubtotalDisplay.disableAfter + 1;
}
if (typeof opts.rowSubtotalDisplay.collapseAt !== 'undefined' && opts.collapseRowsAt !== null) {
opts.rowSubtotalDisplay.collapseAt = opts.collapseRowsAt;
}
if (opts.colSubtotalDisplay.disableSubtotal) {
opts.colSubtotalDisplay.disableFrom = 0;
}
if (typeof opts.colSubtotalDisplay.disableAfter !== 'undefined' && opts.colSubtotalDisplay.disableAfter !== null) {
opts.colSubtotalDisplay.disableFrom = opts.colSubtotalDisplay.disableAfter + 1;
}
if (typeof opts.colSubtotalDisplay.collapseAt !== 'undefined' && opts.collapseColsAt !== null) {
opts.colSubtotalDisplay.collapseAt = opts.collapseColsAt;
}
colAttrs = pivotData.colAttrs;
rowAttrs = pivotData.rowAttrs;
rowKeys = pivotData.getRowKeys();
colKeys = pivotData.getColKeys();
tree = pivotData.tree;
rowTotals = pivotData.rowTotals;
colTotals = pivotData.colTotals;
allTotal = pivotData.allTotal;
classRowHide = "rowhide";
classRowShow = "rowshow";
classColHide = "colhide";
classColShow = "colshow";
clickStatusExpanded = "expanded";
clickStatusCollapsed = "collapsed";
classExpanded = "expanded";
classCollapsed = "collapsed";
classRowExpanded = "rowexpanded";
classRowCollapsed = "rowcollapsed";
classColExpanded = "colexpanded";
classColCollapsed = "colcollapsed";
arrowExpanded = opts.arrowExpanded;
arrowCollapsed = opts.arrowCollapsed;
hasClass = function(element, className) {
var regExp;
regExp = new RegExp("(?:^|\\s)" + className + "(?!\\S)", "g");
return element.className.match(regExp) !== null;
};
removeClass = function(element, className) {
var k, len, name, ref, regExp, results;
ref = className.split(" ");
results = [];
for (k = 0, len = ref.length; k < len; k++) {
name = ref[k];
regExp = new RegExp("(?:^|\\s)" + name + "(?!\\S)", "g");
results.push(element.className = element.className.replace(regExp, ''));
}
return results;
};
addClass = function(element, className) {
var k, len, name, ref, results;
ref = className.split(" ");
results = [];
for (k = 0, len = ref.length; k < len; k++) {
name = ref[k];
if (!hasClass(element, name)) {
results.push(element.className += " " + name);
} else {
results.push(void 0);
}
}
return results;
};
replaceClass = function(element, replaceClassName, byClassName) {
removeClass(element, replaceClassName);
return addClass(element, byClassName);
};
createElement = function(elementType, className, textContent, attributes, eventHandlers) {
var attr, e, event, handler, val;
e = document.createElement(elementType);
if (className != null) {
e.className = className;
}
if (textContent != null) {
e.textContent = textContent;
}
if (attributes != null) {
for (attr in attributes) {
if (!hasProp.call(attributes, attr)) continue;
val = attributes[attr];
e.setAttribute(attr, val);
}
}
if (eventHandlers != null) {
for (event in eventHandlers) {
if (!hasProp.call(eventHandlers, event)) continue;
handler = eventHandlers[event];
e.addEventListener(event, handler);
}
}
return e;
};
setAttributes = function(e, attrs) {
var a, results, v;
results = [];
for (a in attrs) {
if (!hasProp.call(attrs, a)) continue;
v = attrs[a];
results.push(e.setAttribute(a, v));
}
return results;
};
processKeys = function(keysArr, className, opts) {
var headers, lastIdx, row;
lastIdx = keysArr[0].length - 1;
headers = {
children: []
};
row = 0;
keysArr.reduce((function(_this) {
return function(val0, k0) {
var col;
col = 0;
k0.reduce(function(acc, curVal, curIdx, arr) {
var i, k, key, node, ref;
if (!acc[curVal]) {
key = k0.slice(0, col + 1);
acc[curVal] = {
row: row,
col: col,
descendants: 0,
children: [],
text: curVal,
key: key,
flatKey: key.join(String.fromCharCode(0)),
firstLeaf: null,
leaves: 0,
parent: col !== 0 ? acc : null,
th: createElement("th", className, curVal),
childrenSpan: 0
};
acc.children.push(curVal);
}
if (col > 0) {
acc.descendants++;
}
col++;
if (curIdx === lastIdx) {
node = headers;
for (i = k = 0, ref = lastIdx - 1; 0 <= ref ? k <= ref : k >= ref; i = 0 <= ref ? ++k : --k) {
if (!(lastIdx > 0)) {
continue;
}
node[k0[i]].leaves++;
if (!node[k0[i]].firstLeaf) {
node[k0[i]].firstLeaf = acc[curVal];
}
node = node[k0[i]];
}
return headers;
}
return acc[curVal];
}, headers);
row++;
return headers;
};
})(this), headers);
return headers;
};
buildAxisHeader = function(axisHeaders, col, attrs, opts) {
var ah, arrow, hClass;
ah = {
text: attrs[col],
expandedCount: 0,
expandables: 0,
attrHeaders: [],
clickStatus: clickStatusExpanded,
onClick: collapseAxis
};
arrow = arrowExpanded + " ";
hClass = classExpanded;
if (col >= opts.collapseAt) {
arrow = arrowCollapsed + " ";
hClass = classCollapsed;
ah.clickStatus = clickStatusCollapsed;
ah.onClick = expandAxis;
}
if (col === attrs.length - 1 || col >= opts.disableFrom || opts.disableExpandCollapse) {
arrow = "";
}
ah.th = createElement("th", "pvtAxisLabel " + hClass, "" + arrow + ah.text);
if (col < attrs.length - 1 && col < opts.disableFrom && !opts.disableExpandCollapse) {
ah.th.onclick = function(event) {
event = event || window.event;
return ah.onClick(axisHeaders, col, attrs, opts);
};
}
axisHeaders.ah.push(ah);
return ah;
};
buildColAxisHeaders = function(thead, rowAttrs, colAttrs, opts) {
var ah, attr, axisHeaders, col, k, len;
axisHeaders = {
collapseAttrHeader: collapseCol,
expandAttrHeader: expandCol,
ah: []
};
for (col = k = 0, len = colAttrs.length; k < len; col = ++k) {
attr = colAttrs[col];
ah = buildAxisHeader(axisHeaders, col, colAttrs, opts.colSubtotalDisplay);
ah.tr = createElement("tr");
if (col === 0 && rowAttrs.length !== 0) {
ah.tr.appendChild(createElement("th", null, null, {
colspan: rowAttrs.length,
rowspan: colAttrs.length
}));
}
ah.tr.appendChild(ah.th);
thead.appendChild(ah.tr);
}
return axisHeaders;
};
buildRowAxisHeaders = function(thead, rowAttrs, colAttrs, opts) {
var ah, axisHeaders, col, k, ref, th;
axisHeaders = {
collapseAttrHeader: collapseRow,
expandAttrHeader: expandRow,
ah: [],
tr: createElement("tr")
};
for (col = k = 0, ref = rowAttrs.length - 1; 0 <= ref ? k <= ref : k >= ref; col = 0 <= ref ? ++k : --k) {
ah = buildAxisHeader(axisHeaders, col, rowAttrs, opts.rowSubtotalDisplay);
axisHeaders.tr.appendChild(ah.th);
}
if (colAttrs.length !== 0) {
th = createElement("th");
axisHeaders.tr.appendChild(th);
}
thead.appendChild(axisHeaders.tr);
return axisHeaders;
};
getHeaderText = function(h, attrs, opts) {
var arrow;
arrow = " " + arrowExpanded + " ";
if (h.col === attrs.length - 1 || h.col >= opts.disableFrom || opts.disableExpandCollapse || h.children.length === 0) {
arrow = "";
}
return "" + arrow + h.text;
};
buildColHeader = function(axisHeaders, attrHeaders, h, rowAttrs, colAttrs, node, opts) {
var ah, chKey, k, len, ref, ref1;
ref = h.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
buildColHeader(axisHeaders, attrHeaders, h[chKey], rowAttrs, colAttrs, node, opts);
}
ah = axisHeaders.ah[h.col];
ah.attrHeaders.push(h);
h.node = node.counter;
h.onClick = collapseCol;
addClass(h.th, classColShow + " col" + h.row + " colcol" + h.col + " " + classColExpanded);
h.th.setAttribute("data-colnode", h.node);
if (h.children.length !== 0) {
h.th.colSpan = h.childrenSpan;
}
if (h.children.length === 0 && rowAttrs.length !== 0) {
h.th.rowSpan = 2;
}
h.th.textContent = getHeaderText(h, colAttrs, opts.colSubtotalDisplay);
if (h.children.length !== 0 && h.col < opts.colSubtotalDisplay.disableFrom) {
ah.expandables++;
ah.expandedCount += 1;
if (!opts.colSubtotalDisplay.hideOnExpand) {
h.th.colSpan++;
}
if (!opts.colSubtotalDisplay.disableExpandCollapse) {
h.th.onclick = function(event) {
event = event || window.event;
return h.onClick(axisHeaders, h, opts.colSubtotalDisplay);
};
}
h.sTh = createElement("th", "pvtColLabelFiller " + classColShow + " col" + h.row + " colcol" + h.col + " " + classColExpanded);
h.sTh.setAttribute("data-colnode", h.node);
h.sTh.rowSpan = colAttrs.length - h.col;
if (opts.colSubtotalDisplay.hideOnExpand) {
replaceClass(h.sTh, classColShow, classColHide);
}
h[h.children[0]].tr.appendChild(h.sTh);
}
if ((ref1 = h.parent) != null) {
ref1.childrenSpan += h.th.colSpan;
}
h.clickStatus = clickStatusExpanded;
ah.tr.appendChild(h.th);
h.tr = ah.tr;
attrHeaders.push(h);
return node.counter++;
};
buildRowTotalsHeader = function(tr, rowAttrs, colAttrs) {
var th;
th = createElement("th", "pvtTotalLabel rowTotal", opts.localeStrings.totals, {
rowspan: colAttrs.length === 0 ? 1 : colAttrs.length + (rowAttrs.length === 0 ? 0 : 1)
});
return tr.appendChild(th);
};
buildRowHeader = function(tbody, axisHeaders, attrHeaders, h, rowAttrs, colAttrs, node, opts) {
var ah, chKey, firstChild, k, len, ref, ref1;
ref = h.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
buildRowHeader(tbody, axisHeaders, attrHeaders, h[chKey], rowAttrs, colAttrs, node, opts);
}
ah = axisHeaders.ah[h.col];
ah.attrHeaders.push(h);
h.node = node.counter;
h.onClick = collapseRow;
if (h.children.length !== 0) {
firstChild = h[h.children[0]];
}
addClass(h.th, classRowShow + " row" + h.row + " rowcol" + h.col + " " + classRowExpanded);
h.th.setAttribute("data-rownode", h.node);
if (h.col === rowAttrs.length - 1 && colAttrs.length !== 0) {
h.th.colSpan = 2;
}
if (h.children.length !== 0) {
h.th.rowSpan = h.childrenSpan;
}
h.th.textContent = getHeaderText(h, rowAttrs, opts.rowSubtotalDisplay);
h.tr = createElement("tr", "row" + h.row);
h.tr.appendChild(h.th);
if (h.children.length === 0) {
tbody.appendChild(h.tr);
} else {
tbody.insertBefore(h.tr, firstChild.tr);
}
if (h.children.length !== 0 && h.col < opts.rowSubtotalDisplay.disableFrom) {
++ah.expandedCount;
++ah.expandables;
if (!opts.rowSubtotalDisplay.disableExpandCollapse) {
h.th.onclick = function(event) {
event = event || window.event;
return h.onClick(axisHeaders, h, opts.rowSubtotalDisplay);
};
}
h.sTh = createElement("th", "pvtRowLabelFiller row" + h.row + " rowcol" + h.col + " " + classRowExpanded + " " + classRowShow);
if (opts.rowSubtotalDisplay.hideOnExpand) {
replaceClass(h.sTh, classRowShow, classRowHide);
}
h.sTh.setAttribute("data-rownode", h.node);
h.sTh.colSpan = rowAttrs.length - (h.col + 1) + (colAttrs.length !== 0 ? 1 : 0);
if (opts.rowSubtotalDisplay.displayOnTop) {
h.tr.appendChild(h.sTh);
} else {
h.th.rowSpan += 1;
h.sTr = createElement("tr", "row" + h.row);
h.sTr.appendChild(h.sTh);
tbody.appendChild(h.sTr);
}
}
if (h.children.length !== 0) {
h.th.rowSpan++;
}
if ((ref1 = h.parent) != null) {
ref1.childrenSpan += h.th.rowSpan;
}
h.clickStatus = clickStatusExpanded;
attrHeaders.push(h);
return node.counter++;
};
getTableEventHandlers = function(value, rowKey, colKey, rowAttrs, colAttrs, opts) {
var attr, event, eventHandlers, filters, handler, i, ref, ref1;
if (!((ref = opts.table) != null ? ref.eventHandlers : void 0)) {
return;
}
eventHandlers = {};
ref1 = opts.table.eventHandlers;
for (event in ref1) {
if (!hasProp.call(ref1, event)) continue;
handler = ref1[event];
filters = {};
for (i in colAttrs) {
if (!hasProp.call(colAttrs, i)) continue;
attr = colAttrs[i];
if (colKey[i] != null) {
filters[attr] = colKey[i];
}
}
for (i in rowAttrs) {
if (!hasProp.call(rowAttrs, i)) continue;
attr = rowAttrs[i];
if (rowKey[i] != null) {
filters[attr] = rowKey[i];
}
}
eventHandlers[event] = function(e) {
return handler(e, value, filters, pivotData);
};
}
return eventHandlers;
};
buildValues = function(tbody, colAttrHeaders, rowAttrHeaders, rowAttrs, colAttrs, opts) {
var aggregator, ch, cls, k, l, len, len1, rCls, ref, results, rh, td, totalAggregator, tr, val;
results = [];
for (k = 0, len = rowAttrHeaders.length; k < len; k++) {
rh = rowAttrHeaders[k];
if (!(rh.col === rowAttrs.length - 1 || (rh.children.length !== 0 && rh.col < opts.rowSubtotalDisplay.disableFrom))) {
continue;
}
rCls = "pvtVal row" + rh.row + " rowcol" + rh.col + " " + classRowExpanded;
if (rh.children.length > 0) {
rCls += " pvtRowSubtotal";
rCls += opts.rowSubtotalDisplay.hideOnExpand ? " " + classRowHide : " " + classRowShow;
} else {
rCls += " " + classRowShow;
}
tr = rh.sTr ? rh.sTr : rh.tr;
for (l = 0, len1 = colAttrHeaders.length; l < len1; l++) {
ch = colAttrHeaders[l];
if (!(ch.col === colAttrs.length - 1 || (ch.children.length !== 0 && ch.col < opts.colSubtotalDisplay.disableFrom))) {
continue;
}
aggregator = (ref = tree[rh.flatKey][ch.flatKey]) != null ? ref : {
value: (function() {
return null;
}),
format: function() {
return "";
}
};
val = aggregator.value();
cls = " " + rCls + " col" + ch.row + " colcol" + ch.col + " " + classColExpanded;
if (ch.children.length > 0) {
cls += " pvtColSubtotal";
cls += opts.colSubtotalDisplay.hideOnExpand ? " " + classColHide : " " + classColShow;
} else {
cls += " " + classColShow;
}
td = createElement("td", cls, aggregator.format(val), {
"data-value": val,
"data-rownode": rh.node,
"data-colnode": ch.node
}, getTableEventHandlers(val, rh.key, ch.key, rowAttrs, colAttrs, opts));
tr.appendChild(td);
}
totalAggregator = rowTotals[rh.flatKey];
val = totalAggregator.value();
td = createElement("td", "pvtTotal rowTotal " + rCls, totalAggregator.format(val), {
"data-value": val,
"data-row": "row" + rh.row,
"data-rowcol": "col" + rh.col,
"data-rownode": rh.node
});
getTableEventHandlers(val, rh.key, [], rowAttrs, colAttrs, opts);
results.push(tr.appendChild(td));
}
return results;
};
buildColTotalsHeader = function(rowAttrs, colAttrs) {
var colspan, th, tr;
tr = createElement("tr");
colspan = rowAttrs.length + (colAttrs.length === 0 ? 0 : 1);
th = createElement("th", "pvtTotalLabel colTotal", opts.localeStrings.totals, {
colspan: colspan
});
tr.appendChild(th);
return tr;
};
buildColTotals = function(tr, attrHeaders, rowAttrs, colAttrs, opts) {
var clsNames, h, k, len, results, td, totalAggregator, val;
results = [];
for (k = 0, len = attrHeaders.length; k < len; k++) {
h = attrHeaders[k];
if (!(h.col === colAttrs.length - 1 || (h.children.length !== 0 && h.col < opts.colSubtotalDisplay.disableFrom))) {
continue;
}
clsNames = "pvtVal pvtTotal colTotal " + classColExpanded + " col" + h.row + " colcol" + h.col;
if (h.children.length !== 0) {
clsNames += " pvtColSubtotal";
clsNames += opts.colSubtotalDisplay.hideOnExpand ? " " + classColHide : " " + classColShow;
} else {
clsNames += " " + classColShow;
}
totalAggregator = colTotals[h.flatKey];
val = totalAggregator.value();
td = createElement("td", clsNames, totalAggregator.format(val), {
"data-value": val,
"data-for": "col" + h.col,
"data-colnode": "" + h.node
}, getTableEventHandlers(val, [], h.key, rowAttrs, colAttrs, opts));
results.push(tr.appendChild(td));
}
return results;
};
buildGrandTotal = function(tbody, tr, rowAttrs, colAttrs, opts) {
var td, totalAggregator, val;
totalAggregator = allTotal;
val = totalAggregator.value();
td = createElement("td", "pvtGrandTotal", totalAggregator.format(val), {
"data-value": val
}, getTableEventHandlers(val, [], [], rowAttrs, colAttrs, opts));
tr.appendChild(td);
return tbody.appendChild(tr);
};
collapseAxisHeaders = function(axisHeaders, col, opts) {
var ah, collapsible, i, k, ref, ref1, results;
collapsible = Math.min(axisHeaders.ah.length - 2, opts.disableFrom - 1);
if (col > collapsible) {
return;
}
results = [];
for (i = k = ref = col, ref1 = collapsible; ref <= ref1 ? k <= ref1 : k >= ref1; i = ref <= ref1 ? ++k : --k) {
ah = axisHeaders.ah[i];
replaceClass(ah.th, classExpanded, classCollapsed);
ah.th.textContent = " " + arrowCollapsed + " " + ah.text;
ah.clickStatus = clickStatusCollapsed;
results.push(ah.onClick = expandAxis);
}
return results;
};
adjustAxisHeader = function(axisHeaders, col, opts) {
var ah;
ah = axisHeaders.ah[col];
if (ah.expandedCount === 0) {
return collapseAxisHeaders(axisHeaders, col, opts);
} else if (ah.expandedCount === ah.expandables) {
replaceClass(ah.th, classCollapsed, classExpanded);
ah.th.textContent = " " + arrowExpanded + " " + ah.text;
ah.clickStatus = clickStatusExpanded;
return ah.onClick = collapseAxis;
}
};
hideChildCol = function(ch) {
return $(ch.th).closest('table.pvtTable').find("tbody tr td[data-colnode=\"" + ch.node + "\"], th[data-colnode=\"" + ch.node + "\"]").removeClass(classColShow).addClass(classColHide);
};
collapseHiddenColSubtotal = function(h, opts) {
$(h.th).closest('table.pvtTable').find("tbody tr td[data-colnode=\"" + h.node + "\"], th[data-colnode=\"" + h.node + "\"]").removeClass(classColExpanded).addClass(classColCollapsed);
if (h.children.length !== 0) {
h.th.textContent = " " + arrowCollapsed + " " + h.text;
}
return h.th.colSpan = 1;
};
collapseShowColSubtotal = function(h, opts) {
$(h.th).closest('table.pvtTable').find("tbody tr td[data-colnode=\"" + h.node + "\"], th[data-colnode=\"" + h.node + "\"]").removeClass(classColExpanded).addClass(classColCollapsed).removeClass(classColHide).addClass(classColShow);
if (h.children.length !== 0) {
h.th.textContent = " " + arrowCollapsed + " " + h.text;
}
return h.th.colSpan = 1;
};
collapseChildCol = function(ch, h) {
var chKey, k, len, ref;
ref = ch.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
if (hasClass(ch[chKey].th, classColShow)) {
collapseChildCol(ch[chKey], h);
}
}
return hideChildCol(ch);
};
collapseCol = function(axisHeaders, h, opts) {
var chKey, colSpan, k, len, p, ref;
colSpan = h.th.colSpan - 1;
ref = h.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
if (hasClass(h[chKey].th, classColShow)) {
collapseChildCol(h[chKey], h);
}
}
if (h.col < opts.disableFrom) {
if (hasClass(h.th, classColHide)) {
collapseHiddenColSubtotal(h, opts);
} else {
collapseShowColSubtotal(h, opts);
}
}
p = h.parent;
while (p) {
p.th.colSpan -= colSpan;
p = p.parent;
}
h.clickStatus = clickStatusCollapsed;
h.onClick = expandCol;
axisHeaders.ah[h.col].expandedCount--;
return adjustAxisHeader(axisHeaders, h.col, opts);
};
showChildCol = function(ch) {
return $(ch.th).closest('table.pvtTable').find("tbody tr td[data-colnode=\"" + ch.node + "\"], th[data-colnode=\"" + ch.node + "\"]").removeClass(classColHide).addClass(classColShow);
};
expandHideColSubtotal = function(h) {
$(h.th).closest('table.pvtTable').find("tbody tr td[data-colnode=\"" + h.node + "\"], th[data-colnode=\"" + h.node + "\"]").removeClass(classColCollapsed + " " + classColShow).addClass(classColExpanded + " " + classColHide);
replaceClass(h.th, classColHide, classColShow);
return h.th.textContent = " " + arrowExpanded + " " + h.text;
};
expandShowColSubtotal = function(h) {
$(h.th).closest('table.pvtTable').find("tbody tr td[data-colnode=\"" + h.node + "\"], th[data-colnode=\"" + h.node + "\"]").removeClass(classColCollapsed + " " + classColHide).addClass(classColExpanded + " " + classColShow);
h.th.colSpan++;
return h.th.textContent = " " + arrowExpanded + " " + h.text;
};
expandChildCol = function(ch, opts) {
var chKey, k, len, ref, results;
if (ch.children.length !== 0 && opts.hideOnExpand && ch.clickStatus === clickStatusExpanded) {
replaceClass(ch.th, classColHide, classColShow);
} else {
showChildCol(ch);
}
if (ch.sTh && ch.clickStatus === clickStatusExpanded && opts.hideOnExpand) {
replaceClass(ch.sTh, classColShow, classColHide);
}
if (ch.clickStatus === clickStatusExpanded || ch.col >= opts.disableFrom) {
ref = ch.children;
results = [];
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
results.push(expandChildCol(ch[chKey], opts));
}
return results;
}
};
expandCol = function(axisHeaders, h, opts) {
var ch, chKey, colSpan, k, len, p, ref;
if (h.clickStatus === clickStatusExpanded) {
adjustAxisHeader(axisHeaders, h.col, opts);
return;
}
colSpan = 0;
ref = h.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
ch = h[chKey];
expandChildCol(ch, opts);
colSpan += ch.th.colSpan;
}
h.th.colSpan = colSpan;
if (h.col < opts.disableFrom) {
if (opts.hideOnExpand) {
expandHideColSubtotal(h);
--colSpan;
} else {
expandShowColSubtotal(h);
}
}
p = h.parent;
while (p) {
p.th.colSpan += colSpan;
p = p.parent;
}
h.clickStatus = clickStatusExpanded;
h.onClick = collapseCol;
axisHeaders.ah[h.col].expandedCount++;
return adjustAxisHeader(axisHeaders, h.col, opts);
};
hideChildRow = function(ch, opts) {
var cell, k, l, len, len1, ref, ref1, results;
ref = ch.tr.querySelectorAll("th, td");
for (k = 0, len = ref.length; k < len; k++) {
cell = ref[k];
replaceClass(cell, classRowShow, classRowHide);
}
if (ch.sTr) {
ref1 = ch.sTr.querySelectorAll("th, td");
results = [];
for (l = 0, len1 = ref1.length; l < len1; l++) {
cell = ref1[l];
results.push(replaceClass(cell, classRowShow, classRowHide));
}
return results;
}
};
collapseShowRowSubtotal = function(h, opts) {
var cell, k, l, len, len1, ref, ref1, results;
h.th.textContent = " " + arrowCollapsed + " " + h.text;
ref = h.tr.querySelectorAll("th, td");
for (k = 0, len = ref.length; k < len; k++) {
cell = ref[k];
removeClass(cell, classRowExpanded + " " + classRowHide);
addClass(cell, classRowCollapsed + " " + classRowShow);
}
if (h.sTr) {
ref1 = h.sTr.querySelectorAll("th, td");
results = [];
for (l = 0, len1 = ref1.length; l < len1; l++) {
cell = ref1[l];
removeClass(cell, classRowExpanded + " " + classRowHide);
results.push(addClass(cell, classRowCollapsed + " " + classRowShow));
}
return results;
}
};
collapseChildRow = function(ch, h, opts) {
var chKey, k, len, ref;
ref = ch.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
collapseChildRow(ch[chKey], h, opts);
}
return hideChildRow(ch, opts);
};
collapseRow = function(axisHeaders, h, opts) {
var chKey, k, len, ref;
ref = h.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
collapseChildRow(h[chKey], h, opts);
}
collapseShowRowSubtotal(h, opts);
h.clickStatus = clickStatusCollapsed;
h.onClick = expandRow;
axisHeaders.ah[h.col].expandedCount--;
return adjustAxisHeader(axisHeaders, h.col, opts);
};
showChildRow = function(ch, opts) {
var cell, k, l, len, len1, ref, ref1, results;
ref = ch.tr.querySelectorAll("th, td");
for (k = 0, len = ref.length; k < len; k++) {
cell = ref[k];
replaceClass(cell, classRowHide, classRowShow);
}
if (ch.sTr) {
ref1 = ch.sTr.querySelectorAll("th, td");
results = [];
for (l = 0, len1 = ref1.length; l < len1; l++) {
cell = ref1[l];
results.push(replaceClass(cell, classRowHide, classRowShow));
}
return results;
}
};
expandShowRowSubtotal = function(h, opts) {
var cell, k, l, len, len1, ref, ref1, results;
h.th.textContent = " " + arrowExpanded + " " + h.text;
ref = h.tr.querySelectorAll("th, td");
for (k = 0, len = ref.length; k < len; k++) {
cell = ref[k];
removeClass(cell, classRowCollapsed + " " + classRowHide);
addClass(cell, classRowExpanded + " " + classRowShow);
}
if (h.sTr) {
ref1 = h.sTr.querySelectorAll("th, td");
results = [];
for (l = 0, len1 = ref1.length; l < len1; l++) {
cell = ref1[l];
removeClass(cell, classRowCollapsed + " " + classRowHide);
results.push(addClass(cell, classRowExpanded + " " + classRowShow));
}
return results;
}
};
expandHideRowSubtotal = function(h, opts) {
var cell, k, l, len, len1, ref, ref1, results;
h.th.textContent = " " + arrowExpanded + " " + h.text;
ref = h.tr.querySelectorAll("th, td");
for (k = 0, len = ref.length; k < len; k++) {
cell = ref[k];
removeClass(cell, classRowCollapsed + " " + classRowShow);
addClass(cell, classRowExpanded + " " + classRowHide);
}
removeClass(h.th, classRowCollapsed + " " + classRowHide);
addClass(cell, classRowExpanded + " " + classRowShow);
if (h.sTr) {
ref1 = h.sTr.querySelectorAll("th, td");
results = [];
for (l = 0, len1 = ref1.length; l < len1; l++) {
cell = ref1[l];
removeClass(cell, classRowCollapsed + " " + classRowShow);
results.push(addClass(cell, classRowExpanded + " " + classRowHide));
}
return results;
}
};
expandChildRow = function(ch, opts) {
var chKey, k, len, ref, results;
if (ch.children.length !== 0 && opts.hideOnExpand && ch.clickStatus === clickStatusExpanded) {
replaceClass(ch.th, classRowHide, classRowShow);
} else {
showChildRow(ch, opts);
}
if (ch.sTh && ch.clickStatus === clickStatusExpanded && opts.hideOnExpand) {
replaceClass(ch.sTh, classRowShow, classRowHide);
}
if (ch.clickStatus === clickStatusExpanded || ch.col >= opts.disableFrom) {
ref = ch.children;
results = [];
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
results.push(expandChildRow(ch[chKey], opts));
}
return results;
}
};
expandRow = function(axisHeaders, h, opts) {
var ch, chKey, k, len, ref;
if (h.clickStatus === clickStatusExpanded) {
adjustAxisHeader(axisHeaders, h.col, opts);
return;
}
ref = h.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
ch = h[chKey];
expandChildRow(ch, opts);
}
if (h.children.length !== 0) {
if (opts.hideOnExpand) {
expandHideRowSubtotal(h, opts);
} else {
expandShowRowSubtotal(h, opts);
}
}
h.clickStatus = clickStatusExpanded;
h.onClick = collapseRow;
axisHeaders.ah[h.col].expandedCount++;
return adjustAxisHeader(axisHeaders, h.col, opts);
};
collapseAxis = function(axisHeaders, col, attrs, opts) {
var collapsible, h, i, k, ref, ref1, results;
collapsible = Math.min(attrs.length - 2, opts.disableFrom - 1);
if (col > collapsible) {
return;
}
results = [];
for (i = k = ref = collapsible, ref1 = col; k >= ref1; i = k += -1) {
results.push((function() {
var l, len, ref2, results1;
ref2 = axisHeaders.ah[i].attrHeaders;
results1 = [];
for (l = 0, len = ref2.length; l < len; l++) {
h = ref2[l];
if (h.clickStatus === clickStatusExpanded && h.children.length !== 0) {
results1.push(axisHeaders.collapseAttrHeader(axisHeaders, h, opts));
}
}
return results1;
})());
}
return results;
};
expandAxis = function(axisHeaders, col, attrs, opts) {
var ah, h, i, k, ref, results;
ah = axisHeaders.ah[col];
results = [];
for (i = k = 0, ref = col; 0 <= ref ? k <= ref : k >= ref; i = 0 <= ref ? ++k : --k) {
results.push((function() {
var l, len, ref1, results1;
ref1 = axisHeaders.ah[i].attrHeaders;
results1 = [];
for (l = 0, len = ref1.length; l < len; l++) {
h = ref1[l];
results1.push(axisHeaders.expandAttrHeader(axisHeaders, h, opts));
}
return results1;
})());
}
return results;
};
main = function(rowAttrs, rowKeys, colAttrs, colKeys) {
var chKey, colAttrHeaders, colAxisHeaders, colKeyHeaders, k, l, len, len1, node, ref, ref1, result, rowAttrHeaders, rowAxisHeaders, rowKeyHeaders, tbody, thead, tr;
rowAttrHeaders = [];
colAttrHeaders = [];
if (colAttrs.length !== 0 && colKeys.length !== 0) {
colKeyHeaders = processKeys(colKeys, "pvtColLabel");
}
if (rowAttrs.length !== 0 && rowKeys.length !== 0) {
rowKeyHeaders = processKeys(rowKeys, "pvtRowLabel");
}
result = createElement("table", "pvtTable", null, {
style: "display: none;"
});
thead = createElement("thead");
result.appendChild(thead);
if (colAttrs.length !== 0) {
colAxisHeaders = buildColAxisHeaders(thead, rowAttrs, colAttrs, opts);
node = {
counter: 0
};
ref = colKeyHeaders.children;
for (k = 0, len = ref.length; k < len; k++) {
chKey = ref[k];
buildColHeader(colAxisHeaders, colAttrHeaders, colKeyHeaders[chKey], rowAttrs, colAttrs, node, opts);
}
buildRowTotalsHeader(colAxisHeaders.ah[0].tr, rowAttrs, colAttrs);
}
tbody = createElement("tbody");
result.appendChild(tbody);
if (rowAttrs.length !== 0) {
rowAxisHeaders = buildRowAxisHeaders(thead, rowAttrs, colAttrs, opts);
if (colAttrs.length === 0) {
buildRowTotalsHeader(rowAxisHeaders.tr, rowAttrs, colAttrs);
}
node = {
counter: 0
};
ref1 = rowKeyHeaders.children;
for (l = 0, len1 = ref1.length; l < len1; l++) {
chKey = ref1[l];
buildRowHeader(tbody, rowAxisHeaders, rowAttrHeaders, rowKeyHeaders[chKey], rowAttrs, colAttrs, node, opts);
}
}
buildValues(tbody, colAttrHeaders, rowAttrHeaders, rowAttrs, colAttrs, opts);
tr = buildColTotalsHeader(rowAttrs, colAttrs);
if (colAttrs.length > 0) {
buildColTotals(tr, colAttrHeaders, rowAttrs, colAttrs, opts);
}
buildGrandTotal(tbody, tr, rowAttrs, colAttrs, opts);
collapseAxis(colAxisHeaders, opts.colSubtotalDisplay.collapseAt, colAttrs, opts.colSubtotalDisplay);
collapseAxis(rowAxisHeaders, opts.rowSubtotalDisplay.collapseAt, rowAttrs, opts.rowSubtotalDisplay);
result.setAttribute("data-numrows", rowKeys.length);
result.setAttribute("data-numcols", colKeys.length);
result.style.display = "";
return result;
};
return main(rowAttrs, rowKeys, colAttrs, colKeys);
};
$.pivotUtilities.subtotal_renderers = {
"Table With Subtotal": function(pvtData, opts) {
return SubtotalRenderer(pvtData, opts);
},
"Table With Subtotal Bar Chart": function(pvtData, opts) {
return $(SubtotalRenderer(pvtData, opts)).barchart();
},
"Table With Subtotal Heatmap": function(pvtData, opts) {
return $(SubtotalRenderer(pvtData, opts)).heatmap("heatmap", opts);
},
"Table With Subtotal Row Heatmap": function(pvtData, opts) {
return $(SubtotalRenderer(pvtData, opts)).heatmap("rowheatmap", opts);
},
"Table With Subtotal Col Heatmap": function(pvtData, opts) {
return $(SubtotalRenderer(pvtData, opts)).heatmap("colheatmap", opts);
}
};
usFmtPct = $.pivotUtilities.numberFormat({
digitsAfterDecimal: 1,
scaler: 100,
suffix: "%"
});
aggregatorTemplates = $.pivotUtilities.aggregatorTemplates;
subtotalAggregatorTemplates = {
fractionOf: function(wrapped, type, formatter) {
if (type == null) {
type = "row";
}
if (formatter == null) {
formatter = usFmtPct;
}
return function() {
var x;
x = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return function(data, rowKey, colKey) {
if (typeof rowKey === "undefined") {
rowKey = [];
}
if (typeof colKey === "undefined") {
colKey = [];
}
return {
selector: {
row: [rowKey.slice(0, -1), []],
col: [[], colKey.slice(0, -1)]
}[type],
inner: wrapped.apply(null, x)(data, rowKey, colKey),
push: function(record) {
return this.inner.push(record);
},
format: formatter,
value: function() {
return this.inner.value() / data.getAggregator.apply(data, this.selector).inner.value();
},
numInputs: wrapped.apply(null, x)().numInputs
};
};
};
}
};
$.pivotUtilities.subtotalAggregatorTemplates = subtotalAggregatorTemplates;
return $.pivotUtilities.subtotal_aggregators = (function(tpl, sTpl) {
return {
"Sum As Fraction Of Parent Row": sTpl.fractionOf(tpl.sum(), "row", usFmtPct),
"Sum As Fraction Of Parent Column": sTpl.fractionOf(tpl.sum(), "col", usFmtPct),
"Count As Fraction Of Parent Row": sTpl.fractionOf(tpl.count(), "row", usFmtPct),
"Count As Fraction Of Parent Column": sTpl.fractionOf(tpl.count(), "col", usFmtPct)
};
})(aggregatorTemplates, subtotalAggregatorTemplates);
});
}).call(this);
//# sourceMappingURL=subtotal.js.map