📄 canvas.js
字号:
/* 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 <alastair^liquidx.net> For use under the BSD license. <http://www.liquidx.net/plotkit> */// --------------------------------------------------------------------// 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);};PlotKit.CanvasRenderer.prototype.__init__ = function(element, layout, options) { var isNil = MochiKit.Base.isUndefinedOrNull; var Color = MochiKit.Color.Color; // 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(), "axisLineWidth": 0.5, "axisTickSize": 3, "axisLabelColor": Color.blackColor(), "axisLabelFont": "Arial", "axisLabelFontSize": 9, "axisLabelWidth": 50, "pieRadius": 0.4, "enableEvents": true }; MochiKit.Base.update(this.options, options ? options : {}); this.layout = layout; this.element = MochiKit.DOM.getElement(element); this.container = this.element.parentNode; // Stuff relating to Canvas on IE support this.isIE = PlotKit.Base.excanvasSupported(); if (this.isIE && !isNil(G_vmlCanvasManager)) { this.IEDelay = 0.5; this.maxTries = 5; this.renderDelay = null; this.clearDelay = null; this.element = G_vmlCanvasManager.initElement(this.element); } this.height = this.element.height; this.width = this.element.width; // --- check whether everything is ok before we return if (isNil(this.element)) throw "CanvasRenderer() - passed canvas is not found"; if (!this.isIE && !(PlotKit.CanvasRenderer.isSupported(this.element))) throw "CanvasRenderer() - Canvas is not supported."; if (isNil(this.container) || (this.container.nodeName.toLowerCase() != "div")) throw "CanvasRenderer() - <canvas> needs to be enclosed in <div>"; // 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 }; 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 == "bar") { this._renderBarChart(); this._renderBarAxis(); } else if (this.layout.style == "pie") { this._renderPieChart(); this._renderPieAxis(); } else if (this.layout.style == "line") { this._renderLineChart(); this._renderLineAxis(); }};PlotKit.CanvasRenderer.prototype._renderBarChartWrap = function(data, plotFunc) { 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; for (var i = 0; i < setCount; i++) { var setName = setNames[i]; var color = colorScheme[i%colorCount]; context.save(); context.fillStyle = color.toRGBString(); if (this.options.strokeColor) context.strokeStyle = this.options.strokeColor.toRGBString(); else if (this.options.strokeColorTransform) context.strokeStyle = color[this.options.strokeColorTransform]().toRGBString(); context.lineWidth = this.options.strokeWidth; var forEachFunc = function(obj) { if (obj.name == setName) plotFunc(context, obj); }; MochiKit.Iter.forEach(data, bind(forEachFunc, this)); context.restore(); }};PlotKit.CanvasRenderer.prototype._renderBarChart = function() { var bind = MochiKit.Base.bind; var drawRect = function(context, bar) { var x = this.area.w * bar.x + this.area.x; var y = this.area.h * bar.y + this.area.y; var w = this.area.w * bar.w; var h = this.area.h * bar.h; if ((w < 1) || (h < 1)) return; if (this.options.shouldFill) context.fillRect(x, y, w, h); if (this.options.shouldStroke) context.strokeRect(x, y, w, h); }; this._renderBarChartWrap(this.layout.bars, bind(drawRect, this));};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(); }};PlotKit.CanvasRenderer.prototype._renderPieChart = function() { var context = this.element.getContext("2d"); var colorCount = this.options.colorScheme.length; var slices = this.layout.slices; var centerx = this.area.x + this.area.w * 0.5; var centery = this.area.y + this.area.h * 0.5; var radius = Math.min(this.area.w * this.options.pieRadius, this.area.h * this.options.pieRadius); if (this.isIE) { centerx = parseInt(centerx); centery = parseInt(centery); radius = parseInt(radius); } // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1 // so we have to subtract 90 degrees to make it start at y = 1, x = 0 for (var i = 0; i < slices.length; i++) { var color = this.options.colorScheme[i%colorCount]; context.save(); context.fillStyle = color.toRGBString(); var makePath = function() { context.beginPath(); context.moveTo(centerx, centery); context.arc(centerx, centery, radius, slices[i].startAngle - Math.PI/2, slices[i].endAngle - Math.PI/2, false); context.lineTo(centerx, centery); context.closePath(); }; if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.001) { if (this.options.shouldFill) { makePath(); context.fill(); } if (this.options.shouldStroke) { makePath(); context.lineWidth = this.options.strokeWidth; if (this.options.strokeColor) context.strokeStyle = this.options.strokeColor.toRGBString(); else if (this.options.strokeColorTransform) context.strokeStyle = color[this.options.strokeColorTransform]().toRGBString(); context.stroke(); } } context.restore(); }};PlotKit.CanvasRenderer.prototype._renderBarAxis = function() { this._renderAxis();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -