OutlineMode

This sample demonstrates the PivotGrid's new outlineMode property. In outline mode, the PivotGrid renders row fields in an outline format that is more compact and reduces the amount of white space shown on the screen. Outline mode is recommended for views with a large number of row fields.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import { PivotEngine, PivotPanel, PivotGrid } from '@grapecity/wijmo.olap'; import { CellRange } from '@grapecity/wijmo.grid'; import { toggleClass } from '@grapecity/wijmo'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // create the olap components let theEngine = new PivotEngine({ itemsSource: getData(1000), showRowTotals: 'Subtotals', showColumnTotals: 'None', totalsBeforeData: true, rowFields: ['Country', 'Product', 'Color'], valueFields: ['Sales', 'Expenses', 'Downloads'] }); // let thePanel = new PivotPanel('#thePanel', { engine: theEngine, }); // let theGrid = new PivotGrid('#theGrid', { itemsSource: theEngine, outlineMode: true, loadedRows: (s) => { let totalIndex = theEngine.totalsBeforeData ? 0 : s.rows.length - 1; s.rows[totalIndex].visible = false; } }); // // customize the olap components document.getElementById('outline').addEventListener('click', e => { theGrid.outlineMode = e.target.checked; if (theGrid.outlineMode) { let before = document.getElementById('before'); theEngine.totalsBeforeData = before.checked = true; } else { let before = document.getElementById('style'); before.checked = false; toggleClass(theGrid.hostElement, 'outline', false); } }); // document.getElementById('style').addEventListener('click', e => { let customStyle = e.target.checked; toggleClass(theGrid.hostElement, 'outline', customStyle); }); // document.getElementById('before').addEventListener('click', e => { theEngine.totalsBeforeData = e.target.checked; }); // document.getElementById('headers').addEventListener('click', e => { theGrid.showRowFieldHeaders = e.target.checked; }); // // export to CSV document.getElementById('csv').addEventListener('click', e => { let rng = new CellRange(0, 0, theGrid.rows.length - 1, theGrid.columns.length - 1), csv = theGrid.getClipString(rng, true, true, true); // exportFile(csv, 'FlexGrid.csv'); }); // function exportFile(csv, fileName) { let fileType = 'txt/csv;charset=utf-8'; // if (navigator.msSaveBlob) { // IE navigator.msSaveBlob(new Blob([csv], { type: fileType }), fileName); } else { let e = document.createElement('a'); e.setAttribute('href', 'data:' + fileType + ',' + encodeURIComponent(csv)); e.setAttribute('download', fileName); e.style.display = 'none'; document.body.appendChild(e); e.click(); document.body.removeChild(e); } } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Grapecity Wijmo OLAP Pivot Grid OutlineMode</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"> <label> outlineMode <input id="outline" type="checkbox" checked> </label><br /> <label> custom style <input id="style" type="checkbox" checked> </label><br /> <label> totalsBeforeData <input id="before" type="checkbox" checked> </label><br /> <label> showRowFieldHeaders <input id="headers" type="checkbox" checked> </label><br /> <div class="row"> <div class="col-xs-5"> <div id="thePanel"></div> </div> <div class="col-xs-7"> <div id="theGrid" class="outline"></div> <button id="csv" class="btn btn-primary">Export to CSV</button> </div> </div> </div> </body> </html> // // get the raw data export function getData(count) { let countries = ['Germany', 'Italy', 'Japan', 'UK', 'US'], products = ['Widgets', 'Gadgets', 'Doohickeys'], colors = ['Red', 'Green', 'Blue', 'Yellow', 'Purple', 'White', 'Black', 'Magenta'], data = []; // for (let i = 0; i < count; i++) { let trend = (i % countries.length + 1) * (i % products.length + 1); data.push({ country: randomItem(countries), product: randomItem(products), color: randomItem(colors), active: i % 5 == 0, due: new Date(), sales: Math.random() * 10000 * trend, expenses: Math.random() * 5000 * trend, downloads: Math.random() * 100000 * trend }); } // return data; } // // get a random item from an array function randomItem(arr) { return arr[Math.floor(Math.random() * arr.length)]; } .wj-pivotgrid { max-height: 400px; box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .wj-pivotgrid.outline .wj-cell { border-right: none; border-bottom: none; background: #fff; color: #000; } body { margin-bottom: 24pt; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import { Component, Inject, enableProdMode, NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjOlapModule } from '@grapecity/wijmo.angular2.olap'; import { PivotEngine, PivotGrid } from '@grapecity/wijmo.olap'; import { CellRange } from '@grapecity/wijmo.grid'; import { DataService } from './app.data'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { ng: PivotEngine; outlineMode = true; customStyle = true; showRowFieldHeaders = true; constructor(@Inject(DataService) private dataService: DataService) { this.ng = new PivotEngine({ itemsSource: dataService.getData(1000), // raw data showRowTotals: 'Subtotals', showColumnTotals: 'None', totalsBeforeData: true, rowFields: ['Country', 'Product', 'Color'], valueFields: ['Sales', 'Expenses', 'Downloads'] }); } outlineModeChanged() { if (this.outlineMode) { this.ng.totalsBeforeData = true; } else { this.customStyle = false; } } exportToCsv(grid: PivotGrid) { let rng = new CellRange(0, 0, grid.rows.length - 1, grid.columns.length - 1), csv = grid.getClipString(rng, true, true, true); this.exportFile(csv, 'FlexGrid.csv'); } exportFile(csv: string, fileName: string) { let fileType = 'txt/csv;charset=utf-8'; if (navigator.msSaveBlob) { // IE navigator.msSaveBlob(new Blob([csv], { type: fileType }), fileName); } else { let e = document.createElement('a'); e.setAttribute('href', 'data:' + fileType + ',' + encodeURIComponent(csv)); e.setAttribute('download', fileName); e.style.display = 'none'; document.body.appendChild(e); e.click(); document.body.removeChild(e); } } } @NgModule({ imports: [WjOlapModule, BrowserModule, FormsModule], 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 Pivot Grid OutlineMode</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"> <label> outlineMode <input id="outline" type="checkbox" [(ngModel)]="outlineMode" (change)="outlineModeChanged()" /> </label><br /> <label> custom style <input id="style" type="checkbox" [(ngModel)]="customStyle" /> </label><br /> <label> totalsBeforeData <input id="before" type="checkbox" [(ngModel)]="ng.totalsBeforeData" /> </label><br /> <label> showRowFieldHeaders <input id="headers" type="checkbox" [(ngModel)]="showRowFieldHeaders" /> </label><br /> <div class="row"> <div class="col-xs-5"> <wj-pivot-panel [itemsSource]="ng"> </wj-pivot-panel> </div> <div class="col-xs-7"> <wj-pivot-grid #grid [class.outline]="customStyle" [itemsSource]="ng" [outlineMode]="outlineMode" [showRowFieldHeaders]="showRowFieldHeaders"> </wj-pivot-grid> <button class="btn btn-primary" (click)="exportToCsv(grid)"> Export to CSV </button> </div> </div> </div> import { Injectable } from '@angular/core'; @Injectable() export class DataService { getData(cnt: number): any[] { let countries = ['Germany', 'Italy', 'Japan', 'UK', 'US'], products = ['Widgets', 'Gadgets', 'Doohickeys'], colors = ['Red', 'Green', 'Blue', 'Yellow', 'Purple', 'White', 'Black', 'Magenta'], data = []; for (let i = 0; i < cnt; i++) { let trend = (i % countries.length + 1) * (i % products.length + 1); data.push({ country: randomItem(countries), product: randomItem(products), color: randomItem(colors), active: i % 5 == 0, due: new Date(), sales: Math.random() * 10000 * trend, expenses: Math.random() * 5000 * trend, downloads: Math.random() * 100000 * trend }); } return data; } } function randomItem(arr: string[]): string { return arr[Math.floor(Math.random() * arr.length)]; } .wj-pivotgrid { max-height: 400px; box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .wj-pivotgrid.outline .wj-cell { border-right: none; border-bottom: none; background: #fff; color: #000; } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <label> outlineMode <input id="outline" type="checkbox" v-model="outlineMode" v-on:change="outlineModeChanged"> </label><br/> <label> custom style <input id="style" type="checkbox" v-model="customStyle"> </label><br/> <label> totalsBeforeData <input id="before" type="checkbox" v-model="ng.totalsBeforeData"> </label><br/> <label> showRowFieldHeaders <input id="headers" type="checkbox" v-model="showRowFieldHeaders"> </label><br/> <div class="row"> <div class="col-xs-5"> <wj-pivot-panel :items-source="ng"></wj-pivot-panel> </div> <div class="col-xs-7" :class="customStyle ? 'outline' : ''"> <wj-pivot-grid control="grid" :items-source="ng" :outline-mode="outlineMode" :show-row-field-headers="showRowFieldHeaders"> </wj-pivot-grid> <button class="btn btn-primary" v-on:click="exportToCsv()"> Export to CSV </button> </div> </div> </div> </template> <script> import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import Vue from 'vue'; import '@grapecity/wijmo.vue2.olap'; import { PivotEngine } from '@grapecity/wijmo.olap'; import { CellRange } from '@grapecity/wijmo.grid'; import { getData } from './data'; let App = Vue.extend({ name: "app", data: function () { return { ng: new PivotEngine({ itemsSource: getData(1000), showRowTotals: 'Subtotals', showColumnTotals: 'None', totalsBeforeData: true, rowFields: ['Country', 'Product', 'Color'], valueFields: ['Sales', 'Expenses', 'Downloads'] }), outlineMode: true, customStyle: true, totalsBeforeData: true, showRowFieldHeaders: true }; }, methods: { outlineModeChanged() { if (this.outlineMode) { this.ng.totalsBeforeData = this.totalsBeforeData = true; } else { this.customStyle = false; } }, exportToCsv() { let grid = this.grid, // exposed with "control" attribute rng = new CellRange(0, 0, grid.rows.length - 1, grid.columns.length - 1), csv = grid.getClipString(rng, true, true, true); exportFile(csv, 'FlexGrid.csv'); } } }); new Vue({ render: h => h(App) }).$mount("#app"); function exportFile(csv, fileName) { let fileType = 'txt/csv;charset=utf-8'; if (navigator.msSaveBlob) { // IE navigator.msSaveBlob(new Blob([csv], { type: fileType }), fileName); } else { let e = document.createElement('a'); e.setAttribute('href', 'data:' + fileType + ',' + encodeURIComponent(csv)); e.setAttribute('download', fileName); e.style.display = 'none'; document.body.appendChild(e); e.click(); document.body.removeChild(e); } } </script> <style> .wj-pivotgrid { max-height: 400px; box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .outline .wj-pivotgrid .wj-cell { border-right: none; border-bottom: none; background: #fff; color: #000; } 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 Pivot Grid OutlineMode</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> // get the raw data export function getData(count) { let countries = ['Germany', 'Italy', 'Japan', 'UK', 'US'], products = ['Widgets', 'Gadgets', 'Doohickeys'], colors = ['Red', 'Green', 'Blue', 'Yellow', 'Purple', 'White', 'Black', 'Magenta'], data = []; for (let i = 0; i < count; i++) { let trend = (i % countries.length + 1) * (i % products.length + 1); data.push({ country: randomItem(countries), product: randomItem(products), color: randomItem(colors), active: i % 5 == 0, due: new Date(), sales: Math.random() * 10000 * trend, expenses: Math.random() * 5000 * trend, downloads: Math.random() * 100000 * trend }); } return data; } // get a random item from an array function randomItem(arr) { return arr[Math.floor(Math.random() * arr.length)]; } 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.olap'; import * as wjcOlap from '@grapecity/wijmo.react.olap'; import { CellRange } from '@grapecity/wijmo.grid'; import { getData } from './data'; // class App extends React.Component { // // initialize state constructor(props) { super(props); // this._ng = new olap.PivotEngine({ itemsSource: getData(1000), showRowTotals: 'Subtotals', showColumnTotals: 'None', totalsBeforeData: true, rowFields: ['Country', 'Product', 'Color'], valueFields: ['Sales', 'Expenses', 'Downloads'] }); // this.state = { outlineMode: true, customStyle: true, totalsBeforeData: true, showRowFieldHeaders: true }; } // render() { return (<div className="container-fluid"> <label> outlineMode{' '} <input id="outlineMode" type="checkbox" checked={this.state.outlineMode} onChange={this._handleInputChange.bind(this)}/> </label><br /> <label> custom style{' '} <input id="customStyle" type="checkbox" checked={this.state.customStyle} onChange={this._handleInputChange.bind(this)}/> </label><br /> <label> totalsBeforeData{' '} <input id="totalsBeforeData" type="checkbox" checked={this.state.totalsBeforeData} onChange={this._handleInputChange.bind(this)}/> </label><br /> <label> showRowFieldHeaders{' '} <input id="showRowFieldHeaders" type="checkbox" checked={this.state.showRowFieldHeaders} onChange={this._handleInputChange.bind(this)}/> </label><br /> <div className="row"> <div className="col-xs-5"> <wjcOlap.PivotPanel itemsSource={this._ng}> </wjcOlap.PivotPanel> </div> <div className={'col-xs-7' + (this.state.customStyle ? ' outline' : '')}> <wjcOlap.PivotGrid initialized={sender => { this._grid = sender; }} // save reference to the grid itemsSource={this._ng} outlineMode={this.state.outlineMode} showRowFieldHeaders={this.state.showRowFieldHeaders}> </wjcOlap.PivotGrid> <button className="btn btn-primary" onClick={this._exportToCsv.bind(this)}> Export to CSV </button> </div> </div> </div>); } // // handle checkboxes _handleInputChange(e) { const id = e.target.id; const checked = e.target.checked; // this.setState({ [id]: checked }); // switch (id) { case 'totalsBeforeData': // update engine from state this._ng.totalsBeforeData = checked; break; case 'outlineMode': // changing outlineMode resets subtotal position, style if (checked) { this._ng.totalsBeforeData = checked; this.setState({ totalsBeforeData: checked }); } else { this.setState({ customStyle: checked }); } break; } } // // export grid to CSV _exportToCsv() { let grid = this._grid, rng = new CellRange(0, 0, grid.rows.length - 1, grid.columns.length - 1), csv = grid.getClipString(rng, true, true, true); // this._exportFile(csv, 'FlexGrid.csv'); } // _exportFile(csv, fileName) { let fileType = 'txt/csv;charset=utf-8'; // if (navigator.msSaveBlob) { // IE navigator.msSaveBlob(new Blob([csv], { type: fileType }), fileName); } else { let e = document.createElement('a'); e.setAttribute('href', 'data:' + fileType + ',' + encodeURIComponent(csv)); e.setAttribute('download', fileName); e.style.display = 'none'; document.body.appendChild(e); e.click(); document.body.removeChild(e); } } } // 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>Grapecity Wijmo OLAP Pivot Grid OutlineMode</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 { max-height: 400px; box-shadow: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23); } .outline .wj-pivotgrid .wj-cell { border-right: none; border-bottom: none; background: #fff; } body { margin-bottom: 24pt; } // get the raw data export function getData(count) { let countries = ['Germany', 'Italy', 'Japan', 'UK', 'US'], products = ['Widgets', 'Gadgets', 'Doohickeys'], colors = ['Red', 'Green', 'Blue', 'Yellow', 'Purple', 'White', 'Black', 'Magenta'], data = []; // for (let i = 0; i < count; i++) { let trend = (i % countries.length + 1) * (i % products.length + 1); data.push({ country: randomItem(countries), product: randomItem(products), color: randomItem(colors), active: i % 5 == 0, due: new Date(), sales: Math.random() * 10000 * trend, expenses: Math.random() * 5000 * trend, downloads: Math.random() * 100000 * trend }); } // return data; } // // get a random item from an array function randomItem(arr) { return arr[Math.floor(Math.random() * arr.length)]; }