Skip to content

Instantly share code, notes, and snippets.

@gabrielmontagne
Last active September 14, 2016 09:06
Show Gist options
  • Save gabrielmontagne/6f8535213979fab398176c3e4815c8cd to your computer and use it in GitHub Desktop.
Save gabrielmontagne/6f8535213979fab398176c3e4815c8cd to your computer and use it in GitHub Desktop.
Zambezi Grid -- server side filter and sort
license: mit

Zambezi Grid Server side filter and sorting

When a data set is too large, it might not make sense to send it all at once to the client. You might want to populate a grid little by little, requesting data as needed.

The Zambezi Grid supports sparse datasets it can run in server side filter and sort mode by turning it on with serverSideFilterAndSort getter/setter. When this is turned on, no attempt to filter or sorting will be done by the grid. You can use the grid events to request the relevant data from the server.

Events

You can use the following grid events to request additional data rows from the server. Once you get the new rows, you can merge or replace them and redraw the grid.

  • sort-changed will pass your handler the column related to the header's sort gesture
  • visible-lines-change will pass your handler information about the currently visible rows in the grid.

Example

In this example we fake remote calls to fetch additional paginated data. An empty array of length 50K is passed to the grid; the length determines how much you can scroll.

If you scroll slowly (perhaps by using the mouse wheel over the scroller) you'll see the rows being added to the grid as they "arrive". If you open the console in the developer tools you'll see the sort events dispatched, which can be used to request the appropriate sorted data slice.

<!doctype html>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="https://npmcdn.com/[email protected]">
<div class="grid-target"></div>
<script src="https://npmcdn.com/[email protected]"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://npmcdn.com/[email protected]/faker.js"></script>
<script src="https://npmcdn.com/@zambezi/[email protected]"></script>
<script src="https://npmcdn.com/@zambezi/[email protected]"></script>
<script src="https://npmcdn.com/@zambezi/[email protected]"></script>
<script>
var table = grid.createGrid()
.columns(
[
{ key: 'i', label: 'index', locked: 'left', width: 50 }
, { key: 'name' }
, { key: 'email', sortDescending: true }
, { key: 'phone' }
, { key: 'username' }
, {
label: 'address'
, children: [
{ label: 'city', key: 'address.city' }
, { label: 'country', key: 'address.ukCountry' }
, { label: 'county', key: 'address.ukCounty' }
]
}
]
)
.serverSideFilterAndSort(true)
.on(
'visible-lines-change.fetch-data'
, _.throttle(fakeFetchRemoteData, 100, { leading: false }) // throttling is up to the client
)
.on(
'sort-changed'
, (column) => console.info('sort changed, ', column)
)
, rows = Array(50000) // create long empty array
, target = d3.select('.grid-target')
.style('height', '500px')
.datum(rows)
draw()
function draw() {
target.call(table)
}
function fakeFetchRemoteData(min, max) {
setTimeout(patchAndRedraw, 100) // some added latency, just for fun
function patchAndRedraw() {
console.groupCollapsed(`new data ${min} - ${max}`)
d3.range(Math.max(0, min - 2), Math.min(max + 2, rows.length)).forEach(patchRow)
draw()
console.groupEnd(`new data ${min} - ${max}`)
}
function patchRow(i) {
if (rows[i]) return
console.debug('patchRow', i)
rows[i] = Object.assign({i}, faker.Helpers.createCard())
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment