An indexed record Datasaur module.
The datasaur-indexed
data source provides a means to map the original set of rows, resulting in a subset of particular rows in a particular order.
datasaur-indexed
sits on top of a static datasource. For example:
var Source = require('datasaur-local'); // v3.0.0 or higher
var Indexer = require('datasaur-indexed'); // this version must be >= that of datasaur-local
var dataModel = new Indexer(new Source);
datasaur-indexed
defines a custom index
instance property, a version
static property, and some helper methods described in the next section.
The index
property when defined is an integer array that maps the y
value (row index provided to other method calls) to specific rows in the original set of rows.
This property is all that is needed to effectively "index" (reorder, filter, and/or alias) the data.
Given the following set of rows (shown here in JSON syntax):
[
{ "name": "Sam", "gender": "M" },
{ "name": "Al", "gender": "F" },
{ "name": "Max", "gender": "M" },
{ "name": "Jo", "gender": "F" }
]
To filter the data:
dataModel.index = [0, 2] // rows where second column is 'M'
To order the data:
dataModel.index = [1, 3, 2, 0] // alpha ascending by first column
To alias all rows:
dataModel.index = [0, 0, 1, 1, 2, 2, 3, 3]
To remove the index and revert to the original set of rows:
dataModel.index = undefined
While the above approach works, it is wholly inadequate, however, as a generalized solution for filtering and sorting.
See buildIndex
and Generalized sorting below for better solutions.
The version string from package.json. (This is a static property of the constructor.)
datasaur-indexed
defines four custom methods.
Using the dataModel.setIndex([...])
method, rather than assigning directly to dataModel.index
, will dispatch the pre- and post-index data events back to the applicaiton (see Event strings below).
dataModel.buildIndex
and dataModel.sort
both call dataModel.setIndex
.
Calling without an argument is the same as calling dataModel.clearIndex
.
Undefines the index
(by calling setIndex(undefined)
).
Builds a new index and calls dataModel.setIndex
on it:
dataModel.buildIndex(predicate);
where predicate
returns truthy for desired rows, for example:
function predicate(y) {
return this.getValue(1, y) === 'M'; // rows where second column is 'M'
}
Calling without a predicate is the same as calling dataModel.clearIndex()
.
Note that the above example predicate would fail on a computed cell or column.
To properly handle such data, you can use DatasaurIndexed.valOrFunc
instead of calling this.getValue
:
function predicate(y) {
return DatasaurIndexed.valOrFunc(this.getRow(y), 'gender', this.schema.gender.calculator) === 'M'; // rows where second column is 'M'
}
The event string definitions have the following defaults:
DatasaurIndexed.preindexEventString = 'fin-hypergrid-data-prereindex';
DatasaurIndexed.postindexEventString = 'fin-hypergrid-data-postreindex';
For generalized single-column sorting, use datasaur-simple-sort
, which sits on top of datasaur-indexed
:
var Sorter = require('datasaur-simple-sort');
var dataModel = new Sorter(new Indexer(new Source));
dataModel.sort(0); // alpha ascending by first column
As noted in datasaur-simple-sort
's README, it fails on computed cells and columns.
Sorting by multiple columns, each of which may be ascending or descending, is somewhat more complicated,
essentially involving dynamically adding a Sorter
stage for each column to be sorted.
See datasaur-filter
which does something like that,
but forces Array.prototype.sort
to do a stable sort
(which is is not naturally inclined to do), and properly handles computed cells and columns.
Note: As of this writing datasaur-filter
has not yet been updated to v3.0.0.
Published as an npm module to npmjs.org to be npm installed:
npm install datasaur-indexed
Published as a Hypergrid Client Module to be loaded by the client with a <script>
tag:
<script src="https://fin-hypergrid.github.io/datasaur-indexed/3.0.0/build/datasaur-indexed.js"></script>
The above <script>
tag loads the module into fin.Hypergrid.modules['datasaur-indexed']
.
Once loaded it can be referenced from another Hypergrid client module with require(...)
:
var DatasaurIndexed = require('datasaur-indexed');
Or from some other script with fin.Hypergrid.require(...)
:
var DatasaurIndexed = fin.Hypergrid.require('datasaur-indexed');