Commits

Anonymous committed f60d117

in process of canvasmanager integration, code currently IN BUGGY STATE.

Comments (0)

Files changed (13)

examples/area.html

   <link rel="stylesheet" type="text/css" href="examples.css" />
   
   <!-- BEGIN: load jquery -->
-  <script language="javascript" type="text/javascript" src="../src/jquery-1.5.1.min.js"></script>
+  <script language="javascript" type="text/javascript" src="../src/jquery-1.5.1.js"></script>
   <!-- END: load jquery -->
   
   <!-- BEGIN: load jqplot -->

src/jqplot.canvasGridRenderer.js

     };
     
     // called with context of Grid.
-    $.jqplot.CanvasGridRenderer.prototype.createElement = function() {
+    $.jqplot.CanvasGridRenderer.prototype.createElement = function(plot) {
         // Memory Leaks patch
         if (this._elem) {
           if ($.jqplot.use_excanvas) {
             elem = this._elem.get(0);
             window.G_vmlCanvasManager.uninitElement(elem);
-            elem = null;
+            elem = null;    
           }
           
           this._elem.emptyForce();
           this._elem = null;
         }
       
-        var elem = document.createElement('canvas');
+        //var elem = document.createElement('canvas');
+        var elem = plot.canvasManager.getCanvas();
         var w = this._plotDimensions.width;
         var h = this._plotDimensions.height;
         elem.width = w;

src/jqplot.core.js

         }
     };
 
+
+    // canvas manager to reuse canvases on the plot.
+    // Should help solve problem of canvases not being freed and
+    // problem of waiting forever for firefox to decide to free memory.
+    $.jqplot.CanvasManager = function() {
+        this.canvases = [];
+        this.free = [];
+
+        this.getCanvas = function() {
+            var canvas;
+            var idx = $.inArray(true, this.free);
+    
+            if (idx > -1) {
+                canvas = this.canvases[idx];
+                this.free[idx] = false;
+                $(canvas).addClass('reused');
+            }   
+
+            else {
+                canvas = document.createElement('canvas');
+                this.canvases.push(canvas);
+                this.free.push(false);
+                idx = this.canvases.length;
+            }   
+            
+            return canvas;
+        };
+
+        this.freeAllCanvases = function() {
+            for (var i = 0; i < this.canvases.length; i++) {
+                var canvas = this.canvases[i];
+                canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
+                $(canvas).removeClass().removeAttr('style');
+                this.free[i] = true;
+            }   
+        };
+
+        this.destroyAllCanvases = function() {
+            
+        };
+
+        this.freeCanvas = function(idx) {
+            var canvas = this.canvases[idx];
+            canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
+            $(canvas).removeClass().removeAttr('style');
+            this.free[idx] = true;
+        };
+
+        this.destroyCanvas = function(idx) {
+            
+        };
+    };
+
             
     // Convienence function that won't hang IE of FF without FireBug.
     $.jqplot.log = function() {
         this.renderer.init.call(this, this.rendererOptions);
     };
     
-    Grid.prototype.createElement = function(offsets) {
+    Grid.prototype.createElement = function(offsets, plot) {
         this._offsets = offsets;
-        return this.renderer.createElement.call(this);
+        return this.renderer.createElement.call(this, plot);
     };
     
     Grid.prototype.draw = function() {
     $.jqplot.GenericCanvas.prototype = new $.jqplot.ElemContainer();
     $.jqplot.GenericCanvas.prototype.constructor = $.jqplot.GenericCanvas;
     
-    $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions) {
+    $.jqplot.GenericCanvas.prototype.createElement = function(offsets, clss, plotDimensions, plot) {
+        if (!plot) {
+            throw('No Plot Specified for Generic Canvas Create Element');
+        }
+
         this._offsets = offsets;
         var klass = 'jqplot';
         if (clss != undefined) {
             }
         }
         else {
-            elem = document.createElement('canvas');
+            //elem = document.createElement('canvas');
+            elem = plot.canvasManager.getCanvas();
         }
         // if new plotDimensions supplied, use them.
-        if (plotDimensions != undefined) {
+        if (plotDimensions != null) {
             this._plotDimensions = plotDimensions;
         }
         
         //this._elem.remove();
         this._elem.emptyForce();
       }
-      
-      this._ctx = null;
+      // not compatible with canvas manager?  maybe even before?
+      //this._ctx = null;
     };
     
     $.jqplot.HooksManager = function () {
         this.eventListenerHooks = new $.jqplot.EventListenerManager();
         this.preDrawSeriesShadowHooks = new $.jqplot.HooksManager();
         this.postDrawSeriesShadowHooks = new $.jqplot.HooksManager();
-        
+
         this.colorGenerator = $.jqplot.ColorGenerator;
+
+        this.canvasManager = new $.jqplot.CanvasManager();
         
         // Group: methods
         //
             this.target.trigger('jqplotPreReplot');
             
             if (clear) {
+                this.canvasManager.freeAllCanvases();
                 // Memory Leaks patch
                 this.target.find("table.jqplot-table-legend,table.jqplot-legend").each( function() {
                     $(this).unbind();
                     this.preDrawHooks.hooks[i].call(this);
                 }
                 // create an underlying canvas to be used for special features.
-                this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas'));
+                this.target.append(this.baseCanvas.createElement({left:0, right:0, top:0, bottom:0}, 'jqplot-base-canvas', null, this));
                 this.baseCanvas.setContext();
                 this.target.append(this.title.draw());
                 this.title.pack({top:0, left:0});
                 }
                 // ax.y2axis.pack({position:'absolute', top:0, right:0}, {min:this._height - this._gridPadding.bottom, max: this._gridPadding.top});
             
-                this.target.append(this.grid.createElement(this._gridPadding));
+                this.target.append(this.grid.createElement(this._gridPadding, this));
                 this.grid.draw();
                 
                 // put the shadow canvases behind the series canvases so shadows don't overlap on stacked bars.
                     // draw series in order of stacking.  This affects only
                     // order in which canvases are added to dom.
                     j = this.seriesStack[i];
-                    this.target.append(this.series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas'));
+                    this.target.append(this.series[j].shadowCanvas.createElement(this._gridPadding, 'jqplot-series-shadowCanvas', null, this));
                     this.series[j].shadowCanvas.setContext();
                     this.series[j].shadowCanvas._elem.data('seriesIndex', j);
                 }
                     // draw series in order of stacking.  This affects only
                     // order in which canvases are added to dom.
                     j = this.seriesStack[i];
-                    this.target.append(this.series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas'));
+                    this.target.append(this.series[j].canvas.createElement(this._gridPadding, 'jqplot-series-canvas', null, this));
                     this.series[j].canvas.setContext();
                     this.series[j].canvas._elem.data('seriesIndex', j);
                 }
                 // Need to use filled canvas to capture events in IE.
                 // Also, canvas seems to block selection of other elements in document on FF.
-                this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas'));
+                this.target.append(this.eventCanvas.createElement(this._gridPadding, 'jqplot-event-canvas', null, this));
                 this.eventCanvas.setContext();
                 this.eventCanvas._ctx.fillStyle = 'rgba(0,0,0,0)';
                 this.eventCanvas._ctx.fillRect(0,0,this.eventCanvas._ctx.canvas.width, this.eventCanvas._ctx.canvas.height);

src/jqplot.lineRenderer.js

         this.plugins.lineRenderer.highlightedSeriesIndex = null;
         this.plugins.lineRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
         
-        this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(this.plugins.lineRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-lineRenderer-highlight-canvas', null, this));
         this.plugins.lineRenderer.highlightCanvas.setContext();
     } 
     

src/plugins/jqplot.barRenderer.js

         this.plugins.barRenderer = {highlightedSeriesIndex:null};
         this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
         
-        this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions, this));
         this.plugins.barRenderer.highlightCanvas.setContext();
     }   
     

src/plugins/jqplot.bubbleRenderer.js

         var height = this._plotDimensions.height - this._gridPadding.top - this._gridPadding.bottom;
         this.plugins.bubbleRenderer.highlightLabelCanvas.css({top:top, left:left, width:width+'px', height:height+'px'});
 
-        this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-bubbleRenderer-highlight-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-bubbleRenderer-highlight-canvas', this._plotDimensions, this));
         this.eventCanvas._elem.before(this.plugins.bubbleRenderer.highlightLabelCanvas);
         
         var hctx = this.plugins.bubbleRenderer.highlightCanvas.setContext();

src/plugins/jqplot.canvasOverlay.js

     $.jqplot.CanvasOverlay.postPlotDraw = function() {
         this.plugins.canvasOverlay.canvas = new $.jqplot.GenericCanvas();
         
-        this.eventCanvas._elem.before(this.plugins.canvasOverlay.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(this.plugins.canvasOverlay.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this));
         this.plugins.canvasOverlay.canvas.setContext();
 		if (!this.plugins.canvasOverlay.deferDraw) {
 			this.plugins.canvasOverlay.draw(this);

src/plugins/jqplot.cursor.js

         
         // if (c.zoom) {
         c.zoomCanvas = new $.jqplot.GenericCanvas();
-        this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(c.zoomCanvas.createElement(this._gridPadding, 'jqplot-zoom-canvas', this._plotDimensions, this));
         c.zoomCanvas.setContext();
         // }
         c._tooltipElem = $('<div class="jqplot-cursor-tooltip" style="position:absolute;display:none"></div>');
         c.zoomCanvas._elem.before(c._tooltipElem);
         if (c.showVerticalLine || c.showHorizontalLine) {
             c.cursorCanvas = new $.jqplot.GenericCanvas();
-            this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions));
+            this.eventCanvas._elem.before(c.cursorCanvas.createElement(this._gridPadding, 'jqplot-cursor-canvas', this._plotDimensions, this));
             c.cursorCanvas.setContext();
         }
 

src/plugins/jqplot.donutRenderer.js

         // Fix for broken jquery :first selector with canvas (VML) elements.
         var labels = $(this.targetId+' .jqplot-data-label');
         if (labels.length) {
-            $(labels[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions));
+            $(labels[0]).before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions, this));
         }
         // else put highlight canvas before event canvas.
         else {
-            this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions));
+            this.eventCanvas._elem.before(this.plugins.donutRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-donutRenderer-highlight-canvas', this._plotDimensions, this));
         }
         var hctx = this.plugins.donutRenderer.highlightCanvas.setContext();
     }

src/plugins/jqplot.dragable.js

         this.plugins.dragable = {previousCursor:'auto', isOver:false};
         this.plugins.dragable.dragCanvas = new DragCanvas();
         
-        this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(this.plugins.dragable.dragCanvas.createElement(this._gridPadding, 'jqplot-dragable-canvas', this._plotDimensions, this));
         var dctx = this.plugins.dragable.dragCanvas.setContext();
     };
     

src/plugins/jqplot.funnelRenderer.js

         // do we have any data labels?  if so, put highlight canvas before those
         var labels = $(this.targetId+' .jqplot-data-label');
         if (labels.length) {
-            $(labels[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions));
+            $(labels[0]).before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions, this));
         }
         // else put highlight canvas before event canvas.
         else {
-            this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions));
+            this.eventCanvas._elem.before(this.plugins.funnelRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-funnelRenderer-highlight-canvas', this._plotDimensions, this));
         }
         var hctx = this.plugins.funnelRenderer.highlightCanvas.setContext();
     }

src/plugins/jqplot.highlighter.js

     // create a canvas which we can draw on.
     // insert it before the eventCanvas, so eventCanvas will still capture events.
     $.jqplot.Highlighter.postPlotDraw = function() {
-        // Memory Leaks patch    
-        if (this.plugins.highlighter &&
-        this.plugins.highlighter.highlightCanvas) {
-            this.plugins.highlighter.highlightCanvas.resetCanvas();
-            this.plugins.highlighter.highlightCanvas = null;
-        }
+        // Memory Leaks patch    
+        if (this.plugins.highlighter &&
+        this.plugins.highlighter.highlightCanvas) {
+            this.plugins.highlighter.highlightCanvas.resetCanvas();
+            this.plugins.highlighter.highlightCanvas = null;
+        }
 
         this.plugins.highlighter.highlightCanvas = new $.jqplot.GenericCanvas();
         
-        this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions));
+        this.eventCanvas._elem.before(this.plugins.highlighter.highlightCanvas.createElement(this._gridPadding, 'jqplot-highlight-canvas', this._plotDimensions, this));
         this.plugins.highlighter.highlightCanvas.setContext();
         
         var p = this.plugins.highlighter;

src/plugins/jqplot.pieRenderer.js

     // create a canvas which we can draw on.
     // insert it before the eventCanvas, so eventCanvas will still capture events.
     function postPlotDraw() {
-        // Memory Leaks patch    
-        if (this.plugins.pieRenderer &&
-        this.plugins.pieRenderer.highlightCanvas) {
-            this.plugins.pieRenderer.highlightCanvas.resetCanvas();
-            this.plugins.pieRenderer.highlightCanvas = null;
-        }
+        // Memory Leaks patch    
+        if (this.plugins.pieRenderer &&
+        this.plugins.pieRenderer.highlightCanvas) {
+            this.plugins.pieRenderer.highlightCanvas.resetCanvas();
+            this.plugins.pieRenderer.highlightCanvas = null;
+        }
 
         this.plugins.pieRenderer = {highlightedSeriesIndex:null};
         this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
         // do we have any data labels?  if so, put highlight canvas before those
         var labels = $(this.targetId+' .jqplot-data-label');
         if (labels.length) {
-            $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions));
+            $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
         }
         // else put highlight canvas before event canvas.
         else {
-            this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions));
+            this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
         }
         
         var hctx = this.plugins.pieRenderer.highlightCanvas.setContext();
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.