Question

How do I find the minimum value per day? The dimension being the Days, the group the minimum amount. Using the following data as an example -

var data = [
  {date: "2011-11-14T10:17:54Z", amount: 10 },
  {date: "2011-11-14T12:20:19Z", amount: 1 },
  {date: "2011-11-14T14:20:19Z", amount: 0 },
  {date: "2011-11-15T06:30:43Z", amount: 10 },
  {date: "2011-11-15T10:30:43Z", amount: 10 },
  {date: "2011-11-15T16:28:54Z", amount: 100 },
  {date: "2011-11-16T18:48:46Z", amount: 100 },
  {date: "2011-11-16T20:53:41Z", amount: 11 },
  {date: "2011-11-16T22:54:06Z", amount: 10 },
];

So the results should be -

  {date: "2011-11-14T14:20:19Z", amount: 0 },
  {date: "2011-11-15T06:30:43Z", amount: 10 },
  {date: "2011-11-15T10:30:43Z", amount: 10 },
  {date: "2011-11-16T22:54:06Z", amount: 10 },

I'm going round in circles trying to work this out and I'm now completely confused so any help would be appreciated!

Thanks.

Was it helpful?

Solution

The following will get your your absolute minimum. Won't work with filtering though!

var data = [
  {date: "2011-11-14T10:17:54Z", amount: 10 },
  {date: "2011-11-14T12:20:19Z", amount: 1 },
  {date: "2011-11-14T14:20:19Z", amount: 0 },
  {date: "2011-11-15T06:30:43Z", amount: 10 },
  {date: "2011-11-15T10:30:43Z", amount: 10 },
  {date: "2011-11-15T16:28:54Z", amount: 100 },
  {date: "2011-11-16T18:48:46Z", amount: 100 },
  {date: "2011-11-16T20:53:41Z", amount: 11 },
  {date: "2011-11-16T22:54:06Z", amount: 10 },
];

var ndx = crossfilter(data);
var dayDim = ndx.dimension(function (d) { return "" + d.date.substr(8,2); });
var minGroup = dayDim.group().reduce(
  function (p, v) { if(v.amount < p || p === null) p = v.amount; return p; },
  function (p, v) { return p; },
  function () { return null; }
);

console.table(minGroup.top(Infinity));

If you want filtering to work, you need to keep a sorted array of all the values found in each array and then add/remove values as data is filtered and unfiltered. Then use this sorted array to figure out your minimum. Something like the following (untested):

var data = [
  {date: "2011-11-14T10:17:54Z", amount: 10 },
  {date: "2011-11-14T12:20:19Z", amount: 1 },
  {date: "2011-11-14T14:20:19Z", amount: 0 },
  {date: "2011-11-15T06:30:43Z", amount: 10 },
  {date: "2011-11-15T10:30:43Z", amount: 10 },
  {date: "2011-11-15T16:28:54Z", amount: 100 },
  {date: "2011-11-16T18:48:46Z", amount: 100 },
  {date: "2011-11-16T20:53:41Z", amount: 11 },
  {date: "2011-11-16T22:54:06Z", amount: 10 },
];

var ndx = crossfilter(data);
var dayDim = ndx.dimension(function (d) { return "" + d.date.substr(8,2); });
var minGroup = dayDim.group().reduce(
  function (p, v) { 
    if(v.amount < p.min || p.min === null) {
      p.min = v.amount;
    }
    p.values.push(v.amount);
    return p;
  },
  function (p, v) {
    p.values.splice(p.values.indexOf(v.amount),1);
    if(v.amount === p.min) {
      p.values.sort(function(a,b) { return a < b ? -1 : 1; });
      p.min = p.values[0];
    } 
    return p;
  },
  function () { return { min: null, values: [] }; }
);

console.log(minGroup.top(Infinity));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top