Changeset 10

Show
Ignore:
Timestamp:
17/03/06 04:43:04 (2 years ago)
Author:
al
Message:

fixed major bug with Canvas on IE support, now should work transparently for user in both the case where CANVAS is dynamically generated or already existing on the page. If it exists on the page, we need to remove it and regenerate it so it is in the correct name space that IE understands.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plotkit/trunk/PlotKit/Base.js

    r8 r10  
    231231    "axisLabelColor": Color.grayColor(), 
    232232    "axisLineColor": Color.whiteColor(), 
    233     "padding": {top: 5, bottom: 20, left: 40, right: 10}, 
    234     "shouldStroke": true 
     233    "padding": {top: 5, bottom: 30, left: 10, right: 10} 
    235234};     
    236235 
  • plotkit/trunk/PlotKit/Canvas.js

    r8 r10  
    101101        "IECanvasHTC": "PlotKit/iecanvas.htc" 
    102102    }; 
    103  
    104103    MochiKit.Base.update(this.options, options ? options : {}); 
     104 
     105    // we need to refetch the element because of this horrible Canvas on IE 
     106    // crap 
     107    this.element_id = element.id ? element.id : element; 
     108 
     109    // Stuff relating to Canvas on IE support 
     110    var self = PlotKit.CanvasRenderer; 
     111    this.isIE = self.IECanvasEmulationIfNeeded(this.options.IECanvasHTC); 
     112    this.IEDelay = 0.5; 
     113    this.maxTries = 5; 
     114    this.renderDelay = null; 
     115    this.clearDelay = null; 
     116 
    105117    this.layout = layout; 
    106118    this.style = layout.style; 
    107     this.element = MochiKit.DOM.getElement(element); 
     119    this.element = MochiKit.DOM.getElement(this.element_id); 
     120    //this.element = element; 
    108121    this.container = this.element.parentNode; 
    109122    this.height = element.height; 
     
    115128        throw "CanvasRenderer() - passed canvas is not found"; 
    116129 
    117     this.isIE = this.IECanvasEmulationIfNeeded(this.element); 
    118     this.IEDelay = 0.3; 
    119130    if (!this.isIE && !(PlotKit.CanvasRenderer.isSupported(this.element))) 
    120131        throw "CanvasRenderer() - Canvas is not supported."; 
    121132 
    122     if (isNil(this.container) || (this.container.nodeName == "div")) 
     133    if (isNil(this.container) || (this.container.nodeName != "DIV")) 
    123134        throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>"; 
    124135 
     
    138149    {"style":{ "position": "relative", "width": this.width + "px"}}); 
    139150 
     151 
     152 
    140153    // load event system if we have Signals 
    141154    this.event_isinside = null; 
     
    146159}; 
    147160 
    148 PlotKit.CanvasRenderer.prototype.IECanvasEmulationIfNeeded = function(elem) { 
     161PlotKit.CanvasRenderer.IECanvasEmulationIfNeeded = function(htc) { 
    149162    var ie = navigator.appVersion.match(/MSIE (\d\.\d)/); 
    150163    var opera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1); 
     
    152165        return false; 
    153166 
    154     this.element.style.width = this.element.width + "px"; 
    155     this.element.style.height = this.element.height + "px"; 
    156  
    157167    if (isUndefinedOrNull(MochiKit.DOM.getElement('VMLRender'))) { 
     168        // before we add VMLRender, we need to recreate all canvas tags 
     169        // programmatically otherwise IE will not recognise it 
     170 
     171        var nodes = document.getElementsByTagName('canvas'); 
     172        for (var i = 0; i < nodes.length; i++) { 
     173            var node = nodes[i]; 
     174            if (node.getContext) { return; } // Other implementation, abort 
     175            var newNode = MochiKit.DOM.CANVAS( 
     176               {id: node.id,  
     177                width: "" + parseInt(node.width), 
     178                height: "" + parseInt(node.height)}, ""); 
     179            newNode.style.width = parseInt(node.width) + "px"; 
     180            newNode.style.height = parseInt(node.height) + "px"; 
     181            node.id = node.id + "_old"; 
     182            MochiKit.DOM.swapDOM(node, newNode); 
     183        } 
     184 
    158185        document.namespaces.add("v"); 
    159186        var vmlopts = {'id':'VMLRender', 
     
    162189        var vml = MochiKit.DOM.createDOM('object', vmlopts); 
    163190        document.body.appendChild(vml); 
    164         var htc = this.options.IECanvasHTC; 
    165191        var vmlStyle = document.createStyleSheet(); 
    166192        vmlStyle.addRule("canvas", "behavior: url('" + htc + "');"); 
    167193        vmlStyle.addRule("v\\:*", "behavior: url(#VMLRender);"); 
    168194    } 
    169  
    170195    return true; 
    171196}; 
     
    175200        // VML takes a while to start up, so we just poll every this.IEDelay 
    176201        try { 
     202            if (this.renderDelay) { 
     203                this.renderDelay.cancel(); 
     204                this.renderDelay = null; 
     205            } 
    177206            var context = this.element.getContext("2d"); 
    178207        } 
    179208        catch (e) { 
    180209            this.isFirstRender = false; 
    181             this.delay = MochiKit.Async.wait(this.IEDelay); 
    182             this.delay.addCallback(bind(this.render, this)); 
     210            if (this.maxTries-- > 0) { 
     211                log("trying again"); 
     212                this.renderDelay = MochiKit.Async.wait(this.IEDelay); 
     213                this.renderDelay.addCallback(bind(this.render, this)); 
     214            } 
    183215            return; 
    184216        } 
     
    303335PlotKit.CanvasRenderer.prototype._renderPieChart = function() { 
    304336    var context = this.element.getContext("2d"); 
    305     context.save(); 
    306  
    307337    var colorCount = this.options.colorScheme.length; 
    308338    var slices = this.layout.slices; 
     
    312342    var radius = Math.min(this.area.w * this.options.pieRadius,  
    313343                          this.area.h * this.options.pieRadius); 
     344 
     345    if (this.isIE) { 
     346        centerx = parseInt(centerx); 
     347        centery = parseInt(centery); 
     348        radius = parseInt(radius); 
     349    } 
     350 
    314351 
    315352        // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1 
     
    332369        }; 
    333370 
    334                 if (this.options.shouldFill) { 
    335             makePath(); 
    336                 context.fill(); 
    337         } 
    338  
    339                 if (this.options.shouldStroke) { 
    340             makePath(); 
    341                         context.lineWidth = this.options.strokeWidth; 
    342             if (this.options.strokeColor) 
    343                 context.strokeStyle = this.options.strokeColor.toRGBString(); 
    344             else if (this.options.strokeColorTransform) 
    345                 context.strokeStyle = color[this.options.strokeColorTransform]().toRGBString(); 
    346                         context.stroke(); 
    347                 } 
     371        if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.001) { 
     372            if (this.options.shouldFill) { 
     373                makePath(); 
     374                context.fill(); 
     375            } 
     376             
     377            if (this.options.shouldStroke) { 
     378                makePath(); 
     379                context.lineWidth = this.options.strokeWidth; 
     380                if (this.options.strokeColor) 
     381                    context.strokeStyle = this.options.strokeColor.toRGBString(); 
     382                else if (this.options.strokeColorTransform) 
     383                    context.strokeStyle = color[this.options.strokeColorTransform]().toRGBString(); 
     384                context.stroke(); 
     385            } 
     386        } 
    348387        context.restore(); 
    349388    } 
     
    527566PlotKit.CanvasRenderer.prototype._renderBackground = function() { 
    528567    var context = this.element.getContext("2d"); 
     568    context.save(); 
    529569    context.fillStyle = this.options.backgroundColor.toString(); 
    530570    context.fillRect(0, 0, this.width, this.height); 
     571    context.restore(); 
    531572}; 
    532573 
     
    535576        // VML takes a while to start up, so we just poll every this.IEDelay 
    536577        try { 
     578            if (this.clearDelay) { 
     579                this.clearDelay.cancel(); 
     580                this.clearDelay = null; 
     581            } 
    537582            var context = this.element.getContext("2d"); 
    538583        } 
    539584        catch (e) { 
    540585            this.isFirstRender = false; 
    541             this.delay = MochiKit.Async.wait(this.IEDelay); 
    542             this.delay.addCallback(bind(this.clear, this)); 
     586            this.clearDelay = MochiKit.Async.wait(this.IEDelay); 
     587            this.clearDelay.addCallback(bind(this.clear, this)); 
    543588            return; 
    544589        } 
     
    578623    var y = (e.mouse().page.y - PlotKit.Base.findPosY(this.element) - this.area.y) / this.area.h; 
    579624         
    580     log(x, y); 
     625    //log(x, y); 
    581626 
    582627    var isHit = this.layout.hitTest(x, y); 
  • plotkit/trunk/PlotKit/SVG.js

    r8 r10  
    107107    if (isNil(this.element)) 
    108108        throw "SVGRenderer() - passed SVG object is not found"; 
    109     if (isNil(this.container)) 
     109 
     110    if (isNil(this.container) || this.container.nodeName != "DIV") 
    110111        throw "SVGRenderer() - No DIV's around the SVG."; 
    111112 
  • plotkit/trunk/PlotKit/SweetCanvas.js

    r8 r10  
    5858// --------------------------------------------------------------------- 
    5959 
    60 PlotKit.SweetCanvasRenderer.prototype.__init__ = function(element, layout, options) {  
    61     var additionalOptions = PlotKit.Base.officeBlue(); 
    62     MochiKit.Base.update(additionalOptions, options); 
    63     PlotKit.SweetCanvasRenderer.__super__.__init__.call(this, element, layout, additionalOptions); 
     60PlotKit.SweetCanvasRenderer.prototype.__init__ = function(el, layout, opts) {  
     61    var moreOpts = PlotKit.Base.officeBlue(); 
     62    MochiKit.Base.update(moreOpts, opts); 
     63    PlotKit.SweetCanvasRenderer.__super__.__init__.call(this, el, layout, moreOpts); 
    6464}; 
    6565 
     
    105105        context.shadowBlur = 5.0; 
    106106        context.shadowColor = Color.fromHexString("#888888").toRGBString(); 
    107          
    108         prepareFakeShadow(context, x, y, w, h); 
     107 
     108        if (this.isIE) { 
     109            context.save(); 
     110            context.fillStyle = "#cccccc"; 
     111            context.fillRect(x-2, y-2, w+4, h+2);  
     112            context.restore(); 
     113        } 
     114        else { 
     115            prepareFakeShadow(context, x, y, w, h); 
     116        } 
     117 
    109118        context.fillStyle = chooseColor(bar.name).toRGBString(); 
    110119        context.fillRect(x, y, w, h); 
     
    157166        // faux shadow for firefox 
    158167        context.save(); 
    159         context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString(); 
     168        if (this.isIE) { 
     169            context.fillStyle = "#cccccc"; 
     170        } 
     171        else { 
     172            context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString(); 
     173        } 
     174 
    160175        context.translate(-1, -2); 
    161176        bind(makePath, this)();         
     
    178193}; 
    179194 
    180  
    181195PlotKit.CanvasRenderer.prototype._renderPieChart = function() { 
    182196    var context = this.element.getContext("2d"); 
    183     context.save(); 
    184197 
    185198    var colorCount = this.options.colorScheme.length; 
     
    191204                          this.area.h * this.options.pieRadius); 
    192205 
     206    if (this.isIE) { 
     207        centerx = parseInt(centerx); 
     208        centery = parseInt(centery); 
     209        radius = parseInt(radius); 
     210    } 
     211 
    193212        // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1 
    194213        // so we have to subtract 90 degrees to make it start at y = 1, x = 0 
    195  
    196     context.save(); 
    197     context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString(); 
    198     context.shadowBlur = 5.0; 
    199     context.shadowColor = Color.fromHexString("#888888").toRGBString(); 
    200      
    201     context.translate(1, 1); 
    202     context.beginPath(); 
    203     context.moveTo(centerx, centery); 
    204     context.arc(centerx, centery, radius + 2, 0, Math.PI*2, false); 
    205     context.closePath(); 
    206     context.fill(); 
    207     context.restore(); 
    208  
     214    if (!this.isIE) { 
     215        context.save(); 
     216        context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString(); 
     217        context.shadowBlur = 5.0; 
     218        context.shadowColor = Color.fromHexString("#888888").toRGBString(); 
     219         
     220        context.translate(1, 1); 
     221        context.beginPath(); 
     222        context.moveTo(centerx, centery); 
     223        context.arc(centerx, centery, radius + 2, 0, Math.PI*2, false); 
     224        context.closePath(); 
     225        context.fill(); 
     226        context.restore(); 
     227    } 
    209228 
    210229    context.strokeStyle = Color.whiteColor().toRGBString(); 
    211230    context.lineWidth = 2.0;     
     231    context.save(); 
    212232    for (var i = 0; i < slices.length; i++) { 
    213233        var color = this.options.colorScheme[i%colorCount]; 
    214         context.save(); 
    215234        context.fillStyle = color.toRGBString(); 
    216235 
     
    225244            context.closePath(); 
    226245        }; 
    227          
    228          
    229  
    230         makePath(); 
    231         context.fill(); 
    232         makePath(); 
    233                 context.stroke(); 
    234                  
    235         context.restore(); 
    236     } 
    237 }; 
    238  
     246 
     247        if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.0001) { 
     248            makePath(); 
     249            context.fill(); 
     250            makePath(); 
     251            context.stroke(); 
     252        } 
     253    } 
     254    context.restore(); 
     255}; 
    239256 
    240257PlotKit.SweetCanvasRenderer.prototype._renderBackground = function() { 
    241258    var context = this.element.getContext("2d"); 
    242     //context.fillStyle = Color.whiteColor().toRGBString(); 
    243     //context.fillRect(0, 0, this.width, this.height); 
    244  
    245     context.fillStyle = this.options.backgroundColor.toRGBString(); 
    246     context.fillRect(this.area.x, this.area.y, this.area.w, this.area.h); 
    247  
     259    
    248260    if (this.layout.style == "bar" || this.layout.style == "line") { 
    249261        context.save(); 
     262        context.fillStyle = this.options.backgroundColor.toRGBString(); 
     263        context.fillRect(this.area.x, this.area.y, this.area.w, this.area.h); 
    250264        context.strokeStyle = Color.whiteColor().toRGBString(); 
    251265        context.lineWidth = 1.0; 
     
    264278        PlotKit.SweetCanvasRenderer.__super__._renderBackground.call(this); 
    265279    } 
    266          
    267 }; 
     280}; 
  • plotkit/trunk/doc/PlotKit.QuickStart.html

    r8 r10  
    181181</p> 
    182182<pre><code>var options = { 
    183    &quot;IECanvasHTC&quot;: &quot;../PlotKit/iecanvas.htc&quot;, 
     183   &quot;IECanvasHTC&quot;: &quot;/plotkit/iecanvas.htc&quot;, 
    184184   &quot;colorScheme&quot;: PlotKit.Base.palette(PlotKit.Base.baseColors()[0]), 
    185185   &quot;padding&quot;: {left: 0, right: 0, top: 10, bottom: 30}, 
     
    249249<script type="text/javascript"> 
    250250<!-- 
     251 
    251252var options = { 
    252    "IECanvasHTC": "../PlotKit/iecanvas.htc", 
    253    "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]), 
     253   "IECanvasHTC": "../plotkit/iecanvas.htc", 
     254   "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),  
    254255   "padding": {left: 10, right: 10, top: 10, bottom: 30}, 
    255256   "xTicks": [{v:0, label:"zero"},  
     
    261262   "pieRadius": 0.35 
    262263}; 
     264 
    263265 
    264266function drawBarGraph() { 
  • plotkit/trunk/doc/PlotKit.QuickStart.txt

    r8 r10  
    148148 
    149149    var options = { 
    150        "IECanvasHTC": "../PlotKit/iecanvas.htc", 
     150       "IECanvasHTC": "/plotkit/iecanvas.htc", 
    151151       "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]), 
    152152       "padding": {left: 0, right: 0, top: 10, bottom: 30}, 
     
    212212<script type="text/javascript"> 
    213213<!-- 
     214 
    214215var options = { 
    215    "IECanvasHTC": "../PlotKit/iecanvas.htc", 
    216    "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]), 
     216   "IECanvasHTC": "../plotkit/iecanvas.htc", 
     217   "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]),  
    217218   "padding": {left: 10, right: 10, top: 10, bottom: 30}, 
    218219   "xTicks": [{v:0, label:"zero"},  
     
    225226}; 
    226227 
     228 
    227229function drawBarGraph() { 
    228230   var layout = new PlotKit.Layout("bar", options); 
  • plotkit/trunk/tests/sweet.js

    r7 r10  
    11/* actual tests */ 
    22 
    3 var options = {"IECanvasHTC":"../PlotKit/iecanvas.htc"}; 
    4 MochiKit.Base.update(options, PlotKit.Base.officePurple()); 
     3var opts = { 
     4    "IECanvasHTC": "../plotkit/iecanvas.htc", 
     5    "enableEvents": false 
     6}; 
    57 
    68function genericTest(num, plotStyle) { 
     
    911        l.evaluate(); 
    1012        var c = $("test" + num + "canvas"); 
    11         var g = new PlotKit.SweetCanvasRenderer(c, l, options); 
     13        var g = new PlotKit.SweetCanvasRenderer(c, l, opts); 
    1214        g.render(); 
    1315} 
     
    1719        l.addDatasetFromTable("data1." + num, $("test" + num), 0, 1);    
    1820        l.addDatasetFromTable("data2." + num, $("test" + num), 0, 2);    
    19         l.addDatasetFromTable("data3." + num, $("test" + num), 0, 1);    
    20         l.addDatasetFromTable("data4." + num, $("test" + num), 0, 2);    
    21         l.addDatasetFromTable("data5." + num, $("test" + num), 0, 1);    
    22         l.addDatasetFromTable("data6." + num, $("test" + num), 0, 2);    
    2321        l.evaluate(); 
    2422        var c = $("test" + num + "canvas"); 
    25         var g = new PlotKit.SweetCanvasRenderer(c, l, options); 
     23        var g = new PlotKit.SweetCanvasRenderer(c, l, opts); 
    2624        g.render(); 
    2725} 
     
    7169    var missingData = [[0, 1], [1, 4], [3, 16], [5, 17]]; 
    7270     
    73     var dualData = [[0,0,0], [1,2,1], [2,4,4], [3,8,9]]; // , [4,16,16], [5,32,25], [6, 64, 36], [7, 128, 49]]; 
     71    var dualData = [[0,0,0], [1,2,1], [2,4,4], [3,8,9], [4,16,16], [5,32,25], [6, 64, 36], [7, 128, 49]]; 
    7472 
    7573    tests.appendChild(H2(null, "Simple Tests")); 
     
    8785    tests.appendChild(generateUnitTest(5, genericTest, simpleData1, 
    8886    "pie", "")); 
     87 
    8988} 
    9089