GithubHelp home page GithubHelp logo

wildhoney / embercrossfilter Goto Github PK

View Code? Open in Web Editor NEW
47.0 5.0 8.0 29.89 MB

Instead of using Ember DataStore, EmberCrossfilter provides a basic architecture for creating Ember models with Crossfilter; which allows for much quicker sorting and filtering.

PHP 0.87% JavaScript 89.84% CSS 9.29%

embercrossfilter's Introduction

Ember Crossfilter

 

Install via npm: npm install ember-crossfilter

Both Ember DS and native JavaScript filtering methods are slow in comparison to Crossfilter. However, Crossfilter is not the easiest to get started with, and people starting out with Crossfilter find themselves in a pickle. That's why I've created a facade for working with Crossfilter with Ember. If you wish to go with your own implementation, then EmberCrossfilter also serves as a nice reference, and an example of a good implementation.

Out of the box, EmberCrossfilter provides:

  • Create simple filters, such as ranges, custom callbacks, exact matches;
  • Create more complicated boolean filters, such as OR/AND (filterAnd/filterOr);
  • Ability to determine which filters are active;
  • Find the highest/lowest values quickly (top/bottom);
  • Naturally sort an array using the sort object, and modify using the sortContent method;
  • Ability to extend EmberCrossfilter by accessing the _crossfilter property;

Methods

EmberCrossfilter provides a simple interface with a minimal footprint.

It exposes the following public methods:

  • isActiveFilter(key, value) – whether a filter is currently active, with an optional value parameter for specificity.
  • addFilter(key, value) – add a new filter to filter against;
  • addRecord(record) – adds an individual record to the collection;
  • addRecords(records) – adds many records;
  • deleteRecord(record) – deletes a record by the primaryKey;
  • deleteRecords(records) – deletes many records;
  • removeFilter(key, value) – remove a filter that's already been applied using addFilter;
  • clearAllFilters – clears all of the applied filters;
  • sortContent(property, isAscending) – filters the content based on a property from the model;
  • top(property, count) – a helper method for finding the highest value of property;
  • bottom(property, count) – same as above, but the lowest value;

Timing

If you'd like to see the timing outputs in your console, simply set allowDebugging to true in your controller that implements the EmberCrossfilter mixin, and you'll see how long various operations took in milliseconds.

Sorting

To set the default sorting direction for when EmberCrossfilter is initialised, you can supply a sort object in your controller.

The following will sort descending by the name property:

sort: { sortProperty: 'name', isAscending: false }

If you'd like to trigger sorting updates from your controllers/views, then you can invoke the sortContent method with the property, and the direction (ascending/descending), and EmberCrossfilter will update the sort object for you to reflect the changes.

The following will change the sorting to sort ascending by the age property:

sortContent('age', true);

Updates

EmberCrossfilter doesn't provide any mechanism for determining if the content has been updated. If you'd like to know when an update has occurred, then you can observer the content.length property on your controller.

Extras: Crossfilter's Missing Child

When using Crossfilter, it became apparent that comparing two arrays was naturally slow in Crossfilter, such as when you had [1, 2, 3] and you wanted only models with those values set. EmberCrossfilter rectifies that issue by offering a bitwise solution (filterAnd/filterOr) which does all the hard-work for you. It can be configured to use OR/AND.

AND (filterAnd)

If you've set ['Italy', 'Russia'] then a model must have BOTH of these values to be considered valid.

  • Valid: ['Italy', 'Russia', 'Spain']
  • Invalid: ['Italy', 'Brazil', 'India']

OR (filterOr)

In this case if you've set ['Italy', 'Russia'], then a model can have either or both of these to be considered valid.

  • Valid: ['Italy', 'Haiti']
  • Invalid: ['Portugal', 'Latvia']

embercrossfilter's People

Contributors

wildhoney avatar neverfox avatar

Stargazers

Haitham Maya avatar Angus H. avatar Lionel Viet avatar Andreas Haller avatar Stephan Herzog avatar Andrew Schreiber avatar Jakob Bjerre Petersen avatar Deniss Alimovs avatar  avatar Rick Song avatar Sjoerd de Jong avatar Trevor Cowley avatar Glavin Wiechert avatar Haris Pobric avatar  avatar Mika Cohen avatar  avatar  avatar timelyportfolio avatar Michael Bortnick avatar Mohammad Bagher Ehtemam avatar Chris Knox avatar gaurav patel avatar Scott Ames-Messinger avatar Ant Ramm avatar meddle avatar  avatar Diogo Edegar Mafra avatar Taras Mankovski avatar Michael Grassotti avatar Nelson Yee avatar  avatar Jeremy Franz avatar Babak Niknia avatar Arthur Gunn avatar Tom Carter avatar  avatar Bogdan Brisc avatar Jon Buffington avatar Billy Catherall avatar Ryan Rauh avatar Matt Madden avatar Darshan Sawardekar avatar Gabor Babicz avatar Jon Kirkman avatar Elliot Anderson avatar Saleh Souzanchi avatar

Watchers

Alexander Brandon Coles avatar Hoetmaaiers avatar James Cloos avatar  avatar  avatar

embercrossfilter's Issues

Bower?

Not that I can't link directly to the repo, but this doesn't appear to be registered with Bower, despite the bower.json file.

Ember 1.13

Hello thank you for sharing this.

I'm trying to make this work with Ember 1.12. Discovering crossFilter at the same type so this is step by step.

Not too difficult to create a own mixin in Ember-CLI replicating yours, and import crossfilter.js through bower.

Then Ember.ArrayController has been deprecated, so I just set the 'content' property to my array and changed a few bits and bobs to make it work with the 'content' array (some properties were defined on this as it was an arrayController, we need this.get('content') instead). Doesn't seem to work with promiseArray objects so I set up an observer to convert the promiseArray to a normal array. It refreshes when the store fetches new models, though I will have to check the performance of this later:

  //crossFilterArray is an alias for 'content'
  crossFilterArray:null,
  hasInitializedCrossFilterArray: false,
  _setCrossFilterArray: function(){
    if (!this.get('hasInitializedCrossFilterArray')) {
      this.set('hasInitializedCrossFilterArray',true);
      this.set("crossFilterArray",this.get("model").toArray());
    }
    else {
      var arr0=this.get("crossFilterArray");
      var arr1=this.get("model").toArray();
      var add=arr1.filter(function(x){return arr0.indexOf(x)===-1;});
      var rem=arr0.filter(function(x){return arr1.indexOf(x)===-1;});
      //TODO: update _createFilterBoolean on add/deleteRecords
      this.addRecords(add);
      this.deleteRecords(rem);
    }
  },
  _launchSetCrossFilterArray: function(){
    if (!this.get("model")) {return false;}
    Ember.run.scheduleOnce('destroy',this,'_setCrossFilterArray');
  }.observes('model.@each').on('init'),

The filters seem to work alright though using the debugging feature it seems to take 100/200 ms to filter regularly, which is strange given I only have some dozens of rows for now (maybe my dev browser is getting busy).

I have a question right now, I'm sure it can work but if someone had an Idea it could save me hours:

I used to be able to filter on hasMany relationships of my models: each model has many tags, and I want to filter on all the models which have those tags. Problem here is that I can not create a dimension in cross-filter as it must be a naturally-ordered value (i can not send an array of tags in _applyTags, I could send the number of tags for sorting, but for filtering it is not enough information). So there seems to be something missing, maybe the ability to define several properties for each row (one for each hasMany relationship), but in _createFilterBoolean there is only one property fetched per model..

sort on multiple dimensions?

I have set up a sortProperty but I want to set up a fallbackSortProperty to sort on if there are duplicates of the original property. Any suggestions on where to start?

FYI for people that want to use Ember-data

I wanted to use this with ember-data records so I changed way the property value is retrieved in the function

 _createDimensions: function _createDimensions() { ....


        Object.defineProperty(this, name, {
            enumerable      : false,
            configurable    : false,
            writable        : false,
            value           : this._crossfilter.dimension(function(d) {
                 // OLD: Define the property using the JS 1.8.5 way. 
                  // return d[property]
                 //NEW: Change to include d.get(property) the way ember-data does it.
                return Ember.isNone( d[property] ) ? d.get(property) : d[property];
            })
        });

....
}

also need to change it in the _sortedContent

 _sortedContent: function _sortedContent(content, property, isAscending) {

    // Initialise the sorting using Crossfilter's `quicksort`.
    //OLD: var sortAlgorithm   = crossfilter.quicksort.by(function(d) { return d[property]; });
    var sortAlgorithm   = crossfilter.quicksort.by(function(d) { return Ember.isNone( d[property] ) ? d.get(property) : d[property];});

    // Sort the content using Crossfilter.
    var sorted = sortAlgorithm(content, 0, content.length);

    if (!isAscending) {
        // If we want it in descending order, then we need to reverse the array.
        sorted = sorted.reverse();
    }

    return sorted;

}

Reference for working with records. http://emberjs.com/guides/models/working-with-records/

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.