Request new features or modifications


Post by dhettinger »

Sorry to keep sending you guys these (and for the long post) but i found some code that is very slow when zooming in with a large schedule. We modified our zoom so it would keep the time range loaded, this means that when we are zooming in very far we end up with a large number of time headers. This is causing some code to spend a large amount of time in it that normally wouldn't be much of an issue.

The section i am talking about is getTickFromDate (around line 8128)

code before:
getTickFromDate : function(date) {
		
		if (this.getStart() > date || this.getEnd() < date) {
			return -1;
		} 

		var ticks = this.getRange(),
			tickStart, tickEnd, i, l;

		for (i = 0, l = ticks.length; i < l; i++) {
			tickEnd = ticks[i].data.end;
			if (date <= tickEnd) {
				tickStart = ticks[i].data.start;
					
				return i + (date > tickStart ? (date - tickStart)/(tickEnd - tickStart) : 0);
			} 
		}
		
		return -1;
	},
This ends up looping through a collection of about 6000 for each object on our schedule, as you can imagine when you have a couple hundred objects this really slows things down.

After (i commented out actual returns to test to make sure i was calculating the exact same index as the for loop was getting)
getTickFromDate : function(date) {
    	var viewStart = this.getStart();
	    var viewEnd = this.getEnd();
    	if (viewStart > date || viewEnd < date) {
            return -1;
        }
	    
    	//speed hack, narrow ticks range by checking where we are in gantt
    	var percentageIn = (viewEnd - date) / (viewEnd - viewStart);

        var ticks = this.getRange(),
            tickStart, tickEnd, i, l;
	    
    	//now get the closest tick to this percentage.
        var closestTick = ticks.length * percentageIn;
        var tick = ticks.length - Math.ceil(closestTick);
	    

	    if (tick >= ticks.length) {
				tick = ticks.length - 1;
		}
	    //tickStart = ticks[tick].data.start;
	    //return tick + ((date - tickStart) / (ticks[tick].data.end - tickStart));

        for (i = 0, l = ticks.length; i < l; i++) {
            tickEnd = ticks[i].data.end;
            if (date <= tickEnd) {
            	tickStart = ticks[i].data.start;

				if (tick != i) {
					var doesntWork = "nope";
				}
                    
				var returnVar = i + (date > tickStart ? (date - tickStart) / (tickEnd - tickStart) : 0);
				return returnVar;
			} 
        }
        
        return -1;
    },
I haven't hit a break point inside that check yet, so everything looks to be working ok from my tests.

Final Code:
getTickFromDate : function(date) {
    	var viewStart = this.getStart(),
			viewEnd = this.getEnd();
    	if (viewStart > date || viewEnd < date) {
            return -1;
        }
	    
    	//calculate tick from date
    	var percentageIn = (viewEnd - date) / (viewEnd - viewStart),
			ticks = this.getRange(),
            tickStart;
	    
    	//now get the closest tick to this percentage.
        var closestTick = ticks.length * percentageIn;
        var tick = ticks.length - Math.ceil(closestTick);
	    
	   if (tick >= ticks.length) {
				tick = ticks.length - 1;
		}
	    tickStart = ticks[tick].data.start;
	    return tick + ((date - tickStart) / (ticks[tick].data.end - tickStart));
    },
for a large schedule the performance increase from this is extremely noticeable. I would rather keep our source code the same as yours for easy upgrading reasons, if you could take a look over this and let me know what you think that would be greatly appreciated!

Post by nickolay »

Thanks for the report, we'll investigate! https://www.assembla.com/spaces/bryntum ... ity/ticket:

Post Reply