Index: static/js/plotkit/SweetCanvas.js |
diff --git a/static/js/plotkit/SweetCanvas.js b/static/js/plotkit/SweetCanvas.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..073b7044042faeb81e7f5aff926a87c0acde285e |
--- /dev/null |
+++ b/static/js/plotkit/SweetCanvas.js |
@@ -0,0 +1,348 @@ |
+/* |
+ ======= |
+ PlotKit is a collection of Javascript classes that allows |
+ you to quickly visualise data using different types of charts. |
+ |
+ http://www.liquidx.net/plotkit/ |
+ |
+ See LICENSE file for copyright information. |
+ |
+ Canvas Renderer for PlotKit which looks pretty! |
+*/ |
+ |
+// ------------------------------------------------------------------------- |
+// Check required components |
+// ------------------------------------------------------------------------- |
+ |
+try { |
+ if (typeof(PlotKit.CanvasRenderer) == 'undefined') |
+ { |
+ throw ""; |
+ } |
+} |
+catch (e) { |
+ throw "SweetCanvas depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, Canvas}" |
+} |
+ |
+ |
+if (typeof(PlotKit.SweetCanvasRenderer) == 'undefined') { |
+ PlotKit.SweetCanvasRenderer = {}; |
+} |
+ |
+PlotKit.SweetCanvasRenderer = function(element, layout, options) { |
+ if (arguments.length > 0) { |
+ this.__init__(element, layout, options); |
+ } |
+}; |
+ |
+PlotKit.SweetCanvasRenderer.NAME = "PlotKit.SweetCanvasRenderer"; |
+PlotKit.SweetCanvasRenderer.VERSION = PlotKit.VERSION; |
+ |
+PlotKit.SweetCanvasRenderer.__repr__ = function() { |
+ return "[" + this.NAME + " " + this.VERSION + "]"; |
+}; |
+ |
+PlotKit.SweetCanvasRenderer.toString = function() { |
+ return this.__repr__(); |
+}; |
+ |
+// --------------------------------------------------------------------- |
+// Subclassing Magic |
+// --------------------------------------------------------------------- |
+ |
+PlotKit.SweetCanvasRenderer.prototype = new PlotKit.CanvasRenderer(); |
+PlotKit.SweetCanvasRenderer.prototype.constructor = PlotKit.SweetCanvasRenderer; |
+PlotKit.SweetCanvasRenderer.__super__ = PlotKit.CanvasRenderer.prototype; |
+ |
+// --------------------------------------------------------------------- |
+// Constructor |
+// --------------------------------------------------------------------- |
+ |
+PlotKit.SweetCanvasRenderer.prototype.__init__ = function(el, layout, opts) { |
+ var moreOpts = PlotKit.Base.officeBlue(); |
+ MochiKit.Base.update(moreOpts, opts); |
+ PlotKit.SweetCanvasRenderer.__super__.__init__.call(this, el, layout, moreOpts); |
+}; |
+ |
+// --------------------------------------------------------------------- |
+// Extended Plotting Functions |
+// --------------------------------------------------------------------- |
+ |
+PlotKit.SweetCanvasRenderer.prototype._renderBarChart = function() { |
+ var bind = MochiKit.Base.bind; |
+ var shadowColor = Color.blackColor().colorWithAlpha(0.1).toRGBString(); |
+ |
+ var prepareFakeShadow = function(context, x, y, w, h) { |
+ context.fillStyle = shadowColor; |
+ context.fillRect(x-2, y-2, w+4, h+2); |
+ context.fillStyle = shadowColor; |
+ context.fillRect(x-1, y-1, w+2, h+1); |
+ }; |
+ |
+ var colorCount = this.options.colorScheme.length; |
+ var colorScheme = this.options.colorScheme; |
+ var setNames = PlotKit.Base.keys(this.layout.datasets); |
+ var setCount = setNames.length; |
+ |
+ var chooseColor = function(name) { |
+ for (var i = 0; i < setCount; i++) { |
+ if (name == setNames[i]) |
+ return colorScheme[i%colorCount]; |
+ } |
+ return colorScheme[0]; |
+ }; |
+ |
+ 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; |
+ |
+ context.save(); |
+ |
+ context.shadowBlur = 5.0; |
+ context.shadowColor = Color.fromHexString("#888888").toRGBString(); |
+ |
+ if (this.isIE) { |
+ context.save(); |
+ context.fillStyle = "#cccccc"; |
+ context.fillRect(x-2, y-2, w+4, h+2); |
+ context.restore(); |
+ } |
+ else { |
+ prepareFakeShadow(context, x, y, w, h); |
+ } |
+ |
+ if (this.options.shouldFill) { |
+ context.fillStyle = chooseColor(bar.name).toRGBString(); |
+ context.fillRect(x, y, w, h); |
+ } |
+ |
+ context.shadowBlur = 0; |
+ context.strokeStyle = Color.whiteColor().toRGBString(); |
+ context.lineWidth = 2.0; |
+ |
+ if (this.options.shouldStroke) { |
+ context.strokeRect(x, y, w, h); |
+ } |
+ |
+ context.restore(); |
+ |
+ }; |
+ this._renderBarChartWrap(this.layout.bars, bind(drawRect, this)); |
+}; |
+ |
+PlotKit.SweetCanvasRenderer.prototype._renderLineChart = function() { |
+ var context = this.element.getContext("2d"); |
+ var colorCount = this.options.colorScheme.length; |
+ var colorScheme = this.options.colorScheme; |
+ var setNames = PlotKit.Base.keys(this.layout.datasets); |
+ var setCount = setNames.length; |
+ var bind = MochiKit.Base.bind; |
+ |
+ |
+ 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(); |
+ |
+ // 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(); |
+ }; |
+ |
+ // faux shadow for firefox |
+ if (this.options.shouldFill) { |
+ context.save(); |
+ if (this.isIE) { |
+ context.fillStyle = "#cccccc"; |
+ } |
+ else { |
+ context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString(); |
+ } |
+ context.translate(-1, -2); |
+ bind(makePath, this)(context); |
+ if (this.options.shouldFill) { |
+ context.fill(); |
+ } |
+ context.restore(); |
+ } |
+ |
+ context.shadowBlur = 5.0; |
+ context.shadowColor = Color.fromHexString("#888888").toRGBString(); |
+ context.fillStyle = color.toRGBString(); |
+ context.lineWidth = 2.0; |
+ context.strokeStyle = Color.whiteColor().toRGBString(); |
+ |
+ if (this.options.shouldFill) { |
+ bind(makePath, this)(context); |
+ context.fill(); |
+ } |
+ if (this.options.shouldStroke) { |
+ bind(makePath, this)(context); |
+ context.stroke(); |
+ } |
+ context.restore(); |
+ } |
+}; |
+ |
+PlotKit.SweetCanvasRenderer.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 |
+ |
+ if (!this.isIE) { |
+ context.save(); |
+ var shadowColor = Color.blackColor().colorWithAlpha(0.2); |
+ context.fillStyle = shadowColor.toRGBString(); |
+ context.shadowBlur = 5.0; |
+ context.shadowColor = Color.fromHexString("#888888").toRGBString(); |
+ context.translate(1, 1); |
+ context.beginPath(); |
+ context.moveTo(centerx, centery); |
+ context.arc(centerx, centery, radius + 2, 0, Math.PI*2, false); |
+ context.closePath(); |
+ context.fill(); |
+ context.restore(); |
+ } |
+ |
+ context.save(); |
+ context.strokeStyle = Color.whiteColor().toRGBString(); |
+ context.lineWidth = 2.0; |
+ for (var i = 0; i < slices.length; i++) { |
+ var color = this.options.colorScheme[i%colorCount]; |
+ 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.0001) { |
+ if (this.options.shouldFill) { |
+ makePath(); |
+ context.fill(); |
+ } |
+ if (this.options.shouldStroke) { |
+ makePath(); |
+ context.stroke(); |
+ } |
+ } |
+ } |
+ context.restore(); |
+}; |
+ |
+PlotKit.SweetCanvasRenderer.prototype._renderBackground = function() { |
+ var context = this.element.getContext("2d"); |
+ |
+ if (this.layout.style == "bar" || this.layout.style == "line") { |
+ context.save(); |
+ context.fillStyle = this.options.backgroundColor.toRGBString(); |
+ context.fillRect(this.area.x, this.area.y, this.area.w, this.area.h); |
+ context.strokeStyle = this.options.axisLineColor.toRGBString(); |
+ context.lineWidth = 1.0; |
+ |
+ var ticks = this.layout.yticks; |
+ var horiz = false; |
+ if (this.layout.style == "bar" && |
+ this.layout.options.barOrientation == "horizontal") { |
+ ticks = this.layout.xticks; |
+ horiz = true; |
+ } |
+ |
+ for (var i = 0; i < ticks.length; i++) { |
+ var x1 = 0; |
+ var y1 = 0; |
+ var x2 = 0; |
+ var y2 = 0; |
+ |
+ if (horiz) { |
+ x1 = ticks[i][0] * this.area.w + this.area.x; |
+ y1 = this.area.y; |
+ x2 = x1; |
+ y2 = y1 + this.area.h; |
+ } |
+ else { |
+ x1 = this.area.x; |
+ y1 = ticks[i][0] * this.area.h + this.area.y; |
+ x2 = x1 + this.area.w; |
+ y2 = y1; |
+ } |
+ |
+ context.beginPath(); |
+ context.moveTo(x1, y1); |
+ context.lineTo(x2, y2); |
+ context.closePath(); |
+ context.stroke(); |
+ } |
+ context.restore(); |
+ } |
+ else { |
+ PlotKit.SweetCanvasRenderer.__super__._renderBackground.call(this); |
+ } |
+}; |
+ |
+// Namespace Iniitialisation |
+ |
+PlotKit.SweetCanvas = {} |
+PlotKit.SweetCanvas.SweetCanvasRenderer = PlotKit.SweetCanvasRenderer; |
+ |
+PlotKit.SweetCanvas.EXPORT = [ |
+ "SweetCanvasRenderer" |
+]; |
+ |
+PlotKit.SweetCanvas.EXPORT_OK = [ |
+ "SweetCanvasRenderer" |
+]; |
+ |
+PlotKit.SweetCanvas.__new__ = function() { |
+ var m = MochiKit.Base; |
+ |
+ m.nameFunctions(this); |
+ |
+ this.EXPORT_TAGS = { |
+ ":common": this.EXPORT, |
+ ":all": m.concat(this.EXPORT, this.EXPORT_OK) |
+ }; |
+}; |
+ |
+PlotKit.SweetCanvas.__new__(); |
+MochiKit.Base._exportSymbols(this, PlotKit.SweetCanvas); |