PivotEngine Sort Control

The PivotEngine automatically sorts Dimension fields when it generates data summaries. It does not sort Measure fields by default. You can change the sort direction on row and column fields by setting the field's sort property in code. Measure fields are not sorted by default. You can set their sort direction by changing the sortDescriptions property of the engine's pivotView collection. This example shows how you can apply sorts to dimension and measure fields.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjOlap from '@grapecity/wijmo.olap'; import * as wjInput from '@grapecity/wijmo.input'; import * as wjCore from '@grapecity/wijmo'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // create pivot engine var ng = new wjOlap.PivotEngine({ itemsSource: getData(100), rowFields: ['Country', 'Product'], valueFields: ['Sales', 'Expenses'] }); // // create pivot grid var pivotGrid = new wjOlap.PivotGrid('#pivotGrid', { itemsSource: ng, }); // // change the sort order for the dimension (row/column) fields new wjInput.ComboBox('#sortCountry', { itemsSource: 'Ascending,Descending'.split(','), selectedIndexChanged: function (s, e) { ng.fields.getField('Country').descending = s.selectedIndex == 1; } }); new wjInput.ComboBox('#sortProduct', { itemsSource: 'Ascending,Descending'.split(','), selectedIndexChanged: function (s, e) { ng.fields.getField('Product').descending = s.selectedIndex == 1; } }); // // change the sort order for the measure (value) fields var sortSales = new wjInput.ComboBox('#sortSales', { itemsSource: 'None,Ascending,Descending'.split(','), selectedIndexChanged: function (s, e) { updateMeasureSort(); } }); var sortExpenses = new wjInput.ComboBox('#sortExpenses', { itemsSource: 'None,Ascending,Descending'.split(','), selectedIndexChanged: function (s, e) { updateMeasureSort(); } }); // // toggle subtotals document.getElementById('subtotals').addEventListener('click', function (e) { ng.showRowTotals = e.target.checked ? wjOlap.ShowTotals.Subtotals : wjOlap.ShowTotals.GrandTotals; }); // // utility function updateMeasureSort() { var sd = ng.pivotView.sortDescriptions; sd.clear(); addMeasureSort('Sales', sortSales.text); addMeasureSort('Expenses', sortExpenses.text); } // function addMeasureSort(fieldName, sortDirection) { if (sortDirection != 'None') { var sd = ng.pivotView.sortDescriptions, cols = pivotGrid.columns; for (var c = 0; c < cols.length; c++) { var binding = cols[c].binding; if (binding.indexOf(fieldName) == 0) { sd.push(new wjCore.SortDescription(binding, sortDirection == 'Ascending')); } } } } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Grapecity Wijmo OLAP Fields Sort</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-xs-4 panel"> <h4> Sort Dimension fields </h4> <label> Country: <input id="sortCountry"> </label> <label> Product: <input id="sortProduct"> </label> <h4> Sort Measure fields </h4> <label> Sales: <input id="sortSales"> </label> <label> Expenses: <input id="sortExpenses"> </label> <label> Subtotals: <input id="subtotals" type="checkbox"> </label> </div> <div class="col-xs-8"> <div id="pivotGrid"></div> </div> </div> </div> </body> </html> // create some random data export function getData(cnt) { var countries = 'US,Germany,UK,Japan,Italy'.split(','), products = 'Widgets,Gadgets,Doohickeys'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ country: countries[i % countries.length], product: products[i % products.length], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } .wj-pivotgrid { box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .panel label { display: block; } .panel label .wj-combobox { font-weight: normal; } h4 { margin-top: 20pt; } body { margin-bottom: 24pt; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjCore from '@grapecity/wijmo'; import * as wjOlap from '@grapecity/wijmo.olap'; import * as wjInput from '@grapecity/wijmo.input'; // import { Component, Inject, enableProdMode, NgModule, ViewChild } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjInputModule } from '@grapecity/wijmo.angular2.input'; import { WjOlapModule } from '@grapecity/wijmo.angular2.olap'; import { DataService } from './app.data'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { @ViewChild('theGrid') pivotGrid: wjOlap.PivotGrid; @ViewChild('sortSales') sortSales: wjInput.ComboBox; @ViewChild('sortExpenses') sortExpenses: wjInput.ComboBox; ng: wjOlap.PivotEngine; sortOptions: string[]; sortOptions2: string[]; // constructor(@Inject(DataService) private dataService: DataService) { this.ng = new wjOlap.PivotEngine({ itemsSource: dataService.getData(100), rowFields: ['Country', 'Product'], valueFields: ['Sales', 'Expenses'] }); // this.sortOptions = 'Ascending,Descending'.split(','); this.sortOptions2 = 'None,Ascending,Descending'.split(','); } onSelectedIndexChanged(s: wjInput.ComboBox, field: string) { this.ng.fields.getField(field).descending = s.selectedIndex == 1; } onSubtotalsClick(e: MouseEvent) { this.ng.showRowTotals = (e.target as HTMLInputElement).checked ? wjOlap.ShowTotals.Subtotals : wjOlap.ShowTotals.GrandTotals; } updateMeasureSort() { var sd = this.ng.pivotView.sortDescriptions; sd.clear(); this._addMeasureSort('Sales', this.sortSales.text); this._addMeasureSort('Expenses', this.sortExpenses.text); } _addMeasureSort(fieldName: string, sortDirection: string) { if (sortDirection != 'None') { var sd = this.ng.pivotView.sortDescriptions, cols = this.pivotGrid.columns; for (var c = 0; c < cols.length; c++) { var binding = cols[c].binding; if (binding.indexOf(fieldName) == 0) { sd.push(new wjCore.SortDescription(binding, sortDirection == 'Ascending')); } } } } } // @NgModule({ imports: [WjOlapModule, WjInputModule, BrowserModule], declarations: [AppComponent], providers: [DataService], bootstrap: [AppComponent] }) export class AppModule { } // enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Grapecity Wijmo OLAP Fields Sort</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Polyfills --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.min.js"></script> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html> <div class="container-fluid"> <div class="row"> <div class="col-xs-4 panel"> <h4> Sort Dimension fields </h4> <label> Country: <wj-combo-box #countryCombo [itemsSource]="sortOptions" (selectedIndexChanged)='onSelectedIndexChanged(countryCombo, "Country")'></wj-combo-box> </label> <label> Product: <wj-combo-box #productCombo [itemsSource]="sortOptions" (selectedIndexChanged)='onSelectedIndexChanged(productCombo, "Product")'></wj-combo-box> </label> <h4> Sort Measure fields </h4> <label> Sales: <wj-combo-box #sortSales [itemsSource]="sortOptions2" (selectedIndexChanged)="updateMeasureSort()"></wj-combo-box> </label> <label> Expenses: <wj-combo-box #sortExpenses [itemsSource]="sortOptions2" (selectedIndexChanged)="updateMeasureSort()"></wj-combo-box> </label> <label> Subtotals: <input id="subtotals" type="checkbox" (click)="onSubtotalsClick($event)"> </label> </div> <div class="col-xs-8"> <wj-pivot-grid #theGrid [itemsSource]="ng"></wj-pivot-grid> </div> </div> </div> import { Injectable } from '@angular/core'; import * as wjCore from '@grapecity/wijmo'; export interface DataItem { country: string; product: string; downloads: number; sales: number; expenses: number; } @Injectable() export class DataService { getData(cnt: number): DataItem[] { var countries = 'US,Germany,UK,Japan,Italy'.split(','), products = 'Widgets,Gadgets,Doohickeys'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ country: countries[i % countries.length], product: products[i % products.length], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } } .wj-pivotgrid { box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .panel label { display: block; } .panel label .wj-combobox { font-weight: normal; } h4 { margin-top: 20pt; } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <div class="row"> <div class="col-xs-4 panel"> <h4 class="sample-h4"> Sort Dimension fields </h4> <label> Country: <wj-combo-box :items-source="sortOptions" :selectedIndexChanged="onCountrySelectedIndexChanged"></wj-combo-box> </label> <label> Product: <wj-combo-box :items-source="sortOptions" :selectedIndexChanged="onProductSelectedIndexChanged"></wj-combo-box> </label> <h4 class="sample-h4"> Sort Measure fields </h4> <label> Sales: <wj-combo-box :items-source="sortOptions2" :initialized="initializeSortSales" :selectedIndexChanged="updateMeasureSort"></wj-combo-box> </label> <label> Expenses: <wj-combo-box :items-source="sortOptions2" :initialized="initializeSortExpenses" :selectedIndexChanged="updateMeasureSort"></wj-combo-box> </label> <label> Subtotals: <input id="subtotals" type="checkbox" v-on:click="onSubtotalsClick"> </label> </div> <div class="col-xs-8"> <wj-pivot-grid :items-source="ng" :initialized="initializePivotGrid"></wj-pivot-grid> </div> </div> </div> </template> <script> import '@grapecity/wijmo.styles/wijmo.css'; import 'bootstrap.css'; import Vue from 'vue'; import '@grapecity/wijmo.vue2.input'; import '@grapecity/wijmo.vue2.olap'; import * as wjcCore from '@grapecity/wijmo'; import * as wjcOlap from '@grapecity/wijmo.olap'; import { getData } from './data' let App = Vue.extend({ name: "app", data: function() { return { ng: new wjcOlap.PivotEngine({ itemsSource: getData(100), rowFields: ['Country', 'Product'], valueFields: ['Sales', 'Expenses'] }), sortOptions: 'Ascending,Descending'.split(','), sortOptions2: 'None,Ascending,Descending'.split(',') }; }, methods: { initializePivotGrid(pivotGrid) { this.pivotGrid = pivotGrid; }, initializeSortSales(combo){ this.sortSales = combo; }, initializeSortExpenses(combo){ this.sortExpenses = combo; }, onCountrySelectedIndexChanged(combo) { this.ng.fields.getField('Country').descending = combo.selectedIndex == 1; }, onProductSelectedIndexChanged(combo) { this.ng.fields.getField('Product').descending = combo.selectedIndex == 1; }, onSubtotalsClick(e) { this.ng.showRowTotals = e.target.checked ? wjcOlap.ShowTotals.Subtotals : wjcOlap.ShowTotals.GrandTotals; }, updateMeasureSort() { let sd = this.ng.pivotView.sortDescriptions; sd.clear(); this._addMeasureSort('Sales', this.sortSales.text); this._addMeasureSort('Expenses', this.sortExpenses.text); }, _addMeasureSort(fieldName, sortDirection) { if (sortDirection != 'None') { let sd = this.ng.pivotView.sortDescriptions, cols = this.pivotGrid.columns; for (let c = 0; c < cols.length; c++) { let binding = cols[c].binding; if (binding.indexOf(fieldName) == 0) { sd.push(new wjcCore.SortDescription(binding, sortDirection == 'Ascending')); } } } } } }); new Vue({ render: h => h(App) }).$mount("#app"); </script> <style> .wj-pivotgrid { box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .panel label { display: block; } .panel label .wj-combobox { font-weight: normal; } h4.sample-h4 { margin-top: 20pt; } body { margin-bottom: 24pt; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Grapecity Wijmo OLAP Fields Sort</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); </script> </head> <body> <div id="app"> </div> </body> </html> export function getData(cnt) { var countries = 'US,Germany,UK,Japan,Italy'.split(','), products = 'Widgets,Gadgets,Doohickeys'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ country: countries[i % countries.length], product: products[i % products.length], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; } import './app.css'; import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as Olap from '@grapecity/wijmo.react.olap'; import * as wjInput from '@grapecity/wijmo.react.input'; import * as wjcCore from '@grapecity/wijmo'; import * as wjcOlap from '@grapecity/wijmo.olap'; import { getData } from './data'; class App extends React.Component { constructor(props) { super(props); this.state = { ng: new wjcOlap.PivotEngine({ itemsSource: getData(100), rowFields: ['Country', 'Product'], valueFields: ['Sales', 'Expenses'] }), sortOptions: 'Ascending,Descending'.split(','), sortOptions2: 'None,Ascending,Descending'.split(',') }; } render() { return (<div className="container-fluid"> <div className="row"> <div className="col-xs-4 panel"> <h4 className="sample-h4"> Sort Dimension fields </h4> <label> Country: <wjInput.ComboBox itemsSource={this.state.sortOptions} selectedIndexChanged={this.onCountrySelectedIndexChanged.bind(this)}></wjInput.ComboBox> </label> <label> Product: <wjInput.ComboBox itemsSource={this.state.sortOptions} selectedIndexChanged={this.onProductSelectedIndexChanged.bind(this)}></wjInput.ComboBox> </label> <h4 className="sample-h4"> Sort Measure fields </h4> <label> Sales: <wjInput.ComboBox itemsSource={this.state.sortOptions2} initialized={this.initializeSortSales.bind(this)} selectedIndexChanged={this.updateMeasureSort.bind(this)}></wjInput.ComboBox> </label> <label> Expenses: <wjInput.ComboBox itemsSource={this.state.sortOptions2} initialized={this.initializeSortExpenses.bind(this)} selectedIndexChanged={this.updateMeasureSort.bind(this)}></wjInput.ComboBox> </label> <label> Subtotals: <input id="subtotals" type="checkbox" onClick={this.onSubtotalsClick.bind(this)}/> </label> </div> <div className="col-xs-8"> <Olap.PivotGrid itemsSource={this.state.ng} initialized={this.initializePivotGrid.bind(this)}></Olap.PivotGrid> </div> </div> </div>); } initializePivotGrid(pivotGrid) { this.pivotGrid = pivotGrid; } initializeSortSales(combo) { this.sortSales = combo; } initializeSortExpenses(combo) { this.sortExpenses = combo; } onCountrySelectedIndexChanged(combo) { this.state.ng.fields.getField('Country').descending = combo.selectedIndex == 1; } onProductSelectedIndexChanged(combo) { this.state.ng.fields.getField('Product').descending = combo.selectedIndex == 1; } onSubtotalsClick(e) { this.state.ng.showRowTotals = e.target.checked ? wjcOlap.ShowTotals.Subtotals : wjcOlap.ShowTotals.GrandTotals; } updateMeasureSort() { let sd = this.state.ng.pivotView.sortDescriptions; sd.clear(); this._addMeasureSort('Sales', this.sortSales.text); this._addMeasureSort('Expenses', this.sortExpenses.text); } _addMeasureSort(fieldName, sortDirection) { if (sortDirection != 'None') { let sd = this.state.ng.pivotView.sortDescriptions, cols = this.pivotGrid.columns; for (let c = 0; c < cols.length; c++) { let binding = cols[c].binding; if (binding.indexOf(fieldName) == 0) { sd.push(new wjcCore.SortDescription(binding, sortDirection == 'Ascending')); } } } } } ReactDOM.render(<App />, document.getElementById('app')); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>AutoComplete</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div id="app"></div> </body> </html> .wj-pivotgrid { box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23); } .panel label { display: block; } .panel label .wj-combobox { font-weight: normal; } h4.sample-h4 { margin-top: 20pt; } body { margin-bottom: 24pt; } export function getData(cnt) { var countries = 'US,Germany,UK,Japan,Italy'.split(','), products = 'Widgets,Gadgets,Doohickeys'.split(','), data = []; for (var i = 0; i < cnt; i++) { data.push({ country: countries[i % countries.length], product: products[i % products.length], downloads: Math.round(Math.random() * 20000), sales: Math.random() * 10000, expenses: Math.random() * 5000 }); } return data; }