PivotTable Filter

SpreadJS PivotTables support Label Filters, and Value Filters. These functions can be used to filter data. Different filters can be set to obtain the required data.

Description
app.jsx
app-func.jsx
app-class.jsx
index.html
styles.css
Copy to CodeMine

You can set different filters to get the data that you need.

The user can set a filter as follows:

///* function labelFilter(fieldName: string, filterInfo: GC.Spread.Pivot.IPivotTextFilterInfo | GC.Spread.Pivot.IPivotConditionFilterInfo): GC.Spread.Pivot.IPivotTextFilterInfo | GC.Spread.Pivot.IPivotConditionFilterInfo | void
/**
 * get or set label filter info for a field
 * @param {string} fieldName the target field name of pivot table
 * @param {GC.Spread.Pivot.IPivotFilterInfo} filterInfo the label filter info when set
 * @returns get pivot table labelFilter information
 */
labelFilter (fieldName: string, filterInfo?: IPivotConditionFilterInfo | IPivotTextFilterInfo): IPivotConditionFilterInfo | IPivotTextFilterInfo | void;
///* function valueFilter(fieldName: string, filterInfo:GC.Spread.Pivot.IPivotConditionFilterInfo):GC.Spread.Pivot.IPivotConditionFilterInfo | void
/**
 * get or set value filter info for a field
 * @param {string} fieldName the target field name of pivot table
 * @param {GC.Spread.Pivot.IPivotFilterInfo} filterInfo the value filter info when set
 * @returns the pivot table value information
 */
valueFilter (fieldName: string, filterInfo?: IPivotConditionFilterInfo): IPivotConditionFilterInfo | void

You can use the Label Filter as follows:

    let labelFilter = {condition:{conType:GC.Pivot.PivotConditionType.caption, val:[20,30], operator: GC.Pivot.PivotCaptionFilterOperator.between}};
    // if val.length === 1, val=[20,null]
    pivotTable.labelFilter("region", labelFilter);
    let itemList = ["Europe", "South America", "Asia", "Australia"]
    let labelFilter = { textItem: { list: itemList, isAll: false } };
    pivotTable.labelFilter("region", labelFilter);

You can use the Value Filter as follows:

    let valueFilter = { condition: { conType: GC.Pivot.PivotConditionType.value, val: [50, 100], operator: GC.Pivot.PivotValueFilterOperator.between }, conditionByName: "Sum of amount" };
    // if val.length === 1, val=[20,null]
    pivotTable.valueFilter("region", valueFilter);

SpreadJS PivotTable supports five conditions:

    export interface IPivotCaptionConditionFilterInfo{
        conType: GC.Pivot.PivotConditionType;
        val: [string, string];
        operator: GC.Pivot.PivotCaptionFilterOperator;
    }
    export interface IPivotDateConditionFilterInfo{
        conType: GC.Pivot.PivotConditionType;
        val: [Date, Date];
        operator: GC.Pivot.PivotDateFilterOperator;
        isWholeDay: boolean;
    }
    export interface IPivotTop10ConditionFilterInfo{
        conType: GC.Pivot.PivotConditionType;
        val: number;
        type: GC.Pivot.PivotTop10FilterType; //The type of data involved in the calculation
        operator: GC.Pivot.PivotTop10FilterOperator;
    }
    export interface IPivotValueConditionInfo{
        conType: GC.Pivot.PivotConditionType;
        val: [number, number];
        operator: GC.Pivot.PivotValueFilterOperator;
    }
    export interface ITextCollectionCondition{
        list: string[];// field item list
        isAll: boolean;// is field all item or no
    }

For date filter operator, we also support month to date and quarter to date.

  • conType: Used to describe the type of condition
  • operator: Used to describe the operate type of filter; setting up an operator corresponds to the type of conType

SpreadJS PivotTables support two filters, and users can set filters using the following two data types, for example:

    export interface IPivotConditionFilterInfo {
        conditionByName: string;
        condition: GC.Pivot.IPivotCaptionConditionFilterInfo | GC.Pivot.IPivotDateConditionFilterInfo | GC.Pivot.IPivotTop10ConditionFilterInfo | GC.Pivot.IPivotValueConditionInfo
    }

    export interface IPivotTextFilterInfo{
        textItem: GC.Spread.Pivot.ITextCollectionCondition;
    }
You can set different filters to get the data that you need. The user can set a filter as follows: You can use the Label Filter as follows: You can use the Value Filter as follows: SpreadJS PivotTable supports five conditions: For date filter operator, we also support month to date and quarter to date. conType: Used to describe the type of condition operator: Used to describe the operate type of filter; setting up an operator corresponds to the type of conType SpreadJS PivotTables support two filters, and users can set filters using the following two data types, for example:
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample // ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import "@mescius/spread-sheets-pivot-addon"; import { SpreadSheets } from '@mescius/spread-sheets-react'; import './styles.css'; const useState = React.useState; export function AppFunc() { const [spread, setSpread] = useState(null); const [pivotTable, setPivotTable] = useState(null); const initSpread = (spread) => { spread.suspendPaint(); spread.setSheetCount(2); let sheet1 = spread.getSheet(0); let sheet2 = spread.getSheet(1); let tableName = getSource(sheet2, pivotSales); let pt = addPivotTable(sheet1, tableName); setSpread(spread); setPivotTable(pt); spread.resumePaint(); } const getSource = (sheet, tableSource) => { sheet.name("DataSource"); sheet.setRowCount(117); sheet.setColumnWidth(0, 120); sheet.getCell(-1, 0).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 2).formatter("$ #,##0"); let table = sheet.tables.add('table', 0, 0, 117, 6); for (let i = 2; i <= 117; i++) { sheet.setFormula(i - 1, 5, '=D' + i + '*E' + i) } table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); sheet.setArray(0, 0, tableSource); return table.name(); } const addPivotTable = (sheet, source) => { sheet.suspendPaint(); sheet.name("PivotTable"); sheet.setRowCount(10000); let pt = sheet.pivotTables.add("PivotTable", source, 1, 1, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.light8); pt.suspendLayout(); pt.add("salesperson", "Salesperson", GC.Spread.Pivot.PivotTableFieldType.rowField); pt.add("car", "Cars", GC.Spread.Pivot.PivotTableFieldType.rowField); let groupInfo = { originFieldName: "date", dateGroups: [{ by: GC.Pivot.DateGroupType.quarters }] }; pt.group(groupInfo); pt.add("Quarters (date)", "Quarters (date)", GC.Spread.Pivot.PivotTableFieldType.columnField); pt.add("quantity", "Quantity", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pt.resumeLayout(); sheet.resumePaint(); pt.autoFitColumn(); return pt; } return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> </SpreadSheets> </div> <div class="options-container"> <div class="whole-field">The following operations all work on <b>Salesperson</b> Field:</div> <LabelFilter spread={spread} pivotTable={pivotTable}></LabelFilter> <ValueFilter spread={spread} pivotTable={pivotTable}></ValueFilter> </div> </div> ); } function LabelFilter(props) { const [labelType, setLabelType] = useState(1); const [value1, setValue1] = useState(""); const [value2, setValue2] = useState(""); const handleLabel = () => { const spread = props.spread; let pivotTable = props.pivotTable; spread.suspendPaint(); let labelFilterValue1 = value1, labelFilterValue2 = value2; if (labelType) { if (labelType < 13) { labelFilterValue2 = null; } pivotTable.labelFilter("Salesperson", { condition: { conType: GC.Pivot.PivotConditionType.caption, val: [labelFilterValue1, labelFilterValue2], operator: labelType - 1 } }); } else { pivotTable.labelFilter("Salesperson", null); } spread.resumePaint(); } const clearLabel = () => { const spread = props.spread; let pivotTable = props.pivotTable; spread.suspendPaint(); pivotTable.labelFilter("Salesperson", null); setValue1(""); setValue2(""); spread.resumePaint(); } return ( <div> <div>Label Filter:</div> <div className="pivottable-filter label-filter"> <select value={labelType} onChange={e => setLabelType(e.target.value)} name="labelFilter" id="labelFilter" className="pivot-filter"> <option value="1">equalsTo</option> <option value="2">notEqualsTo</option> <option value="3">beginsWith</option> <option value="4">doesNotBeginWith</option> <option value="5">endsWith</option> <option value="6">doesNotEndWith</option> <option value="7">contains</option> <option value="8">doesNotContain</option> <option value="9">greaterThan</option> <option value="10">greaterThanOrEqualsTo</option> <option value="11">lessThan</option> <option value="12">lessThanOrEqualsTo</option> <option value="13">between</option> <option value="14">notBetween</option> </select> <input type="text" className="label-filter-input filter-input" id="label-val1" placeholder="value1" onChange={e => setValue1(e.target.value)} value={value1}></input> <input type="text" className="label-filter-input filter-input" id="label-val2" placeholder="value2" onChange={e => setValue2(e.target.value)} value={value2}></input> </div> <input type="button" className="set-label-filter set-filter" id="set-label-filter" value="Set Label Filter" onClick={handleLabel}></input> <br /> <input type="button" className="set-label-filter set-filter" id="clear-label-filter" value="Clear Label Filter" onClick={clearLabel}></input> <br /> <hr /> </div> ); } function ValueFilter(props) { const [valueType, setValueType] = useState(1); const [value1, setValue1] = useState(""); const [value2, setValue2] = useState(""); const handleValue = () => { const spread = props.spread; let pivotTable = props.pivotTable; spread.suspendPaint(); let valueFilterValue1 = +value1, valueFilterValue2 = +value2; if (valueType) { if (valueType < 7) { valueFilterValue2 = null; } pivotTable.valueFilter("Salesperson", { condition: { conType: GC.Pivot.PivotConditionType.value, val: [valueFilterValue1, valueFilterValue2], operator: valueType - 1 }, conditionByName: "Quantity" }); } else { pivotTable.valueFilter("Salesperson", null); } spread.resumePaint(); } const clearValue = () => { const spread = props.spread; let pivotTable = props.pivotTable; spread.suspendPaint(); pivotTable.valueFilter("Salesperson", null); setValueType(0); setValue1(''); setValue2(''); spread.resumePaint(); } return ( <div> <div className="value-filter-label">Value Filter:</div> <div className="pivottable-filter value-filter"> <select value={valueType} onChange={e => setValueType(e.target.value)} name="valueFilter" id="valueFilter" className="pivot-filter"> <option value="1">equalsTo</option> <option value="2">notEqualsTo</option> <option value="3">greaterThan</option> <option value="4">greaterThanOrEqualsTo</option> <option value="5">lessThan</option> <option value="6">lessThanOrEqualsTo</option> <option value="7">between</option> <option value="8">notBetween</option> </select> <input type="text" className="value-filter-input filter-input" id="value-val1" onChange={e => setValue1(e.target.value)} value={value1} placeholder="value1"></input> <input type="text" className="value-filter-input filter-input" id="value-val2" onChange={e => setValue2(e.target.value)} value={value2} placeholder="value2"></input> </div> <input type="button" className="set-value-filter set-filter" id="set-value-filter" onClick={handleValue} value="Set Value Filter"></input> <br /> <input type="button" className="set-value-filter set-filter" id="clear-value-filter" onClick={clearValue} value="Clear Value Filter"></input> <br /> <hr /> </div> ); }
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import "@mescius/spread-sheets-pivot-addon"; import { SpreadSheets } from '@mescius/spread-sheets-react'; import './styles.css'; const Component = React.Component; export class App extends Component { constructor(props) { super(props); this.state = { renderChild: false } } render() { return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> </SpreadSheets> </div> {this.state.renderChild ? (<div class="options-container"> <div class="whole-field">The following operations all work on <b>Salesperson</b> Field:</div> <LabelFilter spread={this.spread} pivotTable={this.pivotTable}></LabelFilter> <ValueFilter spread={this.spread} pivotTable={this.pivotTable}></ValueFilter> </div>) : ""} </div> ); } componentDidMount() { this.setState(() => ({ renderChild: true })) } initSpread(spread) { this.spread = spread; spread.suspendPaint(); spread.setSheetCount(2); let sheet1 = spread.getSheet(0); let sheet2 = spread.getSheet(1); let tableName = this.getSource(sheet2, pivotSales); let pivotTable = this.addPivotTable(sheet1, tableName); this.pivotTable = pivotTable; spread.resumePaint(); } getSource(sheet, tableSource) { sheet.name("DataSource"); sheet.setRowCount(117); sheet.setColumnWidth(0, 120); sheet.getCell(-1, 0).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 2).formatter("$ #,##0"); let table = sheet.tables.add('table', 0, 0, 117, 6); for (let i = 2; i <= 117; i++) { sheet.setFormula(i - 1, 5, '=D' + i + '*E' + i) } table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); sheet.setArray(0, 0, tableSource); return table.name(); } addPivotTable(sheet, source) { sheet.suspendPaint(); sheet.name("PivotTable"); sheet.setRowCount(10000); let pivotTable = sheet.pivotTables.add("PivotTable", source, 1, 1, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.light8); pivotTable.suspendLayout(); pivotTable.add("salesperson", "Salesperson", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("car", "Cars", GC.Spread.Pivot.PivotTableFieldType.rowField); let groupInfo = { originFieldName: "date", dateGroups: [{ by: GC.Pivot.DateGroupType.quarters }] }; pivotTable.group(groupInfo); pivotTable.add("Quarters (date)", "Quarters (date)", GC.Spread.Pivot.PivotTableFieldType.columnField); pivotTable.add("quantity", "Quantity", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pivotTable.resumeLayout(); sheet.resumePaint(); pivotTable.autoFitColumn(); return pivotTable; } } class LabelFilter extends Component { constructor(props) { super(props); this.state = { labelType: "1", value1: "", value2: "" } this.handleLabel = this.handleLabel.bind(this); this.clearLabel = this.clearLabel.bind(this); } handleLabel() { const labelInfo = this.state; if (labelInfo.value1 === null && labelInfo.value2 === null) { return; } const spread = this.props.spread; let pivotTable = this.props.pivotTable; spread.suspendPaint(); let labelType = +labelInfo.labelType, labelFilterValue1 = labelInfo.value1, labelFilterValue2 = labelInfo.value2; if (labelType) { if (labelType < 13) { labelFilterValue2 = null; } pivotTable.labelFilter("Salesperson", { condition: { conType: GC.Pivot.PivotConditionType.caption, val: [labelFilterValue1, labelFilterValue2], operator: labelType - 1 } }); } else { pivotTable.labelFilter("Salesperson", null); } spread.resumePaint(); } clearLabel() { const spread = this.props.spread; let pivotTable = this.props.pivotTable; spread.suspendPaint(); pivotTable.labelFilter("Salesperson", null); this.state.labelFilterValue1 = ""; this.state.labelFilterValue2 = ""; spread.resumePaint(); } render() { return ( <div> <div>Label Filter:</div> <div className="pivottable-filter label-filter"> <select value={this.state.labelType} onChange={e => { this.setState({ labelType: e.target.value }) }} name="labelFilter" id="labelFilter" className="pivot-filter"> <option value="1">equalsTo</option> <option value="2">notEqualsTo</option> <option value="3">beginsWith</option> <option value="4">doesNotBeginWith</option> <option value="5">endsWith</option> <option value="6">doesNotEndWith</option> <option value="7">contains</option> <option value="8">doesNotContain</option> <option value="9">greaterThan</option> <option value="10">greaterThanOrEqualsTo</option> <option value="11">lessThan</option> <option value="12">lessThanOrEqualsTo</option> <option value="13">between</option> <option value="14">notBetween</option> </select> <input type="text" className="label-filter-input filter-input" id="label-val1" placeholder="value1" onChange={e => { this.setState({ value1: e.target.value }) }} value={this.state.value1}></input> <input type="text" className="label-filter-input filter-input" id="label-val2" placeholder="value2" onChange={e => { this.setState({ value2: e.target.value }) }} value={this.state.value2}></input> </div> <input type="button" className="set-label-filter set-filter" id="set-label-filter" value="Set Label Filter" onClick={this.handleLabel}></input> <br /> <input type="button" className="set-label-filter set-filter" id="clear-label-filter" value="Clear Label Filter" onClick={this.clearLabel}></input> <br /> <hr /> </div> ); } } class ValueFilter extends Component { constructor(props) { super(props); this.state = { valueType: "1", value1: null, value2: null } this.handleValue = this.handleValue.bind(this); this.clearValue = this.clearValue.bind(this); } handleValue() { const valueInfo = this.state; const spread = this.props.spread; let pivotTable = this.props.pivotTable; spread.suspendPaint(); let valueType = +valueInfo.valueType, valueFilterValue1 = +valueInfo.value1, valueFilterValue2 = +valueInfo.value2; if (valueType) { if (valueType < 7) { valueFilterValue2 = null; } pivotTable.valueFilter("Salesperson", { condition: { conType: GC.Pivot.PivotConditionType.value, val: [valueFilterValue1, valueFilterValue2], operator: valueType - 1 }, conditionByName: "Quantity" }); } else { pivotTable.valueFilter("Salesperson", null); } spread.resumePaint(); } clearValue() { const spread = this.props.spread; let pivotTable = this.props.pivotTable; spread.suspendPaint(); pivotTable.valueFilter("Salesperson", null); this.setState({ valueType: "0", value1: "", value2: "" }) spread.resumePaint(); } render() { return ( <div> <div className="value-filter-label">Value Filter:</div> <div className="pivottable-filter value-filter"> <select value={this.state.valueType} onChange={e => { this.setState({ valueType: e.target.value }) }} name="valueFilter" id="valueFilter" className="pivot-filter"> <option value="1">equalsTo</option> <option value="2">notEqualsTo</option> <option value="3">greaterThan</option> <option value="4">greaterThanOrEqualsTo</option> <option value="5">lessThan</option> <option value="6">lessThanOrEqualsTo</option> <option value="7">between</option> <option value="8">notBetween</option> </select> <input type="text" className="value-filter-input filter-input" id="value-val1" onChange={e => { this.setState({ value1: e.target.value }) }} value={this.state.value1} placeholder="value1"></input> <input type="text" className="value-filter-input filter-input" id="value-val2" onChange={e => { this.setState({ value2: e.target.value }) }} value={this.state.value2} placeholder="value2"></input> </div> <input type="button" className="set-value-filter set-filter" id="set-value-filter" onClick={this.handleValue} value="Set Value Filter"></input> <br /> <input type="button" className="set-value-filter set-filter" id="clear-value-filter" onClick={this.clearValue} value="Clear Value Filter"></input> <br /> <hr /> </div> ); } }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/spread/source/data/pivot-data.js" type="text/javascript"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/en/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app" style="height: 100%;"></div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 280px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .pivottable-filter{ height: 100px; } .pivot-filter{ width: 200px; height: 25px; display: block; margin-bottom: 10px; float: left; } .filter-input{ width: 200px; height: 20px; display: block; /* margin-left: 15px; */ margin-top: 10px; } .set-filter{ width: 200px; margin-top: 20px; /* float: right; */ } .value-filter-label{ margin-top: 25px; } .sort-type{ width: 200px; margin-top: 25px; display: block; } .sort{ width: 200px; margin-top: 10px; display: block; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .whole-field{ margin-bottom: 10px; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);