X-Git-Url: https://adrianiainlam.tk/git/?a=blobdiff_plain;f=plotkit_v091%2FPlotKit%2FCanvas.js;h=a3a1e09be077c3dc865051b8de22161cf897702e;hb=3df0ccf0a09d28577e3a695302f1deb926ae8a83;hp=d263192711ad64014af7aa61abe9938aa3f1ebbe;hpb=9148174ba7625a06277b5ead599b7d8ee9fa463c;p=dygraphs.git diff --git a/plotkit_v091/PlotKit/Canvas.js b/plotkit_v091/PlotKit/Canvas.js index d263192..a3a1e09 100644 --- a/plotkit_v091/PlotKit/Canvas.js +++ b/plotkit_v091/PlotKit/Canvas.js @@ -1,57 +1,3 @@ -/* - PlotKit Canvas - ============== - - Provides HTML Canvas Renderer. This is supported under: - - - Safari 2.0 - - Mozilla Firefox 1.5 - - Opera 9.0 preview 2 - - IE 6 (via VML Emulation) - - It uses DIVs for labels. - - Copyright - --------- - Copyright 2005,2006 (c) Alastair Tse - For use under the BSD license. - -*/ -// -------------------------------------------------------------------- -// Check required components -// -------------------------------------------------------------------- - -try { - if ((typeof(PlotKit.Base) == 'undefined') || - (typeof(PlotKit.Layout) == 'undefined')) - { - throw ""; - } -} -catch (e) { - throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Base,Layout}" -} - - -// ------------------------------------------------------------------------ -// Defines the renderer class -// ------------------------------------------------------------------------ - -if (typeof(PlotKit.CanvasRenderer) == 'undefined') { - PlotKit.CanvasRenderer = {}; -} - -PlotKit.CanvasRenderer.NAME = "PlotKit.CanvasRenderer"; -PlotKit.CanvasRenderer.VERSION = PlotKit.VERSION; - -PlotKit.CanvasRenderer.__repr__ = function() { - return "[" + this.NAME + " " + this.VERSION + "]"; -}; - -PlotKit.CanvasRenderer.toString = function() { - return this.__repr__(); -} - PlotKit.CanvasRenderer = function(element, layout, options) { if (arguments.length > 0) this.__init__(element, layout, options); @@ -63,15 +9,7 @@ PlotKit.CanvasRenderer.prototype.__init__ = function(element, layout, options) { // default options this.options = { - "drawBackground": true, - "backgroundColor": Color.whiteColor(), - "padding": {left: 30, right: 30, top: 5, bottom: 10}, - "colorScheme": PlotKit.Base.palette(PlotKit.Base.baseColors()[0]), - "strokeColor": Color.whiteColor(), - "strokeColorTransform": "asStrokeColor", "strokeWidth": 0.5, - "shouldFill": true, - "shouldStroke": true, "drawXAxis": true, "drawYAxis": true, "axisLineColor": Color.blackColor(), @@ -80,9 +18,7 @@ PlotKit.CanvasRenderer.prototype.__init__ = function(element, layout, options) { "axisLabelColor": Color.blackColor(), "axisLabelFont": "Arial", "axisLabelFontSize": 9, - "axisLabelWidth": 50, - "pieRadius": 0.4, - "enableEvents": true + "axisLabelWidth": 50, }; MochiKit.Base.update(this.options, options ? options : {}); @@ -118,112 +54,17 @@ PlotKit.CanvasRenderer.prototype.__init__ = function(element, layout, options) { // internal state this.xlabels = new Array(); this.ylabels = new Array(); - this.isFirstRender = true; this.area = { - x: this.options.padding.left, - y: this.options.padding.top, - w: this.width - this.options.padding.left - this.options.padding.right, - h: this.height - this.options.padding.top - this.options.padding.bottom + x: this.options.yAxisLabelWidth + 2 * this.options.axisTickSize, + y: 0 }; + this.area.w = this.width - this.area.x - this.options.rightGap; + this.area.h = this.height - this.options.axisLabelFontSize - + 2 * this.options.axisTickSize; MochiKit.DOM.updateNodeAttributes(this.container, {"style":{ "position": "relative", "width": this.width + "px"}}); - - // load event system if we have Signals - /* Disabled until we have a proper implementation - try { - this.event_isinside = null; - if (MochiKit.Signal && this.options.enableEvents) { - this._initialiseEvents(); - } - } - catch (e) { - // still experimental - } - */ -}; - -PlotKit.CanvasRenderer.prototype.render = function() { - if (this.isIE) { - // VML takes a while to start up, so we just poll every this.IEDelay - try { - if (this.renderDelay) { - this.renderDelay.cancel(); - this.renderDelay = null; - } - var context = this.element.getContext("2d"); - } - catch (e) { - this.isFirstRender = false; - if (this.maxTries-- > 0) { - this.renderDelay = MochiKit.Async.wait(this.IEDelay); - this.renderDelay.addCallback(bind(this.render, this)); - } - return; - } - } - - if (this.options.drawBackground) - this._renderBackground(); - - if (this.layout.style == "line") { - this._renderLineChart(); - this._renderLineAxis(); - } -}; - -PlotKit.CanvasRenderer.prototype._renderLineChart = function() { - var context = this.element.getContext("2d"); - var colorCount = this.options.colorScheme.length; - var colorScheme = this.options.colorScheme; - var setNames = MochiKit.Base.keys(this.layout.datasets); - var setCount = setNames.length; - var bind = MochiKit.Base.bind; - var partial = MochiKit.Base.partial; - - for (var i = 0; i < setCount; i++) { - var setName = setNames[i]; - var color = colorScheme[i%colorCount]; - var strokeX = this.options.strokeColorTransform; - - // setup graphics context - context.save(); - context.fillStyle = color.toRGBString(); - if (this.options.strokeColor) - context.strokeStyle = this.options.strokeColor.toRGBString(); - else if (this.options.strokeColorTransform) - context.strokeStyle = color[strokeX]().toRGBString(); - - context.lineWidth = this.options.strokeWidth; - - // create paths - var makePath = function(ctx) { - ctx.beginPath(); - ctx.moveTo(this.area.x, this.area.y + this.area.h); - var addPoint = function(ctx_, point) { - if (point.name == setName) - ctx_.lineTo(this.area.w * point.x + this.area.x, - this.area.h * point.y + this.area.y); - }; - MochiKit.Iter.forEach(this.layout.points, partial(addPoint, ctx), this); - ctx.lineTo(this.area.w + this.area.x, - this.area.h + this.area.y); - ctx.lineTo(this.area.x, this.area.y + this.area.h); - ctx.closePath(); - }; - - if (this.options.shouldFill) { - bind(makePath, this)(context); - context.fill(); - } - if (this.options.shouldStroke) { - bind(makePath, this)(context); - context.stroke(); - } - - context.restore(); - } }; @@ -267,15 +108,33 @@ PlotKit.CanvasRenderer.prototype._renderAxis = function() { context.stroke(); var label = DIV(labelStyle, tick[1]); - label.style.top = (y - this.options.axisLabelFontSize) + "px"; - label.style.left = (x - this.options.padding.left - this.options.axisTickSize) + "px"; + var top = (y - this.options.axisLabelFontSize / 2); + if (top < 0) top = 0; + + if (top + this.options.axisLabelFontSize + 3 > this.height) { + label.style.bottom = "0px"; + } else { + label.style.top = top + "px"; + } + label.style.left = "0px"; label.style.textAlign = "right"; - label.style.width = (this.options.padding.left - this.options.axisTickSize * 2) + "px"; + label.style.width = this.options.yAxisLabelWidth + "px"; MochiKit.DOM.appendChildNodes(this.container, label); this.ylabels.push(label); }; MochiKit.Iter.forEach(this.layout.yticks, bind(drawTick, this)); + + // The lowest tick on the y-axis often overlaps with the leftmost + // tick on the x-axis. Shift the bottom tick up a little bit to + // compensate if necessary. + var bottomTick = this.ylabels[0]; + var fontSize = this.options.axisLabelFontSize; + var bottom = parseInt(bottomTick.style.top) + fontSize; + if (bottom > this.height - fontSize) { + bottomTick.style.top = (parseInt(bottomTick.style.top) - + fontSize / 2) + "px"; + } } context.beginPath(); @@ -299,10 +158,21 @@ PlotKit.CanvasRenderer.prototype._renderAxis = function() { context.stroke(); var label = DIV(labelStyle, tick[1]); - label.style.top = (y + this.options.axisTickSize) + "px"; - label.style.left = (x - this.options.axisLabelWidth/2) + "px"; label.style.textAlign = "center"; - label.style.width = this.options.axisLabelWidth + "px"; + label.style.bottom = "0px"; + + var left = (x - this.options.axisLabelWidth/2); + if (left + this.options.axisLabelWidth > this.width) { + left = this.width - this.options.xAxisLabelWidth; + label.style.textAlign = "right"; + } + if (left < 0) { + left = 0; + label.style.textAlign = "left"; + } + + label.style.left = left + "px"; + label.style.width = this.options.xAxisLabelWidth + "px"; MochiKit.DOM.appendChildNodes(this.container, label); this.xlabels.push(label); }; @@ -321,14 +191,6 @@ PlotKit.CanvasRenderer.prototype._renderAxis = function() { }; -PlotKit.CanvasRenderer.prototype._renderBackground = function() { - var context = this.element.getContext("2d"); - context.save(); - context.fillStyle = this.options.backgroundColor.toRGBString(); - context.fillRect(0, 0, this.width, this.height); - context.restore(); -}; - PlotKit.CanvasRenderer.prototype.clear = function() { if (this.isIE) { // VML takes a while to start up, so we just poll every this.IEDelay @@ -340,7 +202,6 @@ PlotKit.CanvasRenderer.prototype.clear = function() { var context = this.element.getContext("2d"); } catch (e) { - this.isFirstRender = false; this.clearDelay = MochiKit.Async.wait(this.IEDelay); this.clearDelay.addCallback(bind(this.clear, this)); return; @@ -360,87 +221,6 @@ PlotKit.CanvasRenderer.prototype.clear = function() { // Everything below here is experimental and undocumented. // ---------------------------------------------------------------- -PlotKit.CanvasRenderer.prototype._initialiseEvents = function() { - var connect = MochiKit.Signal.connect; - var bind = MochiKit.Base.bind; - //MochiKit.Signal.registerSignals(this, ['onmouseover', 'onclick', 'onmouseout', 'onmousemove']); - //connect(this.element, 'onmouseover', bind(this.onmouseover, this)); - //connect(this.element, 'onmouseout', bind(this.onmouseout, this)); - //connect(this.element, 'onmousemove', bind(this.onmousemove, this)); - connect(this.element, 'onclick', bind(this.onclick, this)); -}; - -PlotKit.CanvasRenderer.prototype._resolveObject = function(e) { - // does not work in firefox - //var x = (e.event().offsetX - this.area.x) / this.area.w; - //var y = (e.event().offsetY - this.area.y) / this.area.h; - - var x = (e.mouse().page.x - PlotKit.Base.findPosX(this.element) - this.area.x) / this.area.w; - var y = (e.mouse().page.y - PlotKit.Base.findPosY(this.element) - this.area.y) / this.area.h; - - //log(x, y); - - var isHit = this.layout.hitTest(x, y); - if (isHit) - return isHit; - return null; -}; - -PlotKit.CanvasRenderer.prototype._createEventObject = function(layoutObj, e) { - if (layoutObj == null) { - return null; - } - - e.chart = layoutObj - return e; -}; - - -PlotKit.CanvasRenderer.prototype.onclick = function(e) { - var layoutObject = this._resolveObject(e); - var eventObject = this._createEventObject(layoutObject, e); - if (eventObject != null) - MochiKit.Signal.signal(this, "onclick", eventObject); -}; - -PlotKit.CanvasRenderer.prototype.onmouseover = function(e) { - var layoutObject = this._resolveObject(e); - var eventObject = this._createEventObject(layoutObject, e); - if (eventObject != null) - signal(this, "onmouseover", eventObject); -}; - -PlotKit.CanvasRenderer.prototype.onmouseout = function(e) { - var layoutObject = this._resolveObject(e); - var eventObject = this._createEventObject(layoutObject, e); - if (eventObject == null) - signal(this, "onmouseout", e); - else - signal(this, "onmouseout", eventObject); - -}; - -PlotKit.CanvasRenderer.prototype.onmousemove = function(e) { - var layoutObject = this._resolveObject(e); - var eventObject = this._createEventObject(layoutObject, e); - - if ((layoutObject == null) && (this.event_isinside == null)) { - // TODO: should we emit an event anyway? - return; - } - - if ((layoutObject != null) && (this.event_isinside == null)) - signal(this, "onmouseover", eventObject); - - if ((layoutObject == null) && (this.event_isinside != null)) - signal(this, "onmouseout", eventObject); - - if ((layoutObject != null) && (this.event_isinside != null)) - signal(this, "onmousemove", eventObject); - - this.event_isinside = layoutObject; - //log("move", x, y); -}; PlotKit.CanvasRenderer.isSupported = function(canvasName) { var canvas = null; @@ -460,31 +240,3 @@ PlotKit.CanvasRenderer.isSupported = function(canvasName) { } return true; }; - -// Namespace Iniitialisation - -PlotKit.Canvas = {} -PlotKit.Canvas.CanvasRenderer = PlotKit.CanvasRenderer; - -PlotKit.Canvas.EXPORT = [ - "CanvasRenderer" -]; - -PlotKit.Canvas.EXPORT_OK = [ - "CanvasRenderer" -]; - -PlotKit.Canvas.__new__ = function() { - var m = MochiKit.Base; - - m.nameFunctions(this); - - this.EXPORT_TAGS = { - ":common": this.EXPORT, - ":all": m.concat(this.EXPORT, this.EXPORT_OK) - }; -}; - -PlotKit.Canvas.__new__(); -MochiKit.Base._exportSymbols(this, PlotKit.Canvas); -