<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>SlickGrid example: Optimizing DataView</title> <link rel="stylesheet" href="../slick.grid.css" type="text/css"/> <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css"/> <link rel="stylesheet" href="../controls/slick.pager.css" type="text/css"/> <link rel="stylesheet" href="examples.css" type="text/css"/> <style> .cell-title { font-weight: bold; } .cell-effort-driven { text-align: center; } .cell-selection { border-right-color: silver; border-right-style: solid; background: #f5f5f5; color: gray; text-align: right; font-size: 10px; } </style> </head> <body> <div style="position:relative"> <div style="width:600px;"> <div class="grid-header" style="width:100%"> <label>SlickGrid</label> </div> <div id="myGrid" style="width:100%;height:500px;"></div> <div id="pager" style="width:100%;height:20px;"></div> </div> <div class="options-panel"> <b>Search:</b> <hr/> <div style="padding:6px;"> <label style="width:200px;float:left">Show tasks with % at least: </label> <div style="padding:2px;"> <div style="width:100px;display:inline-block;" id="pcSlider"></div> </div> </div> <br/> <p> This page demonstrates various techniques for optimizing DataView performance for large client-side datasets. This page displays an interactive grid with 500'000 rows with real-time filtering.<br/> This is achieved by: <ul> <li>Inlining filter function to cut down on the cost of function calls.</li> <li>Providing hints to indicate whether a filtering operation will result in narrowing or expanding scope or whether the scope is unchanged. </li> <li>Providing a range of rows for which onRowsChanged even should be fired.</li> </ul> </p> <h2>View Source:</h2> <ul> <li><A href="https://github.com/mleibman/SlickGrid/blob/gh-pages/examples/example-optimizing-dataview.html" target="_sourcewindow"> View the source for this example on Github</a></li> </ul> </div> </div> <script src="../lib/jquery-1.7.min.js"></script> <script src="../lib/jquery-ui-1.8.16.custom.min.js"></script> <script src="../lib/jquery.event.drag-2.2.js"></script> <script src="../slick.core.js"></script> <script src="../slick.formatters.js"></script> <script src="../slick.grid.js"></script> <script src="../slick.dataview.js"></script> <script src="../controls/slick.pager.js"></script> <script> var dataView; var grid; var data = []; var columns = [ {id: "sel", name: "#", field: "num", behavior: "select", cssClass: "cell-selection", width: 40, resizable: false, selectable: false }, {id: "title", name: "Title", field: "title", width: 120, minWidth: 120, cssClass: "cell-title"}, {id: "duration", name: "Duration", field: "duration"}, {id: "%", name: "% Complete", field: "percentComplete", width: 80, resizable: false, formatter: Slick.Formatters.PercentCompleteBar}, {id: "start", name: "Start", field: "start", minWidth: 60}, {id: "finish", name: "Finish", field: "finish", minWidth: 60}, {id: "effort-driven", name: "Effort Driven", width: 80, minWidth: 20, maxWidth: 80, cssClass: "cell-effort-driven", field: "effortDriven", formatter: Slick.Formatters.Checkmark} ]; var options = { editable: false, enableAddRow: false, enableCellNavigation: true }; var percentCompleteThreshold = 0; var prevPercentCompleteThreshold = 0; var h_runfilters = null; function myFilter(item, args) { return item["percentComplete"] >= args; } function DataItem(i) { this.num = i; this.id = "id_" + i; this.percentComplete = Math.round(Math.random() * 100); this.effortDriven = (i % 5 == 0); this.start = "01/01/2009"; this.finish = "01/05/2009"; this.title = "Task " + i; this.duration = "5 days"; } $(function () { // prepare the data for (var i = 0; i < 500000; i++) { data[i] = new DataItem(i); } dataView = new Slick.Data.DataView({ inlineFilters: true }); grid = new Slick.Grid("#myGrid", dataView, columns, options); var pager = new Slick.Controls.Pager(dataView, grid, $("#pager")); // wire up model events to drive the grid dataView.onRowCountChanged.subscribe(function (e, args) { grid.updateRowCount(); grid.render(); }); dataView.onRowsChanged.subscribe(function (e, args) { grid.invalidateRows(args.rows); grid.render(); }); // wire up the slider to apply the filter to the model $("#pcSlider").slider({ "range": "min", "slide": function (event, ui) { if (percentCompleteThreshold != ui.value) { window.clearTimeout(h_runfilters); h_runfilters = window.setTimeout(filterAndUpdate, 10); percentCompleteThreshold = ui.value; } } }); function filterAndUpdate() { var isNarrowing = percentCompleteThreshold > prevPercentCompleteThreshold; var isExpanding = percentCompleteThreshold < prevPercentCompleteThreshold; var renderedRange = grid.getRenderedRange(); dataView.setFilterArgs(percentCompleteThreshold); dataView.setRefreshHints({ ignoreDiffsBefore: renderedRange.top, ignoreDiffsAfter: renderedRange.bottom + 1, isFilterNarrowing: isNarrowing, isFilterExpanding: isExpanding }); dataView.refresh(); prevPercentCompleteThreshold = percentCompleteThreshold; } // initialize the model after all the events have been hooked up dataView.beginUpdate(); dataView.setItems(data); dataView.setFilter(myFilter); dataView.setFilterArgs(0); dataView.endUpdate(); }) </script> </body> </html>