Giter VIP home page Giter VIP logo

ngcrossfilter's Introduction

ngCrossfilter

 

Heroku: http://ng-crossfilter.herokuapp.com/

Introduction

Angular uses native JavaScript methods for sorting, whereas ngCrossfilter uses Crossfilter for a significant improvement in performance.

Getting Started

Firstly you need to initialise Crossfilter with your collection of items.

$scope.$ngc = new Crossfilter(response.data, 'id', 'persistent', ['name', 'age']);

ngCrossfilter's constructor accepts four parameters – with only the first being mandatory. With the second parameter you can change the primary key – which will otherwise default to the first property in the first model; the third parameter allows you to change the filtering strategy – either persistent or transient, whereas the fourth parameter allows you to specify which properties to create dimensions with.

Once you've configured your Crossfilter collection, you can begin filtering and sorting. From within your view you should reference your collection – in our case, $ngc.

<button ng-click="$ngc.filterBy('word', word)">Filter</button>

After you've applied all of your filters, you simply need to iterate over the array using the ng-repeat directive.

<li ng-repeat="model in $ngc.collection() | limitTo: 100">

Filtering

Filter by word:

$ngc.filterBy('word', word)

Third argument allows the specifying of a custom filtering function – see custom functions.

Unfilter by word:

$ngc.unfilterBy('word')

Unfilter all:

$ngc.unfilterAll()

Strategies

By default the filtering strategy is `persistent` which means that all filters are persistent until they are re-applied, or removed. If you'd like to change to the `transient` behaviour where the previous filter is cleared, you can pass `transient` into `ngCrossfilter`'s constructor as the third argument.

Custom Filtering

By specifying a custom function on the third argument of the `filterBy` method you can implement your own sorting logic.
$scope.fuzzyFilter = function fuzzyFilter(expected, actual) {
    var regExp = new RegExp(expected);
    return actual.match(regExp, 'i');
}

Which can then be utilised by passing it as the third argument in your view.

<button ng-click="$ngc.filterBy('word', word, fuzzyFilter)">

Sorting

Sort by word:

$ngc.sortBy('word')

Second argument allows you to choose whether the sorting is by ascending – by not applying a value, the ascending will be inverted each time the same property is sorted on.

Unsort all:

$ngc.unsortAll()

First argument prevents the reverting of the sort order to ascending.

Counting

With filters it's useful to compute the length of any given property and value pair – with ngCrossfilter we can do this with the countBy method.

$ngc.countBy('word', 'Adam')

However, there is one proviso and that is the countBy method may not behave as you expect it to as it disregards the dimension you're counting on – see Crossfilter's Map-Reduce documentation.

In a nutshell, if you're filtering on the name property, and you're also counting by the name property, the name filter will be disregarded – instead you need to count on a dimension that you're not using in the filtering process – unless the default behaviour is useful – and in most cases it actually makes sense – see the Word Count filter in the example. You can implement this by adding a custom dimension with addDimension, or by counting on the primary key – assuming it's not being used in the filtering process.

Update Subscription

Sometimes it is preferable to subscribe to the update of the Crossfilter, and to apply any modifications of your data at that point rather than relying on Angular's dirty-checking.

In these cases you can listen to the crossfilter/updated event, which passes along the collection and the identifier of the Crossfilter.

$scope.$on('crossfilter/updated', function(event, collection, identifier) {

    // Voila!

});

The identifier is empty by default, but can be set at any point.

$ngc.identifyAs('myCrossfilter');

It is possible to disable and re-enable the broadcasting of the crossfilter/updated event. For example, the following would broadcast a single event.

$ngc.disableBroadcastEvent();
$ngc.sortBy('population');
$ngc.unfilterBy('city');

$ngc.enableBroadcastEvent();
$ngc.filterBy('climate', [5, 10]);

If you need full control over when the event is triggered, you may disable the event as described above and broadcast it yourself.

$ngc.broadcastEvent(true);

Bundled Filters

As there are common filtering techniques that Crossfilter doesn't implement, ngCrossfilter comes with a fine selection of bundled filters for common tasks.

Fuzzy Filter

With the fuzzy filter you can filter with incomplete expressions.

$ngc.filterBy('city', 'M', $ngc.filters.fuzzy());

You will notice that the fuzzy method is invoking the method immediately – this allows you to pass valid regular expression flags for insensitivity, et cetera...

$ngc.filterBy('city', 'M', $ngc.filters.fuzzy('i'));

By default no flags will be defined for the regular expression matching.

Regular Expression Filter

With the regular expression filtering you can specify an expression to filter on.

$ngc.filterBy('city', /o$/, $ngc.filters.regexp());

You can pass either an expression or an actual RegExp object to the filter.

InArray Filter

With the inArray filter you can check an array against an array – using the some and every array methods – please check the browser support before using it – although ngCrossfilter will fallback to Underscore.js if it's installed.

$ngc.filterBy('twinCities', ['Beijing', 'Tokyo'], $ngc.filters.inArray());

By default the inArray filter uses the every method, which means in the above example only entries where twinCities has both Beijing and Tokyo will be returned – you can use some instead by passing it into inArray filter method.

$ngc.filterBy('twinCities', ['Beijing', 'Tokyo'], $ngc.filters.inArray('some'));

To invert the inArray filter, use the notInArray filter with the same parameters.

DateTime Filter

Allows you to select a date/time range irrespective of the format of the time and/or date – Moment.js is a requirement to use this filter.

$ngc.filterBy('added', ['2012-01-01', '2012-12-01'],
                       $ngc.filters.dateTimeRange('YYYY-MM-DD'));

The first parameter of the dateTimeRange filter allows you to specify the exact format – see Moment.js documentation – the default being YYYY-MM-DD. With the second parameter you can pass a comparator function for custom range filtering.

$ngc.filterBy('added', ['2012-01-01', '2012-12-01'],
                       $ngc.filters.dateTimeRange('YYYY-MM-DD'),
                       function(current, start, end) {
                           return (current > start);
                       });

dateTimeRange also accepts -Infinity/Infinity ranges for where lows and highs are not applicable.

$ngc.filterBy('added', [-Infinity, '2012-12-01'],
                       $ngc.filters.dateTimeRange('YYYY-MM-DD'));

Bitwise Filter

Simple filter using the bitwise & operator against the collection.

$ngc.filterBy('climate', 2, $ngc.filters.bitwise());

You can invert the filtering by passing an exclamation mark as the first argument to the bitwise method.

$ngc.filterBy('climate', 2, $ngc.filters.bitwise('!'));

Update Model

With Crossfilter updating a model requires removing it from the collection and then re-adding it. If you use this with one of your own primary keys then the PK will be added to the delete list, and therefore re-adding a model with the same PK will still be deleted. Therefore to make Crossfilter work with new models, you need to update the PK first – you can do this yourself, or you can use the convenient updateModel that ngCrossfilter provides – but you will be delegating the PK to ngCrossfilter.

In order to use updateModel you must define your primary key as $id.

var $ngc = new Crossfilter(collection, '$id');
// ...
$ngc.updateModel(personModel, { name: 'Adam' });

With the $id PK in place, the updateModel will do all of the manual labour for you! You needn't worry about updating the PK yourself.

Other Methods

For the entire list of features for ngCrossfilter it is advised to refer to the unit tests – as these have full coverage of all ngCrossfilter methods and their usages.

Accessors

  • first: First model in the collection;
  • last: Last model in the collection;
  • models: Retrieve a slice of the collection;
  • crossfilter: Retrieve an instance of crossfilter;

Dimensions

  • addDimension: Add a custom dimension;
  • deleteDimension: Delete a dimension;

Convenience

  • countBy: Count values – see counting;
  • groupBy: Group by any given dimension;

Manipulation

  • addModel: Add a model to the collection;
  • addModels: Add models to the collection;
  • deleteModel: Delete a model from the collection;
  • deleteModels: Delete models from the collection;
  • restoreModel: Restore a model from the garbage;
  • restoreModels: Restore models from the garbage;
  • updateModel: Update a model – see [update model](#update-model);

Contributions

As with all of my projects, you're more than welcome to contribute. Please include a unit test for your additions, and if the Travis build passes then it will be merged into master.

ngcrossfilter's People

Contributors

wildhoney avatar javiercejudo avatar jlmart88 avatar nickbenes avatar

Stargazers

Kais Rekouche avatar neolitec avatar Bogdan Dinu avatar Kirell Benzi avatar Alexandr Kalinin avatar  avatar  avatar Steven Prybylynskyi avatar Matt Kirchstein avatar Chris Lonardo avatar JavaProgrammer avatar Brandon Weaver avatar Alberto Labarga avatar Jayson Harshbarger avatar ackuser avatar  avatar opavader avatar  avatar cfpperche avatar Adam Hurst avatar Colin Brooks avatar Berker Yüce avatar Aaron Chartier avatar Giacomo Bartoloni avatar Craig MacKay avatar Izon Thomaz Mielke avatar Udi Oron avatar Michael Anthony avatar Bermon Painter avatar Zdzislaw avatar Mateus Lopes avatar Matthew McLeod avatar Manikanta Gade avatar Marcell Kiss avatar  avatar  avatar Joseph Joy Manadan avatar  avatar Plasmaboyer avatar Jarrod Payne avatar Victor Teixeira avatar Joey Gracey avatar Satya van Heummen avatar TC Devs avatar Michael Polino avatar Philippe Koenig avatar Milan Jelicanin avatar Bill Eger avatar Víctor avatar  avatar Omer Katz avatar  avatar Shaun Grady avatar Sönke Ohls avatar Jussi avatar  avatar Max Brokman avatar Spencer Carstens avatar Dan Gornstein avatar Tom Sutton avatar Aleksandar Vidakovic avatar John S. Dvorak avatar Alex K avatar Ramin Mohammadi avatar tom zhou avatar Samuel Richardson avatar Athan avatar PatrickJS avatar  avatar Krist Wongsuphasawat avatar JP Wesselink avatar Charles Beebe avatar Mike Slattery avatar colin b. erdman avatar  avatar Kaleb Scholes avatar Alex Sherwin avatar Steven Marcus avatar Łukasz Rżanek avatar Kai avatar timelyportfolio avatar Adam Hallett avatar Brandon Titus avatar Lucas avatar Mark Daggett avatar Noah Pryor avatar Marcin Stefaniuk avatar

Watchers

Zdzislaw avatar James Cloos avatar Roman Lishtaba avatar  avatar Michael Anthony avatar  avatar Max Brokman avatar  avatar Jos avatar Kais Rekouche avatar  avatar

ngcrossfilter's Issues

crossfilter is not available from dc.js

Hello,

I use ngCrossfilter with dc.js. It looks like dc can not render charts (called by a dc.renderall() ) because 'crossfilter' is not available :

angular.js:13920 TypeError: Cannot read property 'quicksort' of undefined
    at Object._chart._computeOrderedGroups (base-mixin.js:335)
    at Object.<anonymous> (cap-mixin.js:51)
    at Object._chart.data (base-mixin.js:261)
    at drawChart (row-chart.js:136)
    at Object._chart._doRender (row-chart.js:89)
    at Object._chart.render (base-mixin.js:645)
    at Object.dc.renderAll (core.js:230)
    at pages.controller.js:85
    at processQueue (angular.js:16383)
    at angular.js:16399

The base-mixin.js:335 is :
_orderSort = crossfilter.quicksort.by(_ordering);

And crossfilter is not available, because it is defined only into the new Crossfilter() object...

Is there a solution to have the crossfilter object available into dc.js ? Or did I misunderstood anything ?

Thanks.

Bower issue

your package could not be found and installed via bower
check it out please.

Support AngularJS ver 1.3 and above

Currently the bower.json specify the angular dependency as "angular": "~1.2.1"
This should be updated to "angular": "~1.x.x" to support any all legit angularjs versions.

Advantage over using crossfilter directly?

Hi, I like the idea, but I m not getting the clear benefits of using ngCrossfilter over crossfilter directly in the controller, like I use Lodash. Can you please clarify? Thanks.

Identifying which crossfilter triggered an update

I was listening for updates in a crossfilter using the crossfilter/updated event, but I couldn't find a clean way to identify from which crossfilter the event originated when there's more than one.

Maybe I'm missing something, but I guess a backwards-compatible approach would be to optionally set a name/id for a crossfilter and pass that name along with the broadcasted event. It could look something like this:

$scope.ngc = new Crossfilter(response.data, 'id', 'persistent');
$scope.ngc.setCrossfilterName('myCrossfilter1');

$scope.$on('crossfilter/updated', function(event, collection, crossfilterName) {
  if ('myCrossfilter1' === crossfilterName) {
    // ...
  }
};

Thoughts? I'm happy to submit a PR if you think it's worth it!

Update Model

Hi,

First thanks a lot for this awesome angular module. I use it to create sortable and filterable grids.

I have an issue when trying to update a model. I assumed the way to do that was to remove the model and then add the new updated model.
I do something like
$scope.$ngc.deleteModel(model);
$scope.$ngc.addModel(updatedModel);

The model gets deleted correctly but it doesn't get added then. It seems I can't add a model which have been deleted before. Could you help with that ?

Many thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.