mirror of
https://github.com/koalyptus/TableFilter.git
synced 2024-06-01 05:23:02 +02:00
Merge pull request #389 from koalyptus/332-colops-refactor
332 colops refactor
This commit is contained in:
commit
47d350470c
|
@ -11,8 +11,8 @@
|
|||
"array-bracket-spacing": 2,
|
||||
"keyword-spacing": ["error", { "after": true, "before": true }],
|
||||
"max-depth": [2, 7],
|
||||
"max-statements": [2, 150],
|
||||
"complexity": [2, 83],
|
||||
"max-statements": [2, 144],
|
||||
"complexity": [2, 78],
|
||||
"no-unused-vars": 2,
|
||||
"no-eval": 2,
|
||||
"no-underscore-dangle": 0,
|
||||
|
|
4
dist/starter.html
vendored
4
dist/starter.html
vendored
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>tablefilter v0.4.33 - Starter</title>
|
||||
<title>tablefilter v0.4.34 - Starter</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>tablefilter v0.4.33</h1>
|
||||
<h1>tablefilter v0.4.34</h1>
|
||||
|
||||
|
||||
|
||||
|
|
4
dist/tablefilter/style/colsVisibility.css
vendored
4
dist/tablefilter/style/colsVisibility.css
vendored
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
span.colVisSpan{text-align:left;}span.colVisSpan a.colVis{display:inline-block;padding:7px 5px 0;font-size:inherit;font-weight:inherit;vertical-align:top}div.colVisCont{position:relative;background:#fff;-webkit-box-shadow:3px 3px 2px #888;-moz-box-shadow:3px 3px 2px #888;box-shadow:3px 3px 2px #888;position:absolute;display:none;border:1px solid #ccc;height:auto;width:250px;background-color:#fff;margin:35px 0 0 -100px;z-index:10000;padding:10px 10px 10px 10px;text-align:left;font-size:12px;}div.colVisCont:after,div.colVisCont:before{bottom:100%;left:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.colVisCont:after{border-color:rgba(255,255,255,0);border-bottom-color:#fff;border-width:10px;margin-left:-10px}div.colVisCont:before{border-color:rgba(255,255,255,0);border-bottom-color:#ccc;border-width:12px;margin-left:-12px}div.colVisCont p{margin:6px auto 6px auto}div.colVisCont a.colVis{display:initial;font-weight:inherit}ul.cols_checklist{padding:0;margin:0;list-style:none;}ul.cols_checklist label{display:block}ul.cols_checklist input{vertical-align:middle;margin:2px 5px 2px 1px}li.cols_checklist_item{padding:4px;margin:0;}li.cols_checklist_item:hover{background-color:#335ea8;color:#fff}.cols_checklist_slc_item{background-color:#335ea8;color:#fff}
|
4
dist/tablefilter/style/filtersVisibility.css
vendored
4
dist/tablefilter/style/filtersVisibility.css
vendored
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
span.expClpFlt a.btnExpClpFlt{width:35px;height:35px;display:inline-block;}span.expClpFlt a.btnExpClpFlt:hover{background-color:#f4f4f4}span.expClpFlt img{padding:8px 11px 11px 11px}
|
4
dist/tablefilter/style/tablefilter.css
vendored
4
dist/tablefilter/style/tablefilter.css
vendored
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
.activeHeader{background-color:#66afe9 !important;color:#fff !important}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
table.TF{border-left:1px solid #ccc;border-top:none;border-right:none;border-bottom:none;}table.TF th{background:#ebecee url("images/bg_th.jpg") left top repeat-x;border-bottom:1px solid #d0d0d0;border-right:1px solid #d0d0d0;border-left:1px solid #fff;border-top:1px solid #fff;color:#333}table.TF td{border-bottom:1px dotted #999;padding:5px}.fltrow{background-color:#ebecee !important;}.fltrow th,.fltrow td{border-bottom:1px dotted #666 !important;padding:1px 3px 1px 3px !important}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #999 !important}input.flt{width:99% !important}.inf{height:$min-height;background:#d7d7d7 url("images/bg_infDiv.jpg") 0 0 repeat-x !important}input.reset{background:transparent url("images/btn_eraser.gif") center center no-repeat !important}.helpBtn:hover{background-color:transparent}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important;}.nextPage:hover{background:transparent url("images/btn_over_next_page.gif") center center no-repeat !important}.previousPage{background:transparent url("images/btn_previous_page.gif") center center no-repeat !important;}.previousPage:hover{background:transparent url("images/btn_over_previous_page.gif") center center no-repeat !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important;}.firstPage:hover{background:transparent url("images/btn_over_first_page.gif") center center no-repeat !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important;}.lastPage:hover{background:transparent url("images/btn_over_last_page.gif") center center no-repeat !important}div.grd_Cont{background-color:#ebecee !important;border:1px solid #ccc !important;padding:0 !important;}div.grd_Cont .even{background-color:#fff}div.grd_Cont .odd{background-color:#d5d5d5}div.grd_headTblCont{background-color:#ebecee !important;border-bottom:none !important;}div.grd_headTblCont table{border-right:none !important}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{background:#ebecee url("images/bg_th.jpg") left top repeat-x !important;border-bottom:1px solid #d0d0d0 !important;border-right:1px solid #d0d0d0 !important;border-left:1px solid #fff !important;border-top:1px solid #fff !important}div.grd_tblCont table td{border-bottom:1px solid #999 !important}.grd_inf{background:#d7d7d7 url("images/bg_infDiv.jpg") 0 0 repeat-x !important;border-top:1px solid #d0d0d0 !important}.loader{border:1px solid #999}.defaultLoader{width:32px;height:32px;background:transparent url("images/img_loading.gif") 0 0 no-repeat !important}.even{background-color:#fff}.odd{background-color:#d5d5d5}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.activeHeader{background:#999 !important}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
table.TF{border-left:1px dotted #81963b;border-top:none;border-right:0;border-bottom:none;}table.TF th{background:#39424b url("images/bg_headers.jpg") left top repeat-x;border-bottom:0;border-right:1px dotted #d0d0d0;border-left:0;border-top:0;color:#fff}table.TF td{border-bottom:1px dotted #81963b;border-right:1px dotted #81963b;padding:5px}.fltrow{background-color:#81963b !important;}.fltrow th,.fltrow td{border-bottom:1px dotted #39424b !important;border-right:1px dotted #fff !important;border-left:0 !important;border-top:0 !important;padding:1px 3px 1px 3px !important}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #687830 !important}input.flt{width:99% !important}.inf{background:#d8d8d8;height:$min-height}input.reset{width:53px;background:transparent url("images/btn_filter.png") center center no-repeat !important}.helpBtn:hover{background-color:transparent}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important}.previousPage{background:transparent url("images/btn_previous_page.gif") center center no-repeat !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important}div.grd_Cont{background:#81963b url("images/bg_headers.jpg") left top repeat-x !important;border:1px solid #ccc !important;padding:0 1px 1px 1px !important;}div.grd_Cont .even{background-color:#bccd83}div.grd_Cont .odd{background-color:#fff}div.grd_headTblCont{background-color:#ebecee !important;border-bottom:none !important}div.grd_tblCont table{border-right:none !important;}div.grd_tblCont table td{border-bottom:1px dotted #81963b;border-right:1px dotted #81963b}div.grd_tblCont table th,div.grd_headTblCont table th{background:transparent url("images/bg_headers.jpg") 0 0 repeat-x !important;border-bottom:0 !important;border-right:1px dotted #d0d0d0 !important;border-left:0 !important;border-top:0 !important;padding:0 4px 0 4px !important;color:#fff !important;height:35px !important}div.grd_headTblCont table td{border-bottom:1px dotted #39424b !important;border-right:1px dotted #fff !important;border-left:0 !important;border-top:0 !important;background-color:#81963b !important;padding:1px 3px 1px 3px !important}.grd_inf{background-color:#d8d8d8;border-top:1px solid #d0d0d0 !important}.loader{border:0 !important;background:#81963b !important}.defaultLoader{width:32px;height:32px;background:transparent url("images/img_loading.gif") 0 0 no-repeat !important}.even{background-color:#bccd83}.odd{background-color:#fff}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.activeHeader{background:#81963b !important}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
table.TF{padding:0;color:#000;border-right:1px solid #a4bed4;border-top:1px solid #a4bed4;border-left:1px solid #a4bed4;border-bottom:0;}table.TF th{margin:0;color:inherit;background:#d1e5fe url("images/bg_skyblue.gif") 0 0 repeat-x;border-color:#fdfdfd #a4bed4 #a4bed4 #fdfdfd;border-width:1px;border-style:solid}table.TF td{margin:0;padding:5px;color:inherit;border-bottom:1px solid #a4bed4;border-left:0;border-top:0;border-right:0}.fltrow{background-color:#d1e5fe !important;}.fltrow th,.fltrow td{padding:1px 3px 1px 3px !important}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #a4bed4 !important}input.flt{width:99% !important}.inf{background-color:#e3efff !important;border:1px solid #a4bed4;height:$min-height;color:#004a6f}div.tot,div.status{border-right:0 !important}.helpBtn:hover{background-color:transparent}input.reset{background:transparent url("images/icn_clear_filters.png") center center no-repeat !important}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.nextPage:hover{background:#ffe4ab url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.previousPage{background:transparent url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.previousPage:hover{background:#ffe4ab url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.firstPage:hover{background:#ffe4ab url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.lastPage:hover{background:#ffe4ab url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid #ffb552 !important}.activeHeader{background:#ffe4ab !important;border:1px solid #ffb552 !important;color:inherit !important}div.grd_Cont{background-color:#d9eaed !important;border:1px solid #9cc !important;padding:0 !important;}div.grd_Cont .even{background-color:#fff}div.grd_Cont .odd{background-color:#e3efff}div.grd_headTblCont{background-color:#d9eaed !important;border-bottom:none !important}div.grd_tblCont table{border-right:none !important}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{background:#d9eaed url("images/bg_skyblue.gif") left top repeat-x;border-bottom:1px solid #a4bed4;border-right:1px solid #a4bed4 !important;border-left:1px solid #fff !important;border-top:1px solid #fff !important}div.grd_tblCont table td{border-bottom:1px solid #a4bed4 !important;border-right:0 !important;border-left:0 !important;border-top:0 !important}.grd_inf{background-color:#cce2fe;color:#004a6f;border-top:1px solid #9cc !important;}.grd_inf a{text-decoration:none;font-weight:bold}.loader{background-color:#2d8eef;border:1px solid #cce2fe;border-radius:5px}.even{background-color:#fff}.odd{background-color:#e3efff}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.ezActiveRow{background-color:#ffdc61 !important;color:inherit}.ezSelectedRow{background-color:#ffe4ab !important;color:inherit}.ezActiveCell{background-color:#fff !important;color:#000 !important;font-weight:bold}.ezETSelectedCell{background-color:#fff !important;font-weight:bold;color:#000 !important}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* tablefilter v0.4.33 by Max Guglielmi
|
||||
* build date: 2017-01-07T11:45:50.125Z
|
||||
* tablefilter v0.4.34 by Max Guglielmi
|
||||
* build date: 2017-01-15T06:21:30.968Z
|
||||
* MIT License
|
||||
*/
|
||||
table.TF{padding:0;color:inherit;border-right:1px solid transparent;border-top:1px solid transparent;border-left:1px solid transparent;border-bottom:0;}table.TF th{margin:0;color:inherit;background-color:transparent;border-color:transparent;border-width:1px;border-style:solid;}table.TF th:last-child{border-right:1px solid transparent}table.TF td{margin:0;padding:5px;color:inherit;border-bottom:1px solid transparent;border-left:0;border-top:0;border-right:0}.fltrow{background-color:transparent;}.fltrow th,.fltrow td{padding:1px 3px 1px 3px;border-bottom:1px solid transparent !important;}.fltrow th:last-child,.fltrow td:last-child{border-right:1px solid transparent}.flt,select.flt,select.flt_multi,.flt_s,.single_flt,.div_checklist{border:1px solid #a4bed4}input.flt{width:99% !important}.inf{background-color:transparent;border:1px solid transparent;height:$min-height;color:inherit}div.tot,div.status{border-right:0 !important}.helpBtn:hover{background-color:transparent}input.reset{background:transparent url("images/icn_clear_filters.png") center center no-repeat !important}.nextPage{background:transparent url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.nextPage:hover{background:#f7f7f7 url("images/btn_next_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.previousPage{background:transparent url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.previousPage:hover{background:#f7f7f7 url("images/btn_prev_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.firstPage{background:transparent url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.firstPage:hover{background:#f7f7f7 url("images/btn_first_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.lastPage{background:transparent url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid transparent !important;}.lastPage:hover{background:#f7f7f7 url("images/btn_last_page.gif") center center no-repeat !important;border:1px solid #f7f7f7 !important}.activeHeader{background:#f7f7f7 !important;border:1px solid transparent;color:inherit !important}div.grd_Cont{-webkit-box-shadow:0 0 0 0 rgba(50,50,50,0.75);-moz-box-shadow:0 0 0 0 rgba(50,50,50,0.75);box-shadow:0 0 0 0 rgba(50,50,50,0.75);background-color:transparent;border:1px solid transparent;padding:0 !important;}div.grd_Cont .even{background-color:transparent}div.grd_Cont .odd{background-color:#f7f7f7}div.grd_headTblCont{background-color:transparent;border-bottom:none !important}div.grd_tblCont table{border-right:none !important}div.grd_tblCont table th,div.grd_headTblCont table th,div.grd_headTblCont table td{background:transparent;border-bottom:1px solid transparent;border-right:1px solid transparent !important;border-left:1px solid transparent;border-top:1px solid transparent}div.grd_tblCont table td{border-bottom:1px solid transparent;border-right:0 !important;border-left:0 !important;border-top:0 !important}.grd_inf{background-color:transparent;color:inherit;border-top:1px solid transparent;}.grd_inf a{text-decoration:none;font-weight:bold}.loader{background-color:#f7f7f7;border:1px solid #f7f7f7;border-radius:5px;color:#000;text-shadow:none}.even{background-color:transparent}.odd{background-color:#f7f7f7}span.expClpFlt a.btnExpClpFlt:hover{background-color:transparent !important}.ezActiveRow{background-color:#ccc !important;color:inherit}.ezSelectedRow{background-color:#ccc !important;color:inherit}.ezActiveCell{background-color:transparent;color:inherit;font-weight:bold}.ezETSelectedCell{background-color:transparent;font-weight:bold;color:inherit}
|
18
dist/tablefilter/tablefilter.js
vendored
18
dist/tablefilter/tablefilter.js
vendored
File diff suppressed because one or more lines are too long
2
dist/tablefilter/tablefilter.js.map
vendored
2
dist/tablefilter/tablefilter.js.map
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
9
dist/tablefilter/tf-1-a89898708236ababcb36.js
vendored
Normal file
9
dist/tablefilter/tf-1-a89898708236ababcb36.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dist/tablefilter/tf-1-a89898708236ababcb36.js.map
vendored
Normal file
1
dist/tablefilter/tf-1-a89898708236ababcb36.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "tablefilter",
|
||||
"version": "0.4.33",
|
||||
"version": "0.4.34",
|
||||
"description": "A Javascript library making HTML tables filterable and a bit more",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {Feature} from '../../feature';
|
||||
import {createText, elm} from '../../dom';
|
||||
import {isArray, isFn, isUndef, EMPTY_FN} from '../../types';
|
||||
import {isArray, isFn, isUndef, isEmpty, EMPTY_FN} from '../../types';
|
||||
import {numSortAsc} from '../../sort';
|
||||
|
||||
const EVENTS = [
|
||||
'after-filtering',
|
||||
|
@ -8,6 +9,14 @@ const EVENTS = [
|
|||
'after-page-length-change'
|
||||
];
|
||||
|
||||
const SUM = 'sum';
|
||||
const MEAN = 'mean';
|
||||
const MIN = 'min';
|
||||
const MAX = 'max';
|
||||
const MEDIAN = 'median';
|
||||
const Q1 = 'q1';
|
||||
const Q3 = 'q3';
|
||||
|
||||
/**
|
||||
* Column calculations extension
|
||||
*/
|
||||
|
@ -42,6 +51,51 @@ export default class ColOps extends Feature {
|
|||
*/
|
||||
this.opts = opts;
|
||||
|
||||
/**
|
||||
* List of DOM element IDs containing column's calculation result
|
||||
* @type {Array}
|
||||
*/
|
||||
this.labelIds = opts.id || [];
|
||||
|
||||
/**
|
||||
* List of columns' indexes for calculations
|
||||
* @type {Array}
|
||||
*/
|
||||
this.colIndexes = opts.col || [];
|
||||
|
||||
/**
|
||||
* List of operations - possible values: 'sum', 'mean', 'min', 'max',
|
||||
* 'median', 'q1', 'q3'
|
||||
* @type {Array}
|
||||
*/
|
||||
this.operations = opts.operation || [];
|
||||
|
||||
/**
|
||||
* List of write methods used to write the result - possible values:
|
||||
* 'innerHTML', 'setValue', 'createTextNode'
|
||||
* @type {Array}
|
||||
*/
|
||||
this.outputTypes = opts.write_method || [];
|
||||
|
||||
/**
|
||||
* List of row indexes displaying the results
|
||||
* @type {Array}
|
||||
*/
|
||||
this.totRowIndexes = opts.tot_row_index || [];
|
||||
|
||||
/**
|
||||
* List of row indexes excluded from calculations
|
||||
* @type {Array}
|
||||
*/
|
||||
this.excludeRows = opts.exclude_row || [];
|
||||
|
||||
/**
|
||||
* List of decimal precision for calculation results
|
||||
* @type {Array}
|
||||
*/
|
||||
this.decimalPrecisions = isUndef(opts.decimal_precision) ?
|
||||
2 : opts.decimal_precision;
|
||||
|
||||
this.enable();
|
||||
}
|
||||
|
||||
|
@ -53,13 +107,11 @@ export default class ColOps extends Feature {
|
|||
return;
|
||||
}
|
||||
// subscribe to events
|
||||
this.emitter.on(EVENTS, () => this.calc());
|
||||
this.emitter.on(EVENTS, () => this.calcAll());
|
||||
|
||||
this.calc();
|
||||
this.calcAll();
|
||||
|
||||
/**
|
||||
* @inherited
|
||||
*/
|
||||
/** @inherited */
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
|
@ -79,7 +131,7 @@ export default class ColOps extends Feature {
|
|||
* (1) optimized the routine (now it will only process each column once),
|
||||
* (2) added calculations for the median, lower and upper quartile.
|
||||
*/
|
||||
calc() {
|
||||
calcAll() {
|
||||
let tf = this.tf;
|
||||
if (!tf.isInitialized()) {
|
||||
return;
|
||||
|
@ -88,277 +140,307 @@ export default class ColOps extends Feature {
|
|||
this.onBeforeOperation(tf, this);
|
||||
this.emitter.emit('before-column-operation', tf, this);
|
||||
|
||||
let opts = this.opts,
|
||||
labelId = opts.id,
|
||||
colIndex = opts.col,
|
||||
operation = opts.operation,
|
||||
outputType = opts.write_method,
|
||||
totRowIndex = opts.tot_row_index,
|
||||
excludeRow = opts.exclude_row,
|
||||
decimalPrecision = isUndef(opts.decimal_precision) ?
|
||||
2 : opts.decimal_precision;
|
||||
let colIndexes = this.colIndexes,
|
||||
colOperations = this.operations,
|
||||
outputTypes = this.outputTypes,
|
||||
totRowIndexes = this.totRowIndexes,
|
||||
excludeRows = this.excludeRows,
|
||||
decimalPrecisions = isUndef(this.decimalPrecisions) ?
|
||||
2 : this.decimalPrecisions;
|
||||
|
||||
//nuovella: determine unique list of columns to operate on
|
||||
let ucolIndex = [],
|
||||
ucolMax = 0;
|
||||
ucolIndex[ucolMax] = colIndex[0];
|
||||
let uIndexes = [];
|
||||
colIndexes.forEach((val) => {
|
||||
if (uIndexes.indexOf(val) === -1) {
|
||||
uIndexes.push(val);
|
||||
}
|
||||
});
|
||||
|
||||
for (let ii = 1; ii < colIndex.length; ii++) {
|
||||
let saved = 0;
|
||||
//see if colIndex[ii] is already in the list of unique indexes
|
||||
for (let jj = 0; jj <= ucolMax; jj++) {
|
||||
if (ucolIndex[jj] === colIndex[ii]) {
|
||||
saved = 1;
|
||||
let nbCols = uIndexes.length - 1,
|
||||
rows = tf.tbl.rows,
|
||||
colValues = [];
|
||||
|
||||
for (let u = 0; u <= nbCols; u++) {
|
||||
//this retrieves col values
|
||||
//use uIndexes because we only want to pass through this loop
|
||||
//once for each column get the values in this unique column
|
||||
colValues.push(
|
||||
tf.getFilteredDataCol(uIndexes[u], false, true, excludeRows)
|
||||
);
|
||||
|
||||
let curValues = colValues[u];
|
||||
|
||||
//next: calculate all operations for this column
|
||||
let result = 0,
|
||||
operations = [],
|
||||
precisions = [],
|
||||
labels = [],
|
||||
writeType,
|
||||
idx = 0;
|
||||
|
||||
for (let k = 0; k < colIndexes.length; k++) {
|
||||
if (colIndexes[k] !== uIndexes[u]) {
|
||||
continue;
|
||||
}
|
||||
operations[idx] = colOperations[k].toLowerCase();
|
||||
precisions[idx] = decimalPrecisions[k];
|
||||
labels[idx] = this.labelIds[k];
|
||||
writeType = isArray(outputTypes) ? outputTypes[k] : null;
|
||||
idx++;
|
||||
}
|
||||
//if not saved then, save the index;
|
||||
if (saved === 0) {
|
||||
ucolMax++;
|
||||
ucolIndex[ucolMax] = colIndex[ii];
|
||||
}
|
||||
}
|
||||
|
||||
if (isArray(labelId) && isArray(colIndex) && isArray(operation)) {
|
||||
let rows = tf.tbl.rows,
|
||||
colvalues = [],
|
||||
ucol = 0;
|
||||
|
||||
for (; ucol <= ucolMax; ucol++) {
|
||||
//this retrieves col values
|
||||
//use ucolIndex because we only want to pass through this loop
|
||||
//once for each column get the values in this unique column
|
||||
colvalues.push(
|
||||
tf.getColValues(ucolIndex[ucol], false, true, excludeRow)
|
||||
for (let i = 0; i <= idx; i++) {
|
||||
// emit values before column calculation
|
||||
this.emitter.emit(
|
||||
'before-column-calc',
|
||||
tf,
|
||||
this,
|
||||
uIndexes[u],
|
||||
curValues,
|
||||
operations[i],
|
||||
precisions[i]
|
||||
);
|
||||
|
||||
//next: calculate all operations for this column
|
||||
let result,
|
||||
nbvalues = 0,
|
||||
temp,
|
||||
meanValue = 0,
|
||||
sumValue = 0,
|
||||
minValue = null,
|
||||
maxValue = null,
|
||||
q1Value = null,
|
||||
medValue = null,
|
||||
q3Value = null,
|
||||
meanFlag = 0,
|
||||
sumFlag = 0,
|
||||
minFlag = 0,
|
||||
maxFlag = 0,
|
||||
q1Flag = 0,
|
||||
medFlag = 0,
|
||||
q3Flag = 0,
|
||||
theList = [],
|
||||
opsThisCol = [],
|
||||
decThisCol = [],
|
||||
labThisCol = [],
|
||||
oTypeThisCol = [],
|
||||
mThisCol = -1,
|
||||
k = 0,
|
||||
j = 0,
|
||||
i = 0;
|
||||
result = Number(this.calc(curValues, operations[i], null));
|
||||
|
||||
for (; k < colIndex.length; k++) {
|
||||
if (colIndex[k] === ucolIndex[ucol]) {
|
||||
mThisCol++;
|
||||
opsThisCol[mThisCol] = operation[k].toLowerCase();
|
||||
decThisCol[mThisCol] = decimalPrecision[k];
|
||||
labThisCol[mThisCol] = labelId[k];
|
||||
oTypeThisCol = isArray(outputType) ?
|
||||
outputType[k] : null;
|
||||
// emit column calculation result
|
||||
this.emitter.emit(
|
||||
'column-calc',
|
||||
tf,
|
||||
this,
|
||||
uIndexes[u],
|
||||
result,
|
||||
operations[i],
|
||||
precisions[i]
|
||||
);
|
||||
|
||||
switch (opsThisCol[mThisCol]) {
|
||||
case 'mean':
|
||||
meanFlag = 1;
|
||||
break;
|
||||
case 'sum':
|
||||
sumFlag = 1;
|
||||
break;
|
||||
case 'min':
|
||||
minFlag = 1;
|
||||
break;
|
||||
case 'max':
|
||||
maxFlag = 1;
|
||||
break;
|
||||
case 'median':
|
||||
medFlag = 1;
|
||||
break;
|
||||
case 'q1':
|
||||
q1Flag = 1;
|
||||
break;
|
||||
case 'q3':
|
||||
q3Flag = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// write result in expected DOM element
|
||||
this.writeResult(
|
||||
result,
|
||||
labels[i],
|
||||
writeType,
|
||||
precisions[i]
|
||||
);
|
||||
|
||||
for (; j < colvalues[ucol].length; j++) {
|
||||
//sort the list for calculation of median and quartiles
|
||||
if ((q1Flag === 1) || (q3Flag === 1) || (medFlag === 1)) {
|
||||
if (j < colvalues[ucol].length - 1) {
|
||||
for (k = j + 1; k < colvalues[ucol].length; k++) {
|
||||
/* eslint-disable */
|
||||
if (eval(colvalues[ucol][k]) <
|
||||
eval(colvalues[ucol][j])) {
|
||||
/* eslint-enable */
|
||||
temp = colvalues[ucol][j];
|
||||
colvalues[ucol][j] = colvalues[ucol][k];
|
||||
colvalues[ucol][k] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let cvalue = parseFloat(colvalues[ucol][j]);
|
||||
theList[j] = parseFloat(cvalue);
|
||||
}//for i
|
||||
|
||||
if (!isNaN(cvalue)) {
|
||||
nbvalues++;
|
||||
if (sumFlag === 1 || meanFlag === 1) {
|
||||
sumValue += parseFloat(cvalue);
|
||||
}
|
||||
if (minFlag === 1) {
|
||||
if (minValue === null) {
|
||||
minValue = parseFloat(cvalue);
|
||||
} else {
|
||||
minValue = parseFloat(cvalue) < minValue ?
|
||||
parseFloat(cvalue) : minValue;
|
||||
}
|
||||
}
|
||||
if (maxFlag === 1) {
|
||||
if (maxValue === null) {
|
||||
maxValue = parseFloat(cvalue);
|
||||
} else {
|
||||
maxValue = parseFloat(cvalue) > maxValue ?
|
||||
parseFloat(cvalue) : maxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}//for j
|
||||
if (meanFlag === 1) {
|
||||
meanValue = sumValue / nbvalues;
|
||||
}
|
||||
if (medFlag === 1) {
|
||||
let aux = 0;
|
||||
if (nbvalues % 2 === 1) {
|
||||
aux = Math.floor(nbvalues / 2);
|
||||
medValue = theList[aux];
|
||||
} else {
|
||||
medValue = (theList[nbvalues / 2] +
|
||||
theList[((nbvalues / 2) - 1)]) / 2;
|
||||
}
|
||||
}
|
||||
let posa;
|
||||
if (q1Flag === 1) {
|
||||
posa = 0.0;
|
||||
posa = Math.floor(nbvalues / 4);
|
||||
if (4 * posa === nbvalues) {
|
||||
q1Value = (theList[posa - 1] + theList[posa]) / 2;
|
||||
} else {
|
||||
q1Value = theList[posa];
|
||||
}
|
||||
}
|
||||
if (q3Flag === 1) {
|
||||
posa = 0.0;
|
||||
let posb = 0.0;
|
||||
posa = Math.floor(nbvalues / 4);
|
||||
if (4 * posa === nbvalues) {
|
||||
posb = 3 * posa;
|
||||
q3Value = (theList[posb] + theList[posb - 1]) / 2;
|
||||
} else {
|
||||
q3Value = theList[nbvalues - posa - 1];
|
||||
}
|
||||
}
|
||||
|
||||
for (; i <= mThisCol; i++) {
|
||||
switch (opsThisCol[i]) {
|
||||
case 'mean':
|
||||
result = meanValue;
|
||||
break;
|
||||
case 'sum':
|
||||
result = sumValue;
|
||||
break;
|
||||
case 'min':
|
||||
result = minValue;
|
||||
break;
|
||||
case 'max':
|
||||
result = maxValue;
|
||||
break;
|
||||
case 'median':
|
||||
result = medValue;
|
||||
break;
|
||||
case 'q1':
|
||||
result = q1Value;
|
||||
break;
|
||||
case 'q3':
|
||||
result = q3Value;
|
||||
break;
|
||||
}
|
||||
|
||||
let precision = !isNaN(decThisCol[i]) ? decThisCol[i] : 2;
|
||||
|
||||
//if outputType is defined
|
||||
if (oTypeThisCol && result) {
|
||||
result = result.toFixed(precision);
|
||||
|
||||
if (elm(labThisCol[i])) {
|
||||
switch (oTypeThisCol.toLowerCase()) {
|
||||
case 'innerhtml':
|
||||
if (isNaN(result) || !isFinite(result) ||
|
||||
nbvalues === 0) {
|
||||
elm(labThisCol[i]).innerHTML = '.';
|
||||
} else {
|
||||
elm(labThisCol[i]).innerHTML = result;
|
||||
}
|
||||
break;
|
||||
case 'setvalue':
|
||||
elm(labThisCol[i]).value = result;
|
||||
break;
|
||||
case 'createtextnode':
|
||||
let oldnode =
|
||||
elm(labThisCol[i]).firstChild;
|
||||
let txtnode = createText(result);
|
||||
elm(labThisCol[i])
|
||||
.replaceChild(txtnode, oldnode);
|
||||
break;
|
||||
}//switch
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
if (isNaN(result) || !isFinite(result) ||
|
||||
nbvalues === 0) {
|
||||
elm(labThisCol[i]).innerHTML = '.';
|
||||
} else {
|
||||
elm(labThisCol[i]).innerHTML =
|
||||
result.toFixed(precision);
|
||||
}
|
||||
} catch (e) { }//catch
|
||||
}//else
|
||||
}//for i
|
||||
|
||||
// row(s) with result are always visible
|
||||
let totRow = totRowIndex && totRowIndex[ucol] ?
|
||||
rows[totRowIndex[ucol]] : null;
|
||||
if (totRow) {
|
||||
totRow.style.display = '';
|
||||
}
|
||||
}//for ucol
|
||||
}//if typeof
|
||||
// row(s) with result are always visible
|
||||
let totRow = totRowIndexes && totRowIndexes[u] ?
|
||||
rows[totRowIndexes[u]] : null;
|
||||
if (totRow) {
|
||||
totRow.style.display = '';
|
||||
}
|
||||
}//for u
|
||||
|
||||
this.onAfterOperation(tf, this);
|
||||
this.emitter.emit('after-column-operation', tf, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove extension
|
||||
* Make desired calculation on specified column.
|
||||
* @param {Number} colIndex Column index
|
||||
* @param {any} [operation=SUM] Operation type
|
||||
* @param {any} precision Decimal precision
|
||||
* @returns {Number}
|
||||
*/
|
||||
columnCalc(colIndex, operation = SUM, precision) {
|
||||
let excludeRows = this.excludeRows || [];
|
||||
let colValues =
|
||||
this.tf.getFilteredDataCol(colIndex, false, true, excludeRows);
|
||||
|
||||
return this.calc(colValues, operation, precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make calculation on passed values.
|
||||
* @param {Array} values List of values
|
||||
* @param {String} [operation=SUM] Optional operation type
|
||||
* @param {Number} precision Optional result precision
|
||||
* @returns {Number}
|
||||
* @private
|
||||
*/
|
||||
calc(colValues, operation = SUM, precision) {
|
||||
let result = 0;
|
||||
|
||||
if (operation === Q1 || operation === Q3 || operation === MEDIAN) {
|
||||
colValues = this.sortColumnValues(colValues, numSortAsc);
|
||||
}
|
||||
|
||||
switch (operation) {
|
||||
case MEAN:
|
||||
result = this.calcMean(colValues);
|
||||
break;
|
||||
case SUM:
|
||||
result = this.calcSum(colValues);
|
||||
break;
|
||||
case MIN:
|
||||
result = this.calcMin(colValues);
|
||||
break;
|
||||
case MAX:
|
||||
result = this.calcMax(colValues);
|
||||
break;
|
||||
case MEDIAN:
|
||||
result = this.calcMedian(colValues);
|
||||
break;
|
||||
case Q1:
|
||||
result = this.calcQ1(colValues);
|
||||
break;
|
||||
case Q3:
|
||||
result = this.calcQ3(colValues);
|
||||
break;
|
||||
}
|
||||
|
||||
return isEmpty(precision) ? result : result.toFixed(precision);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the sum of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcSum(values = []) {
|
||||
if (isEmpty(values)) {
|
||||
return 0;
|
||||
}
|
||||
let result = values.reduce((x, y) => x + y);
|
||||
return Number(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the mean of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcMean(values = []) {
|
||||
let result = this.calcSum(values) / values.length;
|
||||
return Number(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the max value of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcMax(values = []) {
|
||||
return Math.max.apply(null, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the min value of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcMin(values = []) {
|
||||
return Math.min.apply(null, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the median of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcMedian(values = []) {
|
||||
let nbValues = values.length;
|
||||
let aux = 0;
|
||||
if (nbValues % 2 === 1) {
|
||||
aux = Math.floor(nbValues / 2);
|
||||
return Number(values[aux]);
|
||||
}
|
||||
return Number(
|
||||
(values[nbValues / 2] +
|
||||
values[((nbValues / 2) - 1)]) / 2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the lower quartile of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcQ1(values = []) {
|
||||
let nbValues = values.length;
|
||||
let posa = 0.0;
|
||||
posa = Math.floor(nbValues / 4);
|
||||
if (4 * posa === nbValues) {
|
||||
return Number(
|
||||
(values[posa - 1] + values[posa]) / 2
|
||||
);
|
||||
}
|
||||
return Number(values[posa]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the upper quartile of passed values.
|
||||
* @param {Array} [values=[]] List of values
|
||||
* @returns {Number}
|
||||
*/
|
||||
calcQ3(values = []) {
|
||||
let nbValues = values.length;
|
||||
let posa = 0.0;
|
||||
let posb = 0.0;
|
||||
posa = Math.floor(nbValues / 4);
|
||||
if (4 * posa === nbValues) {
|
||||
posb = 3 * posa;
|
||||
return Number(
|
||||
(values[posb] + values[posb - 1]) / 2
|
||||
);
|
||||
}
|
||||
return Number(values[nbValues - posa - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort passed values with supplied sorter function.
|
||||
* @param {Array} [values=[]] List of values to be sorted
|
||||
* @param {Function} sorter Sorter function
|
||||
* @returns {Array}
|
||||
*/
|
||||
sortColumnValues(values = [], sorter) {
|
||||
return values.sort(sorter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write calculation result in passed DOM element with supplied write method
|
||||
* and decimal precision.
|
||||
* @param {Number} [result=0] Calculation result
|
||||
* @param {DOMElement} label DOM element
|
||||
* @param {String} [writeType='innerhtml'] Write method
|
||||
* @param {Number} [precision=2] Applied decimal precision
|
||||
* @private
|
||||
*/
|
||||
writeResult(result = 0, label, writeType = 'innerhtml', precision = 2) {
|
||||
let labelElm = elm(label);
|
||||
|
||||
if (!labelElm) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = result.toFixed(precision);
|
||||
if (isNaN(result) || !isFinite(result)) {
|
||||
result = '';
|
||||
}
|
||||
|
||||
switch (writeType.toLowerCase()) {
|
||||
case 'innerhtml':
|
||||
labelElm.innerHTML = result;
|
||||
break;
|
||||
case 'setvalue':
|
||||
labelElm.value = result;
|
||||
break;
|
||||
case 'createtextnode':
|
||||
let oldNode = labelElm.firstChild;
|
||||
let txtNode = createText(result);
|
||||
labelElm.replaceChild(txtNode, oldNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Remove extension */
|
||||
destroy() {
|
||||
if (!this.initialized) {
|
||||
return;
|
||||
}
|
||||
// unsubscribe to events
|
||||
this.emitter.off(EVENTS, () => this.calc());
|
||||
this.emitter.off(EVENTS, () => this.calcAll());
|
||||
|
||||
this.initialized = false;
|
||||
}
|
||||
|
|
|
@ -2107,7 +2107,7 @@ export class TableFilter {
|
|||
if (nchilds === this.nbCells && !isExludedRow) {
|
||||
// this loop retrieves cell data
|
||||
for (let j = 0; j < nchilds; j++) {
|
||||
if (j !== colIndex || row[i].style.display !== '') {
|
||||
if (j !== colIndex) {
|
||||
continue;
|
||||
}
|
||||
let cellData = this.getCellData(cell[j]);
|
||||
|
@ -2353,28 +2353,55 @@ export class TableFilter {
|
|||
* Return the filtered data for a given column index
|
||||
* @param {Number} colIndex Colmun's index
|
||||
* @param {Boolean} includeHeaders Optional: include headers row
|
||||
* @param {Boolean} num Optional: return unformatted number
|
||||
* @param {Array} exclude Optional: list of row indexes to be excluded
|
||||
* @param {Boolean} visible Optional: return only visible data
|
||||
* (relevant for paging)
|
||||
* @return {Array} Flat list of values ['val0','val1','val2'...]
|
||||
*
|
||||
* TODO: provide an API returning data in JSON format
|
||||
*/
|
||||
getFilteredDataCol(colIndex, includeHeaders = false) {
|
||||
getFilteredDataCol(
|
||||
colIndex,
|
||||
includeHeaders = false,
|
||||
num = false,
|
||||
exclude = [],
|
||||
visible = true
|
||||
) {
|
||||
if (isUndef(colIndex)) {
|
||||
return [];
|
||||
}
|
||||
let data = this.getFilteredData(),
|
||||
colData = [];
|
||||
|
||||
let rows = this.tbl.rows;
|
||||
|
||||
// ensure valid rows index do not contain excluded rows and row is
|
||||
// displayed
|
||||
let validRows = this.getValidRows(true).filter((rowIdx) => {
|
||||
return exclude.indexOf(rowIdx) === -1 &&
|
||||
(visible ?
|
||||
this.getRowDisplay(rows[rowIdx]) !== 'none' :
|
||||
true);
|
||||
});
|
||||
|
||||
let decimal = this.decimalSeparator;
|
||||
if (this.hasType(colIndex, [FORMATTED_NUMBER])) {
|
||||
let colType = this.colTypes[colIndex];
|
||||
if (colType.hasOwnProperty('decimal')) {
|
||||
decimal = colType.decimal;
|
||||
}
|
||||
}
|
||||
|
||||
// convert column value to expected type if necessary
|
||||
let validColValues = validRows.map((rowIdx) => {
|
||||
let val = this.getCellData(rows[rowIdx].cells[colIndex]);
|
||||
return num ? Number(val) || parseNb(val, decimal) : val;
|
||||
});
|
||||
|
||||
if (includeHeaders) {
|
||||
colData.push(this.getHeadersText()[colIndex]);
|
||||
validColValues.unshift(this.getHeadersText()[colIndex]);
|
||||
}
|
||||
for (let i = 0, len = data.length; i < len; i++) {
|
||||
let r = data[i],
|
||||
//cols values of current row
|
||||
d = r[1],
|
||||
//data of searched column
|
||||
c = d[colIndex];
|
||||
colData.push(c);
|
||||
}
|
||||
return colData;
|
||||
|
||||
return validColValues;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,7 +63,7 @@ export const isUndef = (obj) => obj === UNDEFINED;
|
|||
* @param {Any} obj
|
||||
* @return {Boolean}
|
||||
*/
|
||||
export const isNull = obj => obj === null;
|
||||
export const isNull = (obj) => obj === null;
|
||||
|
||||
/**
|
||||
* Check passed argument is empty (undefined, null or empty string)
|
||||
|
|
|
@ -350,4 +350,4 @@
|
|||
<td>88.233.19.89</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</table>
|
||||
|
|
|
@ -101,6 +101,7 @@ test('Column operations', function() {
|
|||
equal(id('q1-2').innerHTML, 1.10, 'Q1 result');
|
||||
equal(id('q3-1').innerHTML, 2045, 'Q3 result');
|
||||
equal(id('q3-2').innerHTML, 2.15, 'Q3 result');
|
||||
tf.clearFilters();
|
||||
});
|
||||
|
||||
module('Behaviour checks');
|
||||
|
|
Loading…
Reference in a new issue