| 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);
|
|
|