Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using crossfilter to dynamically return results in JavaScript

I feel that the crossfilter library API explanation is written for someone above my skillset, but I also know that mastering it will solve my problem.

To make it simple, I will reference the API Page's example data for this question.

var payments = crossfilter([
  {date: "2011-11-14T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
  {date: "2011-11-14T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
]);

I am able to return records that match a specific key (quantity, total, etc.), but I do not understand how to return results that match a combination of key/value pairs. For instance, how would I return the result set that matched results with a quantity more than 1, a total equal 90, a tip equal 0 and a type of tab? This is where I'm completely lost.

like image 400
S16 Avatar asked May 15 '12 20:05

S16


2 Answers

You could create a dimension for each attribute and then call each dimension's filter method with the corresponding filter criteria you indicated, like so.

var payments_by_quantity = payments.dimension(function(d){return d.quantity}),
    payments_by_total = payments.dimension(function(d){return d.total}),
    payments_by_tip = payments.dimension(function(d){return d.tip}),
    payments_by_type = payments.dimension(function(d){return d.type});

payments_by_quantity.filter([1, Infinity]);
payments_by_total.filter(90);
payments_by_tip.filter(0);
payments_by_type.filter("tab");

payments_by_type.top(Infinity)

The effects are cumulative, so that last line there is actually the result of all values respecting all filters from all dimensions.

like image 84
slo jo Avatar answered Sep 30 '22 10:09

slo jo


I found the above answer precise but inaccurate for me as a beginner i.e. I got no or unexpected results (no disrespect slo-jo, but I'm writing from a beginner perspective as I'm a crossfilter nube). The gotchas are the need to clear filters before calling some filters (you'll need to expand the data set with more variety e.g. different tips, totals etc. to see what I mean). Outputting to the console helps me.

Here's what helps my understanding:

    var data = [
  {date: "2011-11-14T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:30:43Z", quantity: 222, total: 990, tip: 0, type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:53:41Z", quantity: 5, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 990, tip: 0, type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
  {date: "2011-11-14T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
];



<script type="text/javascript">

// questions: For instance, how would I return the result set that matched results with a quantity more than 1, a total equal 90, a tip equal 0 and a type of tab? 
// create dimensions for each attribute
var payments_by_quantity = payments.dimension(function(d){return d.quantity});
     payments_by_total = payments.dimension(function(d){return d.total}),
     payments_by_tip = payments.dimension(function(d){return d.tip}),
     payments_by_type = payments.dimension(function(d){return d.type});

//need top(Infinity) to print out contents of filtered items
var morethan1 = payments_by_quantity.filter([1, Infinity]).top(Infinity);
console.log("morethan1",morethan1);

var tot_eq_90 = payments_by_total.filter(90).top(Infinity);
console.log("tot_eq_90",tot_eq_90);

// clear filters. If not, the result below will still be filtered by totals = 90
payments_by_total.filterAll();

console.log("top1= biggest paymt qty:", payments_by_quantity.top(1));
payments_by_total.filterAll();
console.log("top2= biggest paymt qty:", payments_by_quantity.top(2));
payments_by_total.filterAll();

console.log("bottom paymt tip:", payments_by_tip.bottom(1));

var tip_eq_0 = payments_by_tip.filter(0).top(Infinity);
console.log("tip_eq_0",tip_eq_0);
payments_by_total.filterAll();

var typetab = payments_by_type.filter("tab").top(Infinity);
console.log("typetab",typetab);
payments_by_total.filterAll();

var typetab_i = payments_by_type.top(Infinity);
console.log("typetab+i",typetab_i);
like image 36
snowman55 Avatar answered Sep 30 '22 09:09

snowman55