views:

581

answers:

2

Hi,

I'm currently developing a calendar with all standard views (day, week, month).

To load my calendar events I use JSON. When the events are loaded I have to map them on the active view (day, week or month).

For each view I only need a particular set of events, the events between the date range of the current view (=timeframe).

So, is it possible to filter the events (on date) for each view without looping through the whole JSON object?

Now I'm doing this:

$(eventCache.Events).each(function() { 
    //CHECK IF THIS EVENT SHOULD BE DISPLAYED
});

But the list of events can get up to a couple of hundred so this method is slowing down the performance of the calendar...

This is an example of my data:

{
   "d":{
      "__type":"GetEventsCacheResult",
      "Events":[
         {
            "Subject":"Subject",
            "CalendarId":"139c9edd-b01b-47cf-bae9-18f3e3dca655",
            "ColorCode":"#093647",
            "Id":"0dab7ad9-46c7-e230-294e-0933e78eadae",
            "Description":null,
            "DTStartDate":" \/Date(1244596500000)\/",
            "DTEndDate":"\/Date(1244610000000)\/",
            "StartDate":"10/06/2009 1:15:00",
            "EndDate":"10/06/2009 5:00:00",
            "AppointmentType":0,
            "AllDay":false
         },
         {
            "Subject":"Subject",
            "CalendarId":"139c9edd-b01b-47cf-bae9-18f3e3dca655",
            "ColorCode":"#093647",
            "Id":"0fddb3a0-65f1-08c7-daf2-13da605b499b",
            "Description":null,
            "DTStartDate":" \/Date(1245823200000)\/",
            "DTEndDate":"\/Date(1245832200000)\/",
            "StartDate":"24/06/2009 6:00:00",
            "EndDate":"24/06/2009 8:30:00",
            "AppointmentType":0,
            "AllDay":false
         },
         {
            "Subject":"Subject",
            "CalendarId":"139c9edd-b01b-47cf-bae9-18f3e3dca655",
            "ColorCode":"#093647",
            "Id":"a95b8a2b-7c8a-677f-dc58-1c9836d72748",
            "Description":null,
            "DTStartDate":" \/Date(1247633100000)\/",
            "DTEndDate":"\/Date(1247646600000)\/",
            "StartDate":"15/07/2009 4:45:00",
            "EndDate":"15/07/2009 8:30:00",
            "AppointmentType":0,
            "AllDay":false
         }
      ],
      "Dates":{
         "StartDate":"\/Date(1238022000000 )\/",
         "EndDate":"\/Date(1285106400000)\/"
      }
   }
}
+1  A: 

Loop through it once and build an associative array, or hash of the data grouped as you want to filter it.

It won't necessarily be perfect, but one suggestion is group them by months, and then when someone asks for dates between June 15th and August 12th, you can immediately add July, and sift just through dates after June and August.

Then again, this may be no more effective than simply sort them first, doing a binary search for your first entry and then for the last entry, depending on how many times you expect the filter to be changed.

altCognito
I agree, this is how I'd do it, probably both sorting and also hashing events by month.
Josh
+1  A: 

If you're displaying one month at a time (max), then I would recommend only loading/parsing/caching one months worth of JSON data at a time.

If this is not an option or if you're already doing it this way, you may want to re-index your data or restrict the date range to somthing feasible.

The best solution depends greatly on how your users are going to typically use it.

Josh Stodola
For now I'm using a timeframe of two months and it works but if I want to skip a couple of weeks ahead (fast clicking) it's a little bit slow. If you look at the google calendar, they use a date range of two years(!) and when you skip weeks it's blazing fast...
Bundy
Well, if your data is sorted, it will matter very little how much data you have. Doing two binary searches to find the spot you want in your data should be log(n) time, which is pretty fast.
altCognito