Virtualization

The sample below uses the viewRange property to implement a simple type of 'infinite scrolling'. When the user scrolls to the bottom of the grid, the code adds items to the grid's itemsSource. If you inspect the DOM, you will notice that no matter how large the itemsSource gets, the number of DOM elements remains constant. The data is 'virtualized'.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjGrid from '@grapecity/wijmo.grid'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // // start with a small data set var data = getData(100); // // initialize the grid var rowCount = document.getElementById('rowCount'); var cellCount = document.getElementById('cellCount'); var theGrid = new wjGrid.FlexGrid('#theGrid', { itemsSource: data, updatedView: function (s, e) { rowCount.textContent = s.rows.length; cellCount.textContent = s.hostElement.querySelectorAll('.wj-cell').length; }, scrollPositionChanged: function (s, e) { // // if we're close to the bottom, add 20 items if (s.viewRange.bottomRow >= s.rows.length - 1) { addData(data, 20); s.collectionView.refresh(); } } }); // // add random data to an array function addData(data, cnt) { var more = getData(cnt, data.length); for (var i = 0; i < more.length; i++) { data.push(more[i]); } } } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexGrid Scroll Virtualization</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 id="theGrid"></div> <p> The grid now has <span id='rowCount'></span> rows and <span id='cellCount'></span> cell elements.</p> </div> </body> </html> // get an array with random data export function getData(cnt, start) { var data = []; var countries = 'USA,Germany,UK,Japan,Italy,Greece'.split(','); if (!start) start = 0; for (var i = 0; i < cnt; i++) { data.push({ id: i + start, country: countries[i % countries.length], date: new Date(2014, i % 12, i % 28), amount: Math.random() * 10000, active: i % 4 === 0 }); } return data; } .wj-flexgrid { height: 250px; } #rowCount, #cellCount { font-weight: bold; } body { margin-bottom: 24pt; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import { Component, enableProdMode, NgModule, Inject } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import * as wjcGrid from '@grapecity/wijmo.grid'; import { WjGridModule } from '@grapecity/wijmo.angular2.grid'; import { WjInputModule } from '@grapecity/wijmo.angular2.input'; import { DataService } from './app.data'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { data: any[]; dataSvc: DataService; rowCount: number; cellCount: number; constructor(@Inject(DataService) dataSvc: DataService) { this.data = dataSvc.getData(100); this.dataSvc = dataSvc; } initializeGrid(flex: wjcGrid.FlexGrid) { this.rowCount = flex.rows.length; this.cellCount = flex.hostElement.querySelectorAll('.wj-cell').length; flex.updatedView.addHandler((s: wjcGrid.FlexGrid) => { this.rowCount = s.rows.length; this.cellCount = s.hostElement.querySelectorAll('.wj-cell').length; }); flex.scrollPositionChanged.addHandler((s: wjcGrid.FlexGrid) => { // if we're close to the bottom, add 20 items if (s.viewRange.bottomRow >= s.rows.length - 1) { this._addData(this.data, 20); s.collectionView.refresh(); } }); } // add random data to an array private _addData(data: any[], cnt: number) { let more = this.dataSvc.getData(cnt, data.length); for (let i = 0; i < more.length; i++) { data.push(more[i]) } } } @NgModule({ imports: [WjGridModule, WjInputModule, BrowserModule], providers: [DataService], declarations: [AppComponent], 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 FlexGrid Scroll Virtualization</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"> <wj-flex-grid #flex (initialized)="initializeGrid(flex)" [(itemsSource)]="data"> </wj-flex-grid> <p> The grid now has <span id='rowCount'>{{rowCount}}</span> rows and <span id='cellCount'>{{cellCount}}</span> cell elements.</p> </div> import { Injectable } from '@angular/core'; @Injectable() export class DataService { // get an array with random data getData(cnt: number, start?: number): any[] { let data = []; let countries = 'USA,Germany,UK,Japan,Italy,Greece'.split(','); if (!start) start = 0; for (let i = 0; i < cnt; i++) { data.push({ id: i + start, country: countries[i % countries.length], date: new Date(2014, i % 12, i % 28), amount: Math.random() * 10000, active: i % 4 === 0 }); } return data; } } .wj-flexgrid { height: 250px; } #rowCount, #cellCount { font-weight: bold; } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <wj-flex-grid :initialized="initializeGrid" :itemsSource="data"> </wj-flex-grid> <p> The grid now has <span id='rowCount'>{{rowCount}}</span> rows and <span id='cellCount'>{{cellCount}}</span> cell elements. </p> </div> </template> <script> import "@grapecity/wijmo.styles/wijmo.css"; import "bootstrap.css"; import Vue from "vue"; import * as wjcGrid from '@grapecity/wijmo.grid'; import '@grapecity/wijmo.vue2.grid'; import '@grapecity/wijmo.vue2.input'; import { getData } from './data'; new Vue({ el: "#app", data: { data: getData(100), rowCount: 0, cellCount: 0 }, methods:{ initializeGrid(flex){ this.rowCount = flex.rows.length; this.cellCount = flex.hostElement.querySelectorAll('.wj-cell').length; flex.updatedView.addHandler((s) => { this.rowCount = s.rows.length; this.cellCount = s.hostElement.querySelectorAll('.wj-cell').length; }); flex.scrollPositionChanged.addHandler((s) => { // if we're close to the bottom, add 20 items if (s.viewRange.bottomRow >= s.rows.length - 1) { this._addData(this.data, 20); s.collectionView.refresh(); } }); }, _addData(data, cnt) { let more = getData(cnt, data.length); for (let i = 0; i < more.length; i++) { data.push(more[i]) } } } }); </script> <style> .wj-flexgrid { height: 250px; } #rowCount, #cellCount { font-weight: bold; } 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 FlexGrid Scroll Virtualization</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, start) { let data = []; let countries = 'USA,Germany,UK,Japan,Italy,Greece'.split(','); if (!start) start = 0; for (let i = 0; i < cnt; i++) { data.push({ id: i + start, country: countries[i % countries.length], date: new Date(2014, i % 12, i % 28), amount: Math.random() * 10000, active: i % 4 === 0 }); } return data; } import "@grapecity/wijmo.styles/wijmo.css"; import "bootstrap.css"; import "./app.css"; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as wjcGrid from "@grapecity/wijmo.react.grid"; class App extends React.Component { constructor(props) { super(props); this.state = { data: this._getData(100), rowCount: 0, cellCount: 0 }; } render() { return <div className="container-fluid"> <wjcGrid.FlexGrid initialized={this.initializeGrid.bind(this)} itemsSource={this.state.data}> </wjcGrid.FlexGrid> <p> The grid now has <span id='rowCount'>{this.state.rowCount}</span> rows and {' '}<span id='cellCount'>{this.state.cellCount}</span> cell elements. </p> </div>; } _getData(cnt, start) { let data = []; let countries = 'USA,Germany,UK,Japan,Italy,Greece'.split(','); if (!start) start = 0; for (let i = 0; i < cnt; i++) { data.push({ id: i + start, country: countries[i % countries.length], date: new Date(2014, i % 12, i % 28), amount: Math.random() * 10000, active: i % 4 === 0 }); } return data; } initializeGrid(flex) { this.setState({ rowCount: flex.rows.length }); this.setState({ cellCount: flex.hostElement.querySelectorAll('.wj-cell').length }); flex.updatedView.addHandler((s) => { this.setState({ rowCount: s.rows.length }); this.setState({ cellCount: s.hostElement.querySelectorAll('.wj-cell').length }); }); flex.scrollPositionChanged.addHandler((s) => { // if we're close to the bottom, add 20 items if (s.viewRange.bottomRow >= s.rows.length - 1) { this._addData(this.state.data, 20); s.collectionView.refresh(); } }); } _addData(data, cnt) { let more = this._getData(cnt, data.length); for (let i = 0; i < more.length; i++) { data.push(more[i]); } } } 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 Chart Overview</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-flexgrid { height: 250px; } #rowCount, #cellCount { font-weight: bold; } body { margin-bottom: 24pt; }