Blame | Last modification | View Log | RSS feed
if(!dojo._hasResource["dojox.charting.Chart2D"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.dojo._hasResource["dojox.charting.Chart2D"] = true;dojo.provide("dojox.charting.Chart2D");dojo.require("dojox.gfx");dojo.require("dojox.lang.functional");dojo.require("dojox.charting.Theme");dojo.require("dojox.charting.Series");dojo.require("dojox.charting.axis2d.Default");dojo.require("dojox.charting.plot2d.Default");dojo.require("dojox.charting.plot2d.Lines");dojo.require("dojox.charting.plot2d.Areas");dojo.require("dojox.charting.plot2d.Markers");dojo.require("dojox.charting.plot2d.MarkersOnly");dojo.require("dojox.charting.plot2d.Scatter");dojo.require("dojox.charting.plot2d.Stacked");dojo.require("dojox.charting.plot2d.StackedLines");dojo.require("dojox.charting.plot2d.StackedAreas");dojo.require("dojox.charting.plot2d.Columns");dojo.require("dojox.charting.plot2d.StackedColumns");dojo.require("dojox.charting.plot2d.ClusteredColumns");dojo.require("dojox.charting.plot2d.Bars");dojo.require("dojox.charting.plot2d.StackedBars");dojo.require("dojox.charting.plot2d.ClusteredBars");dojo.require("dojox.charting.plot2d.Grid");dojo.require("dojox.charting.plot2d.Pie");(function(){var df = dojox.lang.functional, dc = dojox.charting,clear = df.lambda("item.clear()"),purge = df.lambda("item.purgeGroup()"),destroy = df.lambda("item.destroy()"),makeClean = df.lambda("item.dirty = false"),makeDirty = df.lambda("item.dirty = true");dojo.declare("dojox.charting.Chart2D", null, {constructor: function(node, kwArgs){// initialize parametersif(!kwArgs){ kwArgs = {}; }this.margins = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};this.stroke = kwArgs.stroke;this.fill = kwArgs.fill;// default initializationthis.theme = null;this.axes = {}; // map of axesthis.stack = []; // stack of plottersthis.plots = {}; // map of plotter indicesthis.series = []; // stack of data runsthis.runs = {}; // map of data run indicesthis.dirty = true;this.coords = null;// create a surfacethis.node = dojo.byId(node);var box = dojo.marginBox(node);this.surface = dojox.gfx.createSurface(this.node, box.w, box.h);},destroy: function(){dojo.forEach(this.series, destroy);dojo.forEach(this.stack, destroy);df.forIn(this.axes, destroy);},getCoords: function(){if(!this.coords){this.coords = dojo.coords(this.node, true);}return this.coords;},setTheme: function(theme){this.theme = theme;this.dirty = true;return this;},addAxis: function(name, kwArgs){var axis;if(!kwArgs || !("type" in kwArgs)){axis = new dc.axis2d.Default(this, kwArgs);}else{axis = typeof kwArgs.type == "string" ?new dc.axis2d[kwArgs.type](this, kwArgs) :new kwArgs.type(this, kwArgs);}axis.name = name;axis.dirty = true;if(name in this.axes){this.axes[name].destroy();}this.axes[name] = axis;this.dirty = true;return this;},addPlot: function(name, kwArgs){var plot;if(!kwArgs || !("type" in kwArgs)){plot = new dc.plot2d.Default(this, kwArgs);}else{plot = typeof kwArgs.type == "string" ?new dc.plot2d[kwArgs.type](this, kwArgs) :new kwArgs.type(this, kwArgs);}plot.name = name;plot.dirty = true;if(name in this.plots){this.stack[this.plots[name]].destroy();this.stack[this.plots[name]] = plot;}else{this.plots[name] = this.stack.length;this.stack.push(plot);}this.dirty = true;return this;},addSeries: function(name, data, kwArgs){var run = new dc.Series(this, data, kwArgs);if(name in this.runs){this.series[this.runs[name]].destroy();this.series[this.runs[name]] = run;}else{this.runs[name] = this.series.length;this.series.push(run);}this.dirty = true;// fix min/maxif(!("ymin" in run) && "min" in run){ run.ymin = run.min; }if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }return this;},updateSeries: function(name, data){if(name in this.runs){var run = this.series[this.runs[name]],plot = this.stack[this.plots[run.plot]], axis;run.data = data;run.dirty = true;// check to see if axes and plot should be updatedif(plot.hAxis){axis = this.axes[plot.hAxis];if(axis.dependOnData()){axis.dirty = true;// find all plots and mark them dirtydojo.forEach(this.stack, function(p){if(p.hAxis && p.hAxis == plot.hAxis){p.dirty = true;}});}}else{plot.dirty = true;}if(plot.vAxis){axis = this.axes[plot.vAxis];if(axis.dependOnData()){axis.dirty = true;// find all plots and mark them dirtydojo.forEach(this.stack, function(p){if(p.vAxis && p.vAxis == plot.vAxis){p.dirty = true;}});}}else{plot.dirty = true;}}return this;},resize: function(width, height){var box;switch(arguments.length){case 0:box = dojo.marginBox(this.node);break;case 1:box = width;break;default:box = {w: width, h: height};break;}dojo.marginBox(this.node, box);this.surface.setDimensions(box.w, box.h);this.dirty = true;this.coords = null;return this.render();},render: function(){if(this.dirty){return this.fullRender();}// calculate geometrydojo.forEach(this.stack, function(plot){if(plot.dirty || (plot.hAxis && this.axes[plot.hAxis].dirty) ||(plot.vAxis && this.axes[plot.vAxis].dirty)){plot.calculateAxes(this.plotArea);}}, this);// go over the stack backwardsdf.forEachReversed(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);// go over axesdf.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);this._makeClean();// BEGIN FOR HTML CANVASif(this.surface.render){ this.surface.render(); };// END FOR HTML CANVASreturn this;},fullRender: function(){this._makeDirty();// clear old valuesdojo.forEach(this.stack, clear);dojo.forEach(this.series, purge);df.forIn(this.axes, purge);dojo.forEach(this.stack, purge);this.surface.clear();// rebuild new connections, and add defaults// assign seriesdojo.forEach(this.series, function(run){if(!(run.plot in this.plots)){var plot = new dc.plot2d.Default(this, {});plot.name = run.plot;this.plots[run.plot] = this.stack.length;this.stack.push(plot);}this.stack[this.plots[run.plot]].addSeries(run);}, this);// assign axesdojo.forEach(this.stack, function(plot){if(plot.hAxis){plot.setAxis(this.axes[plot.hAxis]);}if(plot.vAxis){plot.setAxis(this.axes[plot.vAxis]);}}, this);// set up a themeif(!this.theme){this.theme = new dojox.charting.Theme(dojox.charting._def);}var requiredColors = df.foldl(this.stack, "z + plot.getRequiredColors()", 0);this.theme.defineColors({num: requiredColors, cache: false});// calculate geometry// 1st passvar dim = this.dim = this.surface.getDimensions();dim.width = dojox.gfx.normalizedLength(dim.width);dim.height = dojox.gfx.normalizedLength(dim.height);df.forIn(this.axes, clear);dojo.forEach(this.stack, function(plot){ plot.calculateAxes(dim); });// assumption: we don't have stacked axes yetvar offsets = this.offsets = {l: 0, r: 0, t: 0, b: 0};df.forIn(this.axes, function(axis){df.forIn(axis.getOffsets(), function(o, i){ offsets[i] += o; });});// add marginsdf.forIn(this.margins, function(o, i){ offsets[i] += o; });// 2nd pass with realistic dimensionsthis.plotArea = {width: dim.width - offsets.l - offsets.r, height: dim.height - offsets.t - offsets.b};df.forIn(this.axes, clear);dojo.forEach(this.stack, function(plot){ plot.calculateAxes(this.plotArea); }, this);// generate shapes// draw a chart backgroundvar t = this.theme,fill = this.fill ? this.fill : (t.chart && t.chart.fill),stroke = this.stroke ? this.stroke : (t.chart && t.chart.stroke);if(fill){this.surface.createRect({width: dim.width,height: dim.height}).setFill(fill);}if(stroke){this.surface.createRect({width: dim.width - 1,height: dim.height - 1}).setStroke(stroke);}// draw a plot backgroundfill = t.plotarea && t.plotarea.fill;stroke = t.plotarea && t.plotarea.stroke;if(fill){this.surface.createRect({x: offsets.l, y: offsets.t,width: dim.width - offsets.l - offsets.r,height: dim.height - offsets.t - offsets.b}).setFill(fill);}if(stroke){this.surface.createRect({x: offsets.l, y: offsets.t,width: dim.width - offsets.l - offsets.r - 1,height: dim.height - offsets.t - offsets.b - 1}).setStroke(stroke);}// go over the stack backwardsdf.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);// go over axesdf.forIn(this.axes, function(axis){ axis.render(dim, offsets); });this._makeClean();return this;},_makeClean: function(){// reset dirty flagsdojo.forEach(this.axes, makeClean);dojo.forEach(this.stack, makeClean);dojo.forEach(this.series, makeClean);this.dirty = false;},_makeDirty: function(){// reset dirty flagsdojo.forEach(this.axes, makeDirty);dojo.forEach(this.stack, makeDirty);dojo.forEach(this.series, makeDirty);this.dirty = true;}});})();}