Git Product home page Git Product logo

pourover's Introduction

PourOver is a library for simple, fast filtering and sorting of large collections -- think 100,000s of items -- in the browser. It allows you to build data-exploration apps and archives that run at 60fps, that don't have to to wait for a database call to render query results.

PourOver is built around the ideal of simple queries that can be arbitrarily composed with each other, without having to recalculate their results. You can union, intersect, and difference queries. PourOver will remember how your queries were constructed and can smartly update them when items are added or modified. You also get useful features like collections that buffer their information periodically, views that page and cache, fast sorting, and much, much more.

Visit the PourOver homepage on Github pages for more info.

Examples in the Wild

PourOver was created by the Interactive News group at the New York Times, and open-sourced in 2014. We actively use it in production across a number of projects, including:

  • Live Blogs
  • Red Carpet Project
  • plus a number of internal admin tools that allow newsroom staff to edit and sort large collections of items.

Maintenance and Upkeep

PourOver is in active, daily use in the newsroom. As we make bugfixes and enhancements in the course of our NYT work, we'll push them into this repo.

We welcome suggestions and feedback via issues or pull requests, but a stable build and consistent API for internal NYT use is our primary goal. We recognize that this may not accommodate all community uses or interests.

Contributor @hhsnopek has created a community fork here intended for a broader developer audience.

Dependencies

Underscore.js is the only dependency. Optionally, you may use Lo-dash instead of underscore.

Browser Support

PourOver should work in any browser that underscore works in. It has been tested in:

  • IE7+
  • Firefox 4+
  • Safari 5+
  • Opera 9+
  • Chrome 1+

pourover's People

Contributors

bkoski avatar dannguyen avatar davidgtonge avatar duner avatar esmooov avatar jdalton avatar lpradel avatar macdiva avatar nicksergeant avatar outofculture avatar ses4j avatar snatchev avatar tiffehr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pourover's Issues

Alter possible values for an existing exactFilter?

How do you change the allowed possibilities for an exact filter dynamically? I can updateItem() with a new value but then there's no way to let the filter know that the new discrete value exists.

Also, there doesn't seem to be a removeFilter or changeFilter method, which would be a natural mechanism for doing so.

Uncaught TypeError: undefined is not a function

Hello all,

I've got a TypeError on Chrome 38.0.2125.111 m (win8) on line 513 of pourover.js from nov. 4 : https://github.com/NYTimes/pourover/blob/master/pourover.js#L513

f.on("queryChange",function(){

Same on Firefox 33.0.2 (win8), "TypeError: f.on is not a function"

During debug I've found that the error appears when I do :

collection.addFilters([mythology_filter, gender_filter, hobbies_filter]);

During the Basic example...

Any ideas ?

Thanks :)

Distributed PourOver

I understand that everyone is busy with work and other problems that have a higher priority over PourOver. I recently sent an email to @esmooov and @bkoski asking to add myself as a maintainer of PourOver. Without any response over the past week I have gone ahead and forked PourOver and published it with the latest changes from #47. This fork will continue to grow and improve pourover. If anyone would like to help maintain PourOver I'd be glad to grant them access to the repo.

Sorting of caches

Can you describe how to write custom filter cache methods? Why do you need insert_sorted and union_sorted methods? I tested it on simple arrays, and they return very strange order of elements.

DB on top of PourOver

Hello everyone.
I posted a similar question in CrossFilter github issue's list and someone directed me here! So here's a copy of the question. I hope someone can clarify if it's possible to use PourOver for what I want to do.
I'm investigating how to create an in memory "relational/object" database in the browser. I wonder whether it's feasible and/or desirable to use PourOver as an indexing/querying engine for it.
Let's consider this scenario:
I have some json stored in localStorage (maximum 5 MB). I want to load it into memory and start querying (create get update delete...). The data model/schema is two entities (Student and Class) related by (takes/takenBy) a Many-to-Many relationship. [Student] --takes--> [Class].
Student:[ {id:0, name:adam, age:22},{id:1, name:Eva, age:29},{id:2, name:Abel, age:7}]
Class:[ {id:0, name:Math, Day:1},{id:1, name:Poetry, Day:1},{id:2, name:Math, Day:Tue}]
Takes:[
{StudentID:0 , ClassID:0 },
{StudentID:0 , ClassID:1 },
{StudentID:1 , ClassID:1 },
{StudentID:1 , ClassID:2 },
{StudentID:2 , ClassID:2 },
]
Let's say that I load each of the above (two entities + the relation) to its own 'PourOver collection'.
I also create a 'high-level' query engine on top of PourOver. This engine would use the three 'PourOver collections' to query the data and do some joins etc.
I want it to be able not only to query/get but also to create/add, update and delete.
When the user is done, the in memory data is stored back in the localStorage.

I would like to have PourOver users/creators' opinions before trying such thing. If there's something inherent to PourOver that would hinder such approach I'd prefer to know that in advance.

I had a quick look and it seems PourOver's singleton is not meant to handle more than a collection. I'm saying that because of the line (basic example):
PourOver.makeExactFilter("mythology", ["greek","norse"]);
To me it looks like it's using the PourOver "singleton" to create a filter for one collection. This would mean no two collection can have the same filter-name (i.e. field name).
etc...
Thank you much for your time.

Source for homepage?

I noticed a few typos (eg. afterward/afterword) on the homepage, but it doesn't seem to be part of this repo, so I couldn't fix it.

[question] Any thoughts of node?

I am currently working on a project that would benefit greatly from the magical goodness of pourover filtering. I could definitely get a lot of power out of using it in browser, but in my specific context it would make more sense using it on node.

Thusly, I'm here and curious. Any intentions of adding to npm?

Sort `attr` property has no effect.

From the Advanced View example, setting attr in a new sort will specify "what it sorts with respect to." But, as noted as an aside in #27, it doesn't seem to do anything.

Here's a jsFiddle setting attr to uqbar and the sort still working: http://jsfiddle.net/mhkeller/vLur82dq/

The relevant code:

var TitleSort = PourOver.Sort.extend({
    attr: 'uqbar',
    fn: function(a,b){
        if (b.title < a.title){
          return -1;
        } else if (b.title > a.title){
          return 1;
        } else {
          return 0;
        }
    }
});

Similarly, it seems that the way to set the attr by which to sort objects is by setting the name on a and b.

The Advanced View example, however, does not have anything set on a and b.

var RevNameSort = PourOver.Sort.extend({
    attr: "name",
    fn: function(a,b){
        if (b < a){
          return -1;
        } else if (b > a){
          return 1;
        } else {
          return 0;
        }
    }
});

Demo?

This looks great - is there anywhere to see a demo of this in action, preferably with a rather large dataset?

List of improvements

Any thoughts on these improvements?

  • Use node's package.json to handle deps and devDeps
  • Use mocha for testing
  • Add travis support for automated testing
  • Use npm scripts for building/testing (npm build & npm test)
  • Update inline documentation to jsdoc (still can use docco for generation, I believe)

These should be looked at prior to merging #47 as the PR contains changes that are unnecessary if any of these improvements are agreed upon.

I'll PR these based on the current master for your review.

Community collaboration suggestions from @hhsnopek

Improvements:

  • dist folder, separate from source
  • travis-ci for continous integration and testing
  • some parts of UMD/AMD/Global support & perhaps bower
  • tests refactored and faster using mocha (maybe)
  • update inline documentation to jsdoc (+docco; maybe, within other documentation improvements)
  • build process using gulp

Reversing a sort?

How do I reverse sort? I can define a second sort function, but that seems like a waste. Also, as a side note, what's the purpose of the 'attr' attribute of the sorter? I set it to something that does not exist, and that doesn't seem to matter.

Thanks.

Approaching the 100k items problem with PourOver

Hi @esmooov,

I've read the PourOver documentation and have played a bit with its examples. I'm not entirely sure I've grasped how one would approach the 100k items problem with PourOver or how up-to-date the documentation is so, i 'll try to write down what I've understood. It would be great if you could correct me where necessary. Off we go:


As I understand it, the main case for PourOver is the handling of an array of thousands of homogeneous items. By "handle", I mean that these items should be able to be sorted and filtered, based on a subset of their attributes. Also, this array is big in size, which prohibits the straight-forward client-side approach of downloading it all in the user's browser and managing it there.

So, with PourOver we first need to decide on which of the items' attributes are essential for filtering/sorting. Using this subset, we can create a new, compact array of items that will be downloaded on the user's browser. If this array is still big in size, we would use Tamper to compress it in the backend and uncompress it in the frontend.

Now, on the frontend side of things, this more compact array will be the collection that we will operate on. The rest of the information will be handled by a buffered collection, that will use as a dictionary the former collection. This buffered collection will get the necessary information for an item lazily, i.e. only when it needs to be explicitly rendered.


So, have I missed anything? Is there a faster alternative to the above?

Thanks,
Alex

Cant delete the items in the collection

I was going through the example as shown on the home page and it says that you can remove the item in the collection by using collection.removeItems(1) but its doesn't work but whenever I pass the cid explicitly like collection.removeItems({cid: 1}), it works fine. Am i missing something here? or it is a typo or is there any reason for it??? Thanks

chain sorting, via @ outofculture

Feature request, really. While it's easy enough to make a single sort fn that captures the logic of two or more semantically atomic sorts, having to do so for every possible combination of sorts seems silly.

Lodash v3.7.0 (latest) Breaks Pourover

From the how to:

**data**

var collection = new PourOver.Collection( monsters );

var mythology_filter = PourOver.makeExactFilter( "mythology", [ "greek", "norse" ] );
var gender_filter = PourOver.makeExactFilter( "sex", [ "m", "f" ] );
var hobbies_filter = PourOver.makeInclusionFilter( "hobbies", [ "riddles",
                                                              "sitting",
                                                              "being a wonder",
                                                              "coiling",
                                                              "terrorizing",
                                                              "growing",
                                                              "luring",
                                                              "staring",
                                                              "god-killing" ] );

collection.addFilters( [ mythology_filter, gender_filter, hobbies_filter ] );

var greek_monsters = collection.filters.mythology.getFn( "greek" );
var terror_monsters = collection.filters.hobbies.getFn( "terrorizing" );

var greek_terrors = greek_monsters.and( terror_monsters );

var my_monsters = collection.get( greek_terrors.cids );

Errors with:

Uncaught TypeError: Cannot read property 'getFn' of undefined

All works fine with Underscore.js. I tried both the modern and compatibility build of lodash.

Nested dictionaries inside collections

There is an example given at this https://nytimes.github.io/pourover/examples/examples_build/advanced_views.html, but i have my data in below format, and will this be work for displaying as well as filtering?

[{
  "resume_id": 1592570,
  "name": "Developer",
  "updation_on": "2015-08-05",
  "education": [
    {
      "id": 2678646,
      "title": "BS Computer Engineering",
      "institute": "University of Information Technology and Management Sciences",
      "city": null,
      "country": "ABC",
      "start_date": "2002-01-01",
      "end_date": "2006-03-01",
      "cgpa": 0.00
    }
  ],
  "experience": [
    {
      "id": 2376166,
      "desig": "Senior Executive Engineer",
      "company": " Telecom Pvt Limited",
      "start_on": "2013-12-01",
      "industry": null
    },
    {
      "id": 2376167,
      "desig": "Senior Executive Engineer",
      "company": "Telecom Pvt Limited",
      "start_on": "2013-12-01",
      "industry": null,
    }
  ]
}]

Implement removeItemAttribute.

PourOver.Collection has a updateItem but no removeItemAttribute so there's no way to clear an existing attribute once set.

PourOver View is broken

Hello, I have tried the example codes for Views and it doesn't work.

A View won't update its matchset when overriding the selectionFn(). You need to do naturalSelectionFn() manually or change the .matchset object.

Moreover, the example with change event to render a console.log also does not work as it is.

Lastly, removing items from a collection is also broken.

Build a filter meant for dates or other continuous ranges

Dates and ranges seem like a key feature for a library like this. dvrangeFilter seems to meet the interface requirements, but the documentation seems to warn off of using it because, obviously, there are many discrete date values. Is there a solution or thought to address this now or in the works?

Aggregation with pourover

Really more of a question. I have been evaluating crossfilter and this seems to do several similar things and in many ways it easier.

Does pourover have any capabilities to perform aggregation on the entire data set or any slices of that data? is this on the roadmap?

Thanks!

Create a library of custom filters

I'm sure that there were already many custom filters written by memebers of the community. If they are willing to share, it would be nice to have a directory, where people can upload their custom filters.

Basic Pourover example broken

It looks like the basic pourover example found at this url is broken with the latest underscore.js (1.7.0) and pourover.js.

Specifically, adding filters to a collection:

collection.addFilters([mythology_filter, gender_filter, hobbies_filter]);

returns: "Uncaught TypeError: undefined is not a function"

Update: I was able to reproduce the error in both chrome and firefox.

Techniques for full-text searching within PourOver?

Hi there! Love the library. It's almost like you were reading my mind. I run http://broker.is/ and you solved/are attempting to solve my two biggest pain points. I'll be using PourOver/Tamper exclusively for this project, so I'll focus on bringing functionality over here when appropriate :)

Anyways, my original question is this: do you have any ideas / suggestions for full-text filtering within a PourOver collection? PourOver is excellent for categorical filtering, sorting, and pagination, but I also have a full-text querying component to my collections. If I want to use the built-in pagination / sorting with PourOver, I'd need to devise a way to integrate full-text searching on specific fields in PourOver, instead of doing that after the collection has been filtered via PO.

My idea was to do this is as a manual filter. Does that sound like an appropriate approach, or do you have any ideas on how else to handle this type of a situation?

Suggestion: Simple API doc

A simple API document—a list of all methods—would be helpful. The existing docs and examples are well written and helpful, but to get a comprehensive view of the API I am looking through the source code, which is time consuming.

Browser compatibility?

Which browsers (and versions) are known to work with this library? Which ones work when you add particular polyfills?

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.