dojox/charting/Chart.js

  • Provides:

    • dojox.charting.Chart
  • Requires:

    • dojox.gfx in common
    • dojox.lang.functional in common
    • dojox.lang.functional.fold in common
    • dojox.lang.functional.reversed in common
    • dojox.charting.Element in common
    • dojox.charting.Theme in common
    • dojox.charting.Series in common
    • dojox.charting.axis2d.common in common
  • dojox.charting.Chart

    • type
      Function
    • summary
      The constructor for a new Chart.  Initializes all parameters used for a chart.
    • description
      dojox.charting.Chart is the primary object used for any kind of charts.  It
      is simple to create--just pass it a node reference, which is used as the
      container for the chart--and a set of optional keyword arguments and go.
      
      Note that like most of dojox.gfx, most of dojox.charting.Chart's methods are
      designed to return a reference to the chart itself, to allow for functional
      chaining.  This makes defining everything on a Chart very easy to do.
    • example
      Create an area chart, with smoothing.
      
      	new dojox.charting.Chart(node))
      		.addPlot("default", { type: "Areas", tension: "X" })
      		.setTheme(dojox.charting.themes.Shrooms)
      		.addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
      		.addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
      		.addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
      		.render();
    • example
      The form of data in a data series can take a number of forms: a simple array,
      an array of objects {x,y}, or something custom (as determined by the plot).
      Here's an example of a Candlestick chart, which expects an object of
      { open, high, low, close }.
      
      	new dojox.charting.Chart(node))
      		.addPlot("default", {type: "Candlesticks", gap: 1})
      		.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
      		.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
      		.addSeries("Series A", [
      				{ open: 20, close: 16, high: 22, low: 8 },
      				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
      				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
      				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
      				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
      				{ open: 24, close: 8, high: 24, low: 5 },
      				{ open: 8, close: 16, high: 22, low: 2 },
      				{ open: 16, close: 12, high: 19, low: 7 },
      				{ open: 12, close: 20, high: 22, low: 8 },
      				{ open: 20, close: 16, high: 22, low: 8 },
      				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
      				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
      				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
      				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
      				{ open: 24, close: 8, high: 24, low: 5 },
      				{ open: 8, close: 16, high: 22, low: 2 },
      				{ open: 16, close: 12, high: 19, low: 7 },
      				{ open: 12, close: 20, high: 22, low: 8 },
      				{ open: 20, close: 16, high: 22, low: 8 },
      				{ open: 16, close: 22, high: 26, low: 6 },
      				{ open: 22, close: 18, high: 22, low: 11 },
      				{ open: 18, close: 29, high: 32, low: 14 },
      				{ open: 29, close: 24, high: 29, low: 13 },
      				{ open: 24, close: 8, high: 24, low: 5 },
      				{ open: 8, close: 16, high: 22, low: 2 },
      				{ open: 16, close: 12, high: 19, low: 7 },
      				{ open: 12, close: 20, high: 22, low: 8 },
      				{ open: 20, close: 16, high: 22, low: 8 }
      			],
      			{ stroke: { color: "green" }, fill: "lightgreen" }
      		)
      		.render();
      
      
      theme: dojox.charting.Theme?
      An optional theme to use for styling the chart.
      axes: dojox.charting.Axis{}?
      A map of axes for use in plotting a chart.
      stack: dojox.charting.plot2d.Base[]
      A stack of plotters.
      plots: dojox.charting.plot2d.Base{}
      A map of plotter indices
      series: dojox.charting.Series[]
      The stack of data runs used to create plots.
      runs: dojox.charting.Series{}
      A map of series indices
      margins: Object?
      The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
      stroke: dojox.gfx.Stroke?
      The outline of the chart (stroke in vector graphics terms).
      fill: dojox.gfx.Fill?
      The color for the chart.
      node: DOMNode
      The container node passed to the constructor.
      surface: dojox.gfx.Surface
      The main graphics surface upon which a chart is drawn.
      dirty: Boolean
      A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
      coords: Object
      The coordinates on a page of the containing node, as returned from dojo.coords.
    • parameters:
      • node: (typeof DOMNode)
      • kwArgs: (typeof dojox.charting.__ChartCtorArgs)
    • source: [view]
      dojo.provide("dojox.charting.Chart");


      dojo.require("dojox.gfx");
      dojo.require("dojox.lang.functional");
      dojo.require("dojox.lang.functional.fold");
      dojo.require("dojox.lang.functional.reversed");


      dojo.require("dojox.charting.Element");
      dojo.require("dojox.charting.Theme");
      dojo.require("dojox.charting.Series");
      dojo.require("dojox.charting.axis2d.common");




      dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
       // summary:
       //  The keyword arguments that can be passed in a Chart constructor.
       //
       // margins: Object?
       //  Optional margins for the chart, in the form of { l, t, r, b}.
       // stroke: dojox.gfx.Stroke?
       //  An optional outline/stroke for the chart.
       // fill: dojox.gfx.Fill?
       //  An optional fill for the chart.
       // delayInMs: Number
       //  Delay in ms for delayedRender(). Default: 200.
       this.margins = margins;
       this.stroke = stroke;
       this.fill = fill;
       this.delayInMs = delayInMs;
      }


      (function(){
       var df = dojox.lang.functional, dc = dojox.charting, g = dojox.gfx,
        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"),
        getName = df.lambda("item.name");


       dojo.declare("dojox.charting.Chart", null, {
        // summary:
        //  The main chart object in dojox.charting. This will create a two dimensional
        //  chart based on dojox.gfx.
        //
        // description:
        //  dojox.charting.Chart is the primary object used for any kind of charts. It
        //  is simple to create--just pass it a node reference, which is used as the
        //  container for the chart--and a set of optional keyword arguments and go.
        //
        //  Note that like most of dojox.gfx, most of dojox.charting.Chart's methods are
        //  designed to return a reference to the chart itself, to allow for functional
        //  chaining. This makes defining everything on a Chart very easy to do.
        //
        // example:
        //  Create an area chart, with smoothing.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", { type: "Areas", tension: "X" })
        // |  .setTheme(dojox.charting.themes.Shrooms)
        // |  .addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
        // |  .addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
        // |  .addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
        // |  .render();
        //
        // example:
        //  The form of data in a data series can take a number of forms: a simple array,
        //  an array of objects {x,y}, or something custom (as determined by the plot).
        //  Here's an example of a Candlestick chart, which expects an object of
        //  { open, high, low, close }.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", {type: "Candlesticks", gap: 1})
        // |  .addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
        // |  .addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
        // |  .addSeries("Series A", [
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6 },
        // |    { open: 22, close: 18, high: 22, low: 11 },
        // |    { open: 18, close: 29, high: 32, low: 14 },
        // |    { open: 29, close: 24, high: 29, low: 13 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 }
        // |   ],
        // |   { stroke: { color: "green" }, fill: "lightgreen" }
        // |  )
        // |  .render();
        //
        // theme: dojox.charting.Theme?
        //  An optional theme to use for styling the chart.
        // axes: dojox.charting.Axis{}?
        //  A map of axes for use in plotting a chart.
        // stack: dojox.charting.plot2d.Base[]
        //  A stack of plotters.
        // plots: dojox.charting.plot2d.Base{}
        //  A map of plotter indices
        // series: dojox.charting.Series[]
        //  The stack of data runs used to create plots.
        // runs: dojox.charting.Series{}
        //  A map of series indices
        // margins: Object?
        //  The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
        // stroke: dojox.gfx.Stroke?
        //  The outline of the chart (stroke in vector graphics terms).
        // fill: dojox.gfx.Fill?
        //  The color for the chart.
        // node: DOMNode
        //  The container node passed to the constructor.
        // surface: dojox.gfx.Surface
        //  The main graphics surface upon which a chart is drawn.
        // dirty: Boolean
        //  A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
        // coords: Object
        //  The coordinates on a page of the containing node, as returned from dojo.coords.


        constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
         // summary:
         //  The constructor for a new Chart. Initializes all parameters used for a chart.
         // returns: dojox.charting.Chart
         //  The newly created chart.


         // initialize parameters
         if(!kwArgs){ kwArgs = {}; }
         this.margins = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
         this.stroke = kwArgs.stroke;
         this.fill = kwArgs.fill;
         this.delayInMs = kwArgs.delayInMs || 200;
         this.title = kwArgs.title;
         this.titleGap = kwArgs.titleGap;
         this.titlePos = kwArgs.titlePos;
         this.titleFont = kwArgs.titleFont;
         this.titleFontColor = kwArgs.titleFontColor;
         this.chartTitle = null;


         // default initialization
         this.theme = null;
         this.axes = {};  // map of axes
         this.stack = []; // stack of plotters
         this.plots = {}; // map of plotter indices
         this.series = []; // stack of data runs
         this.runs = {};  // map of data run indices
         this.dirty = true;
         this.coords = null;


         // create a surface
         this.node = dojo.byId(node);
         var box = dojo.marginBox(node);
         this.surface = g.createSurface(this.node, box.w || 400, box.h || 300);
  • dojox.charting.Chart.destroy

    • type
      Function
    • source: [view]
         dojo.forEach(this.series, destroy);
         dojo.forEach(this.stack, destroy);
         df.forIn(this.axes, destroy);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.destroy();
    • summary
      Cleanup when a chart is to be destroyed.
    • return_summary
      void
  • dojox.charting.Chart.getCoords

    • type
      Function
    • source: [view]
         if(!this.coords){
          this.coords = dojo.coords(this.node, true);
         }
         return this.coords; // Object
    • summary
      Get the coordinates and dimensions of the containing DOMNode, as
      returned by dojo.coords.
    • return_summary
      Object
      The resulting coordinates of the chart.  See dojo.coords for details.
    • returns
      Object
  • dojox.charting.Chart.setTheme

    • type
      Function
    • parameters:
      • theme: (typeof dojox.charting.Theme)
        The theme to be used for visual rendering.
    • source: [view]
         this.theme = theme.clone();
         this.dirty = true;
         return this; // dojox.charting.Chart
    • summary
      Set a theme of the chart.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.addAxis

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the axis.
      • kwArgs: (typeof dojox.charting.axis2d.__AxisCtorArgs)
        An optional keyword arguments object for use in defining details of an axis.
    • source: [view]
      var axis, axisType = kwArgs && kwArgs.type || "Default";
      if(typeof axisType == "string"){
      if(!dc.axis2d || !dc.axis2d[axisType]){
      throw Error("Can't find axis: " + axisType + " - didn't you forget to dojo" + ".require() it?");
      }
      axis = new dc.axis2d[axisType](this, kwArgs);
      }else{
      axis = new axisType(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; // dojox.charting.Chart
    • summary
      Add an axis to the chart, for rendering.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.getAxis

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name the axis was defined by.
    • source: [view]
         return this.axes[name]; // dojox.charting.axis2d.Default
    • summary
      Get the given axis, by name.
    • return_summary
      dojox.charting.axis2d.Default
      The axis as stored in the chart's axis map.
    • returns
      dojox.charting.axis2d.Default
  • dojox.charting.Chart.removeAxis

    • type
      Function
    • parameters:
      • name: (typeof String)
        The axis name, as defined in addAxis.
    • source: [view]
         if(name in this.axes){
          // destroy the axis
          this.axes[name].destroy();
          delete this.axes[name];
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
    • summary
      Remove the axis that was defined using name.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.addPlot

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the plot to be added to the chart.  If you only plan on using one plot, call it "default".
      • kwArgs: (typeof dojox.charting.plot2d.__PlotCtorArgs)
        An object with optional parameters for the plot in question.
    • source: [view]
         var plot, plotType = kwArgs && kwArgs.type || "Default";
      if(typeof plotType == "string"){
      if(!dc.plot2d || !dc.plot2d[plotType]){
      throw Error("Can't find plot: " + plotType + " - didn't you forget to dojo" + ".require() it?");
      }
      plot = new dc.plot2d[plotType](this, kwArgs);
      }else{
      plot = new plotType(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; // dojox.charting.Chart
    • summary
      Add a new plot to the chart, defined by name and using the optional keyword arguments object.
      Note that dojox.charting assumes the main plot to be called "default"; if you do not have
      a plot called "default" and attempt to add data series to the chart without specifying the
      plot to be rendered on, you WILL get errors.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.removePlot

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the plot as defined using addPlot.
    • source: [view]
         if(name in this.plots){
          // get the index and remove the name
          var index = this.plots[name];
          delete this.plots[name];
          // destroy the plot
          this.stack[index].destroy();
          // remove the plot from the stack
          this.stack.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.plots, function(idx, name, plots){
           if(idx > index){
            plots[name] = idx - 1;
           }
          });
      // remove all related series
      var ns = dojo.filter(this.series, function(run){ return run.plot != name; });
      if(ns.length < this.series.length){
      // kill all removed series
      dojo.forEach(this.series, function(run){
      if(run.plot == name){
      run.destroy();
      }
      });
      // rebuild all necessary data structures
      this.runs = {};
      dojo.forEach(ns, function(run, index){
      this.runs[run.plot] = index;
      }, this);
      this.series = ns;
      }
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
    • summary
      Remove the plot defined using name from the chart's plot stack.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.getPlotOrder

    • type
      Function
    • source: [view]
         return df.map(this.stack, getName); // Array
    • summary
      Returns an array of plot names in the current order
      (the top-most plot is the first).
    • return_summary
      Array
    • returns
      Array
  • dojox.charting.Chart.setPlotOrder

    • type
      Function
    • parameters:
      • newOrder: (typeof Array)
        Array of plot names compatible with getPlotOrder().
    • source: [view]
         var names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.plots) || (name in names)){
            return false;
           }
           names[name] = 1;
           return true;
          }, this);
         if(order.length < this.stack.length){
          df.forEach(this.stack, function(plot){
           var name = plot.name;
           if(!(name in names)){
            order.push(name);
           }
          });
         }
         var newStack = df.map(order, function(name){
           return this.stack[this.plots[name]];
          }, this);
         df.forEach(newStack, function(plot, i){
          this.plots[plot.name] = i;
         }, this);
         this.stack = newStack;
         this.dirty = true;
         return this; // dojox.charting.Chart
    • summary
      Sets new order of plots. newOrder cannot add or remove
      plots. Wrong names, or dups are ignored.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.movePlotToFront

    • type
      Function
    • parameters:
      • name: (typeof String)
        Plot's name to move.
    • source: [view]
         if(name in this.plots){
          var index = this.plots[name];
          if(index){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
    • summary
      Moves a given plot to front.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.movePlotToBack

    • type
      Function
    • parameters:
      • name: (typeof String)
        Plot's name to move.
    • source: [view]
         if(name in this.plots){
          var index = this.plots[name];
          if(index < this.stack.length - 1){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
    • summary
      Moves a given plot to back.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.addSeries

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the data series to be plotted.
      • data: (typeof Array|Object)
        The array of data points (either numbers or objects) that
        represents the data to be drawn. Or it can be an object. In
        the latter case, it should have a property &quot;data&quot; (an array),
        destroy(), and setSeriesObject().
      • kwArgs: (typeof dojox.charting.__SeriesCtorArgs)
        An optional keyword arguments object that will be mixed into
        the resultant series object.
    • source: [view]
         var run = new dc.Series(this, data, kwArgs);
         run.name = name;
         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/max
         if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
         if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
         return this; // dojox.charting.Chart
    • summary
      Add a data series to the chart for rendering.
    • return_summary
      dojox.charting.Chart:
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.removeSeries

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the series as defined by addSeries.
    • source: [view]
         if(name in this.runs){
          // get the index and remove the name
          var index = this.runs[name];
          delete this.runs[name];
          // destroy the run
          this.series[index].destroy();
          // remove the run from the stack of series
          this.series.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.runs, function(idx, name, runs){
           if(idx > index){
            runs[name] = idx - 1;
           }
          });
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
    • summary
      Remove the series defined by name from the chart.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.updateSeries

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the series as defined in addSeries.
      • data: (typeof Array|Object)
        The array of data points (either numbers or objects) that
        represents the data to be drawn. Or it can be an object. In
        the latter case, it should have a property &quot;data&quot; (an array),
        destroy(), and setSeriesObject().
    • source: [view]
         if(name in this.runs){
          var run = this.series[this.runs[name]];
          run.update(data);
          this._invalidateDependentPlots(run.plot, false);
          this._invalidateDependentPlots(run.plot, true);
         }
         return this; // dojox.charting.Chart
    • summary
      Update the given series with a new set of data points.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.getSeriesOrder

    • type
      Function
    • parameters:
      • plotName: (typeof String)
        Plot's name.
    • source: [view]
         return df.map(df.filter(this.series, function(run){
           return run.plot == plotName;
          }), getName);
    • summary
      Returns an array of series names in the current order
      (the top-most series is the first) within a plot.
    • return_summary
      Array
  • dojox.charting.Chart.setSeriesOrder

    • type
      Function
    • parameters:
      • newOrder: (typeof Array)
        Array of series names compatible with getPlotOrder(). All
        series should belong to the same plot.
    • source: [view]
         var plotName, names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.runs) || (name in names)){
            return false;
           }
           var run = this.series[this.runs[name]];
           if(plotName){
            if(run.plot != plotName){
             return false;
            }
           }else{
            plotName = run.plot;
           }
           names[name] = 1;
           return true;
          }, this);
         df.forEach(this.series, function(run){
          var name = run.name;
          if(!(name in names) && run.plot == plotName){
           order.push(name);
          }
         });
         var newSeries = df.map(order, function(name){
           return this.series[this.runs[name]];
          }, this);
         this.series = newSeries.concat(df.filter(this.series, function(run){
          return run.plot != plotName;
         }));
         df.forEach(this.series, function(run, i){
          this.runs[run.name] = i;
         }, this);
         this.dirty = true;
         return this; // dojox.charting.Chart
    • summary
      Sets new order of series within a plot. newOrder cannot add
      or remove series. Wrong names, or dups are ignored.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.moveSeriesToFront

    • type
      Function
    • parameters:
      • name: (typeof String)
        Series' name to move.
    • source: [view]
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[0]){
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
    • summary
      Moves a given series to front of a plot.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.moveSeriesToBack

    • type
      Function
    • parameters:
      • name: (typeof String)
        Series' name to move.
    • source: [view]
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[newOrder.length - 1]){
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
    • summary
      Moves a given series to back of a plot.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.resize

    • type
      Function
    • parameters:
      • width: (typeof Number)
        The new width of the chart.
      • height: (typeof Number)
        The new height of the chart.
    • source: [view]
         var box;
         switch(arguments.length){
          // case 0, do not resize the div, just the surface
          case 1:
           // argument, override node box
           box = dojo.mixin({}, width);
           dojo.marginBox(this.node, box);
           break;
          case 2:
           box = {w: width, h: height};
           // argument, override node box
           dojo.marginBox(this.node, box);
           break;
         }
         // in all cases take back the computed box
         box = dojo.marginBox(this.node);
         // and set it on the surface
         this.surface.setDimensions(box.w, box.h);
         this.dirty = true;
         this.coords = null;
         return this.render(); // dojox.charting.Chart
    • summary
      Resize the chart to the dimensions of width and height.
    • description
      Resize the chart and its surface to the width and height dimensions.
      If no width/height or box is provided, resize the surface to the marginBox of the chart.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.getGeometry

    • type
      Function
    • source: [view]
         var ret = {};
         df.forIn(this.axes, function(axis){
          if(axis.initialized()){
           ret[axis.name] = {
            name:  axis.name,
            vertical: axis.vertical,
            scaler:  axis.scaler,
            ticks:  axis.ticks
           };
          }
         });
         return ret; // Object
    • summary
      Returns a map of information about all axes in a chart and what they represent
      in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
    • return_summary
      Object
      An map of geometry objects, a one-to-one mapping of axes.
    • returns
      Object
  • dojox.charting.Chart.setAxisWindow

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the axis as defined by addAxis.
      • scale: (typeof Number)
        The scale on the target axis.
      • offset: (typeof Number)
        Any offest, as measured by axis tick
      • zoom: (typeof Boolean|Object)
        The chart zooming animation trigger.  This is null by default,
        e.g. {duration: 1200}, or just set true.
    • source: [view]
         var axis = this.axes[name];
         if(axis){
          axis.setWindow(scale, offset);
          dojo.forEach(this.stack,function(plot){
           if(plot.hAxis == name || plot.vAxis == name){
            plot.zoom = zoom;
           }
          })
         }
         return this; // dojox.charting.Chart
    • summary
      Zooms an axis and all dependent plots. Can be used to zoom in 1D.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.setWindow

    • type
      Function
    • parameters:
      • sx: (typeof Number)
        The scale for the x axis.
      • sy: (typeof Number)
        The scale for the y axis.
      • dx: (typeof Number)
        The pixel offset on the x axis.
      • dy: (typeof Number)
        The pixel offset on the y axis.
      • zoom: (typeof Boolean|Object)
        The chart zooming animation trigger.  This is null by default,
        e.g. {duration: 1200}, or just set true.
    • source: [view]
         if(!("plotArea" in this)){
          this.calculateGeometry();
         }
         df.forIn(this.axes, function(axis){
          var scale, offset, bounds = axis.getScaler().bounds,
           s = bounds.span / (bounds.upper - bounds.lower);
          if(axis.vertical){
           scale = sy;
           offset = dy / s / scale;
          }else{
           scale = sx;
           offset = dx / s / scale;
          }
          axis.setWindow(scale, offset);
         });
         dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
         return this; // dojox.charting.Chart
    • summary
      Zooms in or out any plots in two dimensions.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.zoomIn

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the axis as defined by addAxis.
      • range: (typeof Array)
        The end points of the zoom range, measured in axis ticks.
    • source: [view]
         var axis = this.axes[name];
         if(axis){
          var scale, offset, bounds = axis.getScaler().bounds;
          var lower = Math.min(range[0],range[1]);
          var upper = Math.max(range[0],range[1]);
          lower = range[0] < bounds.lower ? bounds.lower : lower;
          upper = range[1] > bounds.upper ? bounds.upper : upper;
          scale = (bounds.upper - bounds.lower) / (upper - lower);
          offset = lower - bounds.lower;
          this.setAxisWindow(name, scale, offset);
          this.render();
         }
    • summary
      Zoom the chart to a specific range on one axis.  This calls render()
      directly as a convenience method.
  • dojox.charting.Chart.calculateGeometry

    • type
      Function
    • source: [view]
         if(this.dirty){
          return this.fullGeometry();
         }


         // calculate geometry
         var dirty = dojo.filter(this.stack, function(plot){
           return plot.dirty ||
            (plot.hAxis && this.axes[plot.hAxis].dirty) ||
            (plot.vAxis && this.axes[plot.vAxis].dirty);
          }, this);
         calculateAxes(dirty, this.plotArea);


         return this; // dojox.charting.Chart
    • summary
      Calculate the geometry of the chart based on the defined axes of
      a chart.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.fullGeometry

    • type
      Function
    • source: [view]
         this._makeDirty();


         // clear old values
         dojo.forEach(this.stack, clear);


         // rebuild new connections, and add defaults


         // set up a theme
         if(!this.theme){
          this.setTheme(new dojox.charting.Theme(dojox.charting._def));
         }


         // assign series
         dojo.forEach(this.series, function(run){
          if(!(run.plot in this.plots)){
      if(!dc.plot2d || !dc.plot2d.Default){
      throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
      }
           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 axes
         dojo.forEach(this.stack, function(plot){
          if(plot.hAxis){
           plot.setAxis(this.axes[plot.hAxis]);
          }
          if(plot.vAxis){
           plot.setAxis(this.axes[plot.vAxis]);
          }
         }, this);


         // calculate geometry


         // 1st pass
         var dim = this.dim = this.surface.getDimensions();
         dim.width = g.normalizedLength(dim.width);
         dim.height = g.normalizedLength(dim.height);
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, dim);


         // assumption: we don't have stacked axes yet
         var 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 title area
         if(this.title){
          this.titleGap = (this.titleGap==0) ? 0 : this.titleGap || this.theme.chart.titleGap || 20;
          this.titlePos = this.titlePos || this.theme.chart.titlePos || "top";
          this.titleFont = this.titleFont || this.theme.chart.titleFont;
          this.titleFontColor = this.titleFontColor || this.theme.chart.titleFontColor || "black";
          var tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
         }
         // add margins
         df.forIn(this.margins, function(o, i){ offsets[i] += o; });


         // 2nd pass with realistic dimensions
         this.plotArea = {
          width: dim.width - offsets.l - offsets.r,
          height: dim.height - offsets.t - offsets.b
         };
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, this.plotArea);


         return this; // dojox.charting.Chart
    • summary
      Calculate the full geometry of the chart.  This includes passing
      over all major elements of a chart (plots, axes, series, container)
      in order to ensure proper rendering.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.render

    • type
      Function
    • source: [view]
         if(this.theme){
          this.theme.clear();
         }


         if(this.dirty){
          return this.fullRender();
         }


         this.calculateGeometry();


         // go over the stack backwards
         df.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
    • summary
      Render the chart according to the current information defined.  This should
      be the last call made when defining/creating a chart, or if data within the
      chart has been changed.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.fullRender

    • type
      Function
    • source: [view]
      dojo.provide("dojox.charting.Chart");


      dojo.require("dojox.gfx");
      dojo.require("dojox.lang.functional");
      dojo.require("dojox.lang.functional.fold");
      dojo.require("dojox.lang.functional.reversed");


      dojo.require("dojox.charting.Element");
      dojo.require("dojox.charting.Theme");
      dojo.require("dojox.charting.Series");
      dojo.require("dojox.charting.axis2d.common");




      dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
       // summary:
       //  The keyword arguments that can be passed in a Chart constructor.
       //
       // margins: Object?
       //  Optional margins for the chart, in the form of { l, t, r, b}.
       // stroke: dojox.gfx.Stroke?
       //  An optional outline/stroke for the chart.
       // fill: dojox.gfx.Fill?
       //  An optional fill for the chart.
       // delayInMs: Number
       //  Delay in ms for delayedRender(). Default: 200.
       this.margins = margins;
       this.stroke = stroke;
       this.fill = fill;
       this.delayInMs = delayInMs;
      }


      (function(){
       var df = dojox.lang.functional, dc = dojox.charting, g = dojox.gfx,
        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"),
        getName = df.lambda("item.name");


       dojo.declare("dojox.charting.Chart", null, {
        // summary:
        //  The main chart object in dojox.charting. This will create a two dimensional
        //  chart based on dojox.gfx.
        //
        // description:
        //  dojox.charting.Chart is the primary object used for any kind of charts. It
        //  is simple to create--just pass it a node reference, which is used as the
        //  container for the chart--and a set of optional keyword arguments and go.
        //
        //  Note that like most of dojox.gfx, most of dojox.charting.Chart's methods are
        //  designed to return a reference to the chart itself, to allow for functional
        //  chaining. This makes defining everything on a Chart very easy to do.
        //
        // example:
        //  Create an area chart, with smoothing.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", { type: "Areas", tension: "X" })
        // |  .setTheme(dojox.charting.themes.Shrooms)
        // |  .addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
        // |  .addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
        // |  .addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
        // |  .render();
        //
        // example:
        //  The form of data in a data series can take a number of forms: a simple array,
        //  an array of objects {x,y}, or something custom (as determined by the plot).
        //  Here's an example of a Candlestick chart, which expects an object of
        //  { open, high, low, close }.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", {type: "Candlesticks", gap: 1})
        // |  .addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
        // |  .addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
        // |  .addSeries("Series A", [
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6 },
        // |    { open: 22, close: 18, high: 22, low: 11 },
        // |    { open: 18, close: 29, high: 32, low: 14 },
        // |    { open: 29, close: 24, high: 29, low: 13 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 }
        // |   ],
        // |   { stroke: { color: "green" }, fill: "lightgreen" }
        // |  )
        // |  .render();
        //
        // theme: dojox.charting.Theme?
        //  An optional theme to use for styling the chart.
        // axes: dojox.charting.Axis{}?
        //  A map of axes for use in plotting a chart.
        // stack: dojox.charting.plot2d.Base[]
        //  A stack of plotters.
        // plots: dojox.charting.plot2d.Base{}
        //  A map of plotter indices
        // series: dojox.charting.Series[]
        //  The stack of data runs used to create plots.
        // runs: dojox.charting.Series{}
        //  A map of series indices
        // margins: Object?
        //  The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
        // stroke: dojox.gfx.Stroke?
        //  The outline of the chart (stroke in vector graphics terms).
        // fill: dojox.gfx.Fill?
        //  The color for the chart.
        // node: DOMNode
        //  The container node passed to the constructor.
        // surface: dojox.gfx.Surface
        //  The main graphics surface upon which a chart is drawn.
        // dirty: Boolean
        //  A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
        // coords: Object
        //  The coordinates on a page of the containing node, as returned from dojo.coords.


        constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
         // summary:
         //  The constructor for a new Chart. Initializes all parameters used for a chart.
         // returns: dojox.charting.Chart
         //  The newly created chart.


         // initialize parameters
         if(!kwArgs){ kwArgs = {}; }
         this.margins = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
         this.stroke = kwArgs.stroke;
         this.fill = kwArgs.fill;
         this.delayInMs = kwArgs.delayInMs || 200;
         this.title = kwArgs.title;
         this.titleGap = kwArgs.titleGap;
         this.titlePos = kwArgs.titlePos;
         this.titleFont = kwArgs.titleFont;
         this.titleFontColor = kwArgs.titleFontColor;
         this.chartTitle = null;


         // default initialization
         this.theme = null;
         this.axes = {};  // map of axes
         this.stack = []; // stack of plotters
         this.plots = {}; // map of plotter indices
         this.series = []; // stack of data runs
         this.runs = {};  // map of data run indices
         this.dirty = true;
         this.coords = null;


         // create a surface
         this.node = dojo.byId(node);
         var box = dojo.marginBox(node);
         this.surface = g.createSurface(this.node, box.w || 400, box.h || 300);
        },
        destroy: function(){
         // summary:
         //  Cleanup when a chart is to be destroyed.
         // returns: void
         dojo.forEach(this.series, destroy);
         dojo.forEach(this.stack, destroy);
         df.forIn(this.axes, destroy);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.destroy();
        },
        getCoords: function(){
         // summary:
         //  Get the coordinates and dimensions of the containing DOMNode, as
         //  returned by dojo.coords.
         // returns: Object
         //  The resulting coordinates of the chart. See dojo.coords for details.
         if(!this.coords){
          this.coords = dojo.coords(this.node, true);
         }
         return this.coords; // Object
        },
        setTheme: function(theme){
         // summary:
         //  Set a theme of the chart.
         // theme: dojox.charting.Theme
         //  The theme to be used for visual rendering.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         this.theme = theme.clone();
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        addAxis: function(name, kwArgs){
         // summary:
         //  Add an axis to the chart, for rendering.
         // name: String
         //  The name of the axis.
         // kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
         //  An optional keyword arguments object for use in defining details of an axis.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
      var axis, axisType = kwArgs && kwArgs.type || "Default";
      if(typeof axisType == "string"){
      if(!dc.axis2d || !dc.axis2d[axisType]){
      throw Error("Can't find axis: " + axisType + " - didn't you forget to dojo" + ".require() it?");
      }
      axis = new dc.axis2d[axisType](this, kwArgs);
      }else{
      axis = new axisType(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; // dojox.charting.Chart
        },
        getAxis: function(name){
         // summary:
         //  Get the given axis, by name.
         // name: String
         //  The name the axis was defined by.
         // returns: dojox.charting.axis2d.Default
         //  The axis as stored in the chart's axis map.
         return this.axes[name]; // dojox.charting.axis2d.Default
        },
        removeAxis: function(name){
         // summary:
         //  Remove the axis that was defined using name.
         // name: String
         //  The axis name, as defined in addAxis.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.axes){
          // destroy the axis
          this.axes[name].destroy();
          delete this.axes[name];
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        addPlot: function(name, kwArgs){
         // summary:
         //  Add a new plot to the chart, defined by name and using the optional keyword arguments object.
         //  Note that dojox.charting assumes the main plot to be called "default"; if you do not have
         //  a plot called "default" and attempt to add data series to the chart without specifying the
         //  plot to be rendered on, you WILL get errors.
         // name: String
         //  The name of the plot to be added to the chart. If you only plan on using one plot, call it "default".
         // kwArgs: dojox.charting.plot2d.__PlotCtorArgs
         //  An object with optional parameters for the plot in question.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var plot, plotType = kwArgs && kwArgs.type || "Default";
      if(typeof plotType == "string"){
      if(!dc.plot2d || !dc.plot2d[plotType]){
      throw Error("Can't find plot: " + plotType + " - didn't you forget to dojo" + ".require() it?");
      }
      plot = new dc.plot2d[plotType](this, kwArgs);
      }else{
      plot = new plotType(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; // dojox.charting.Chart
        },
        removePlot: function(name){
         // summary:
         //  Remove the plot defined using name from the chart's plot stack.
         // name: String
         //  The name of the plot as defined using addPlot.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          // get the index and remove the name
          var index = this.plots[name];
          delete this.plots[name];
          // destroy the plot
          this.stack[index].destroy();
          // remove the plot from the stack
          this.stack.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.plots, function(idx, name, plots){
           if(idx > index){
            plots[name] = idx - 1;
           }
          });
      // remove all related series
      var ns = dojo.filter(this.series, function(run){ return run.plot != name; });
      if(ns.length < this.series.length){
      // kill all removed series
      dojo.forEach(this.series, function(run){
      if(run.plot == name){
      run.destroy();
      }
      });
      // rebuild all necessary data structures
      this.runs = {};
      dojo.forEach(ns, function(run, index){
      this.runs[run.plot] = index;
      }, this);
      this.series = ns;
      }
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        getPlotOrder: function(){
         // summary:
         //  Returns an array of plot names in the current order
         //  (the top-most plot is the first).
         // returns: Array
         return df.map(this.stack, getName); // Array
        },
        setPlotOrder: function(newOrder){
         // summary:
         //  Sets new order of plots. newOrder cannot add or remove
         //  plots. Wrong names, or dups are ignored.
         // newOrder: Array:
         //  Array of plot names compatible with getPlotOrder().
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.plots) || (name in names)){
            return false;
           }
           names[name] = 1;
           return true;
          }, this);
         if(order.length < this.stack.length){
          df.forEach(this.stack, function(plot){
           var name = plot.name;
           if(!(name in names)){
            order.push(name);
           }
          });
         }
         var newStack = df.map(order, function(name){
           return this.stack[this.plots[name]];
          }, this);
         df.forEach(newStack, function(plot, i){
          this.plots[plot.name] = i;
         }, this);
         this.stack = newStack;
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        movePlotToFront: function(name){
         // summary:
         //  Moves a given plot to front.
         // name: String:
         //  Plot's name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          var index = this.plots[name];
          if(index){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        movePlotToBack: function(name){
         // summary:
         //  Moves a given plot to back.
         // name: String:
         //  Plot's name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          var index = this.plots[name];
          if(index < this.stack.length - 1){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        addSeries: function(name, data, kwArgs){
         // summary:
         //  Add a data series to the chart for rendering.
         // name: String:
         //  The name of the data series to be plotted.
         // data: Array|Object:
         //  The array of data points (either numbers or objects) that
         //  represents the data to be drawn. Or it can be an object. In
         //  the latter case, it should have a property "data" (an array),
         //  destroy(), and setSeriesObject().
         // kwArgs: dojox.charting.__SeriesCtorArgs?:
         //  An optional keyword arguments object that will be mixed into
         //  the resultant series object.
         // returns: dojox.charting.Chart:
         //  A reference to the current chart for functional chaining.
         var run = new dc.Series(this, data, kwArgs);
         run.name = name;
         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/max
         if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
         if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
         return this; // dojox.charting.Chart
        },
        removeSeries: function(name){
         // summary:
         //  Remove the series defined by name from the chart.
         // name: String
         //  The name of the series as defined by addSeries.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          // get the index and remove the name
          var index = this.runs[name];
          delete this.runs[name];
          // destroy the run
          this.series[index].destroy();
          // remove the run from the stack of series
          this.series.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.runs, function(idx, name, runs){
           if(idx > index){
            runs[name] = idx - 1;
           }
          });
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        updateSeries: function(name, data){
         // summary:
         //  Update the given series with a new set of data points.
         // name: String
         //  The name of the series as defined in addSeries.
         // data: Array|Object:
         //  The array of data points (either numbers or objects) that
         //  represents the data to be drawn. Or it can be an object. In
         //  the latter case, it should have a property "data" (an array),
         //  destroy(), and setSeriesObject().
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var run = this.series[this.runs[name]];
          run.update(data);
          this._invalidateDependentPlots(run.plot, false);
          this._invalidateDependentPlots(run.plot, true);
         }
         return this; // dojox.charting.Chart
        },
        getSeriesOrder: function(plotName){
         // summary:
         //  Returns an array of series names in the current order
         //  (the top-most series is the first) within a plot.
         // plotName: String:
         //  Plot's name.
         // returns: Array
         return df.map(df.filter(this.series, function(run){
           return run.plot == plotName;
          }), getName);
        },
        setSeriesOrder: function(newOrder){
         // summary:
         //  Sets new order of series within a plot. newOrder cannot add
         //  or remove series. Wrong names, or dups are ignored.
         // newOrder: Array:
         //  Array of series names compatible with getPlotOrder(). All
         //  series should belong to the same plot.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var plotName, names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.runs) || (name in names)){
            return false;
           }
           var run = this.series[this.runs[name]];
           if(plotName){
            if(run.plot != plotName){
             return false;
            }
           }else{
            plotName = run.plot;
           }
           names[name] = 1;
           return true;
          }, this);
         df.forEach(this.series, function(run){
          var name = run.name;
          if(!(name in names) && run.plot == plotName){
           order.push(name);
          }
         });
         var newSeries = df.map(order, function(name){
           return this.series[this.runs[name]];
          }, this);
         this.series = newSeries.concat(df.filter(this.series, function(run){
          return run.plot != plotName;
         }));
         df.forEach(this.series, function(run, i){
          this.runs[run.name] = i;
         }, this);
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        moveSeriesToFront: function(name){
         // summary:
         //  Moves a given series to front of a plot.
         // name: String:
         //  Series' name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[0]){
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        moveSeriesToBack: function(name){
         // summary:
         //  Moves a given series to back of a plot.
         // name: String:
         //  Series' name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[newOrder.length - 1]){
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        resize: function(width, height){
         // summary:
         //  Resize the chart to the dimensions of width and height.
         // description:
         //  Resize the chart and its surface to the width and height dimensions.
         //  If no width/height or box is provided, resize the surface to the marginBox of the chart.
         // width: Number
         //  The new width of the chart.
         // height: Number
         //  The new height of the chart.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var box;
         switch(arguments.length){
          // case 0, do not resize the div, just the surface
          case 1:
           // argument, override node box
           box = dojo.mixin({}, width);
           dojo.marginBox(this.node, box);
           break;
          case 2:
           box = {w: width, h: height};
           // argument, override node box
           dojo.marginBox(this.node, box);
           break;
         }
         // in all cases take back the computed box
         box = dojo.marginBox(this.node);
         // and set it on the surface
         this.surface.setDimensions(box.w, box.h);
         this.dirty = true;
         this.coords = null;
         return this.render(); // dojox.charting.Chart
        },
        getGeometry: function(){
         // summary:
         //  Returns a map of information about all axes in a chart and what they represent
         //  in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
         // returns: Object
         //  An map of geometry objects, a one-to-one mapping of axes.
         var ret = {};
         df.forIn(this.axes, function(axis){
          if(axis.initialized()){
           ret[axis.name] = {
            name:  axis.name,
            vertical: axis.vertical,
            scaler:  axis.scaler,
            ticks:  axis.ticks
           };
          }
         });
         return ret; // Object
        },
        setAxisWindow: function(name, scale, offset, zoom){
         // summary:
         //  Zooms an axis and all dependent plots. Can be used to zoom in 1D.
         // name: String
         //  The name of the axis as defined by addAxis.
         // scale: Number
         //  The scale on the target axis.
         // offset: Number
         //  Any offest, as measured by axis tick
         // zoom: Boolean|Object?
         //  The chart zooming animation trigger. This is null by default,
         //  e.g. {duration: 1200}, or just set true.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var axis = this.axes[name];
         if(axis){
          axis.setWindow(scale, offset);
          dojo.forEach(this.stack,function(plot){
           if(plot.hAxis == name || plot.vAxis == name){
            plot.zoom = zoom;
           }
          })
         }
         return this; // dojox.charting.Chart
        },
        setWindow: function(sx, sy, dx, dy, zoom){
         // summary:
         //  Zooms in or out any plots in two dimensions.
         // sx: Number
         //  The scale for the x axis.
         // sy: Number
         //  The scale for the y axis.
         // dx: Number
         //  The pixel offset on the x axis.
         // dy: Number
         //  The pixel offset on the y axis.
         // zoom: Boolean|Object?
         //  The chart zooming animation trigger. This is null by default,
         //  e.g. {duration: 1200}, or just set true.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(!("plotArea" in this)){
          this.calculateGeometry();
         }
         df.forIn(this.axes, function(axis){
          var scale, offset, bounds = axis.getScaler().bounds,
           s = bounds.span / (bounds.upper - bounds.lower);
          if(axis.vertical){
           scale = sy;
           offset = dy / s / scale;
          }else{
           scale = sx;
           offset = dx / s / scale;
          }
          axis.setWindow(scale, offset);
         });
         dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
         return this; // dojox.charting.Chart
        },
        zoomIn: function(name, range){
         // summary:
         //  Zoom the chart to a specific range on one axis. This calls render()
         //  directly as a convenience method.
         // name: String
         //  The name of the axis as defined by addAxis.
         // range: Array
         //  The end points of the zoom range, measured in axis ticks.
         var axis = this.axes[name];
         if(axis){
          var scale, offset, bounds = axis.getScaler().bounds;
          var lower = Math.min(range[0],range[1]);
          var upper = Math.max(range[0],range[1]);
          lower = range[0] < bounds.lower ? bounds.lower : lower;
          upper = range[1] > bounds.upper ? bounds.upper : upper;
          scale = (bounds.upper - bounds.lower) / (upper - lower);
          offset = lower - bounds.lower;
          this.setAxisWindow(name, scale, offset);
          this.render();
         }
        },
        calculateGeometry: function(){
         // summary:
         //  Calculate the geometry of the chart based on the defined axes of
         //  a chart.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(this.dirty){
          return this.fullGeometry();
         }


         // calculate geometry
         var dirty = dojo.filter(this.stack, function(plot){
           return plot.dirty ||
            (plot.hAxis && this.axes[plot.hAxis].dirty) ||
            (plot.vAxis && this.axes[plot.vAxis].dirty);
          }, this);
         calculateAxes(dirty, this.plotArea);


         return this; // dojox.charting.Chart
        },
        fullGeometry: function(){
         // summary:
         //  Calculate the full geometry of the chart. This includes passing
         //  over all major elements of a chart (plots, axes, series, container)
         //  in order to ensure proper rendering.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         this._makeDirty();


         // clear old values
         dojo.forEach(this.stack, clear);


         // rebuild new connections, and add defaults


         // set up a theme
         if(!this.theme){
          this.setTheme(new dojox.charting.Theme(dojox.charting._def));
         }


         // assign series
         dojo.forEach(this.series, function(run){
          if(!(run.plot in this.plots)){
      if(!dc.plot2d || !dc.plot2d.Default){
      throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
      }
           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 axes
         dojo.forEach(this.stack, function(plot){
          if(plot.hAxis){
           plot.setAxis(this.axes[plot.hAxis]);
          }
          if(plot.vAxis){
           plot.setAxis(this.axes[plot.vAxis]);
          }
         }, this);


         // calculate geometry


         // 1st pass
         var dim = this.dim = this.surface.getDimensions();
         dim.width = g.normalizedLength(dim.width);
         dim.height = g.normalizedLength(dim.height);
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, dim);


         // assumption: we don't have stacked axes yet
         var 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 title area
         if(this.title){
          this.titleGap = (this.titleGap==0) ? 0 : this.titleGap || this.theme.chart.titleGap || 20;
          this.titlePos = this.titlePos || this.theme.chart.titlePos || "top";
          this.titleFont = this.titleFont || this.theme.chart.titleFont;
          this.titleFontColor = this.titleFontColor || this.theme.chart.titleFontColor || "black";
          var tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
         }
         // add margins
         df.forIn(this.margins, function(o, i){ offsets[i] += o; });


         // 2nd pass with realistic dimensions
         this.plotArea = {
          width: dim.width - offsets.l - offsets.r,
          height: dim.height - offsets.t - offsets.b
         };
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, this.plotArea);


         return this; // dojox.charting.Chart
        },
        render: function(){
         // summary:
         //  Render the chart according to the current information defined. This should
         //  be the last call made when defining/creating a chart, or if data within the
         //  chart has been changed.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(this.theme){
          this.theme.clear();
         }


         if(this.dirty){
          return this.fullRender();
         }


         this.calculateGeometry();


         // go over the stack backwards
         df.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
        },
        fullRender: function(){
         // summary:
         //  Force a full rendering of the chart, including full resets on the chart itself.
         //  You should not call this method directly unless absolutely necessary.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.


         // calculate geometry
         this.fullGeometry();
         var offsets = this.offsets, dim = this.dim, rect;


         // get required colors
         //var requiredColors = df.foldl(this.stack, "z + plot.getRequiredColors()", 0);
         //this.theme.defineColors({num: requiredColors, cache: false});


         // clear old shapes
         dojo.forEach(this.series, purge);
         df.forIn(this.axes, purge);
         dojo.forEach(this.stack, purge);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.clear();
      this.chartTitle = null;


         // generate shapes


         // draw a plot background
         var t = this.theme,
          fill = t.plotarea && t.plotarea.fill,
          stroke = t.plotarea && t.plotarea.stroke,
          rect = {
           x: offsets.l - 1, y: offsets.t - 1,
           width: dim.width - offsets.l - offsets.r + 2,
           height: dim.height - offsets.t - offsets.b + 2
          };
         if(fill){
          fill = dc.Element.prototype._shapeFill(dc.Element.prototype._plotFill(fill, dim, offsets), rect);
          this.surface.createRect(rect).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 backwards
         df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);


         // pseudo-clipping: matting
         fill = this.fill !== undefined ? this.fill : (t.chart && t.chart.fill);
         stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);


         // TRT: support for "inherit" as a named value in a theme.
         if(fill == "inherit"){
          // find the background color of the nearest ancestor node, and use that explicitly.
          var node = this.node, fill = new dojo.Color(dojo.style(node, "backgroundColor"));
          while(fill.a==0 && node!=document.documentElement){
           fill = new dojo.Color(dojo.style(node, "backgroundColor"));
           node = node.parentNode;
          }
         }


         if(fill){
          fill = dc.Element.prototype._plotFill(fill, dim, offsets);
          if(offsets.l){ // left
           rect = {
            width: offsets.l,
            height: dim.height + 1
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.r){ // right
           rect = {
            x: dim.width - offsets.r,
            width: offsets.r + 1,
            height: dim.height + 2
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.t){ // top
           rect = {
            width: dim.width + 1,
            height: offsets.t
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.b){ // bottom
           rect = {
            y: dim.height - offsets.b,
            width: dim.width + 1,
            height: offsets.b + 2
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
         }
         if(stroke){
          this.surface.createRect({
           width: dim.width - 1,
           height: dim.height - 1
          }).setStroke(stroke);
         }


         //create title: Whether to make chart title as a widget which extends dojox.charting.Element?
         if(this.title){
          var forceHtmlLabels = (g.renderer == "canvas"),
           labelType = forceHtmlLabels || !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
           tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          this.chartTitle = dc.axis2d.common.createText[labelType](
           this,
           this.surface,
           dim.width/2,
           this.titlePos=="top" ? tsize + this.margins.t : dim.height - this.margins.b,
           "middle",
           this.title,
           this.titleFont,
           this.titleFontColor
          );
         }


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
    • summary
      Force a full rendering of the chart, including full resets on the chart itself.
      You should not call this method directly unless absolutely necessary.
    • returns
      Object|dojox.charting.Chart|dojox.charting.axis2d.Default|Array
  • dojox.charting.Chart.delayedRender

    • type
      Function
    • source: [view]
         if(!this._delayedRenderHandle){
          this._delayedRenderHandle = setTimeout(
           dojo.hitch(this, function(){
            clearTimeout(this._delayedRenderHandle);
            this._delayedRenderHandle = null;
            this.render();
           }),
           this.delayInMs
          );
         }


         return this; // dojox.charting.Chart
    • summary
      Delayed render, which is used to collect multiple updates
      within a delayInMs time window.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart.connectToPlot

    • type
      Function
    • parameters:
      • name: (typeof String)
        The name of the plot as defined by addPlot.
      • object: (typeof Object)
        The object to be connected.
      • method: (typeof Function)
        The function to be executed.
    • source: [view]
         return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null; // Array
    • summary
      A convenience method to connect a function to a plot.
    • return_summary
      Array
      A handle to the connection, as defined by dojo.connect (see dojo.connect).
    • returns
      Array
  • dojox.charting.Chart.fireEvent

    • type
      Function
    • parameters:
      • seriesName: (typeof String)
        Series name.
      • eventName: (typeof String)
        Event name to simulate: onmouseover, onmouseout, onclick.
      • index: (typeof Number)
        Valid data value index for the event.
    • source: [view]
         if(seriesName in this.runs){
          var plotName = this.series[this.runs[seriesName]].plot;
          if(plotName in this.plots){
           var plot = this.stack[this.plots[plotName]];
           if(plot){
            plot.fireEvent(seriesName, eventName, index);
           }
          }
         }
         return this; // dojox.charting.Chart
    • summary
      Fires a synthetic event for a series item.
    • return_summary
      dojox.charting.Chart
      A reference to the current chart for functional chaining.
    • returns
      dojox.charting.Chart
  • dojox.charting.Chart._makeClean

    • type
      Function
    • source: [view]
      dojo.provide("dojox.charting.Chart");


      dojo.require("dojox.gfx");
      dojo.require("dojox.lang.functional");
      dojo.require("dojox.lang.functional.fold");
      dojo.require("dojox.lang.functional.reversed");


      dojo.require("dojox.charting.Element");
      dojo.require("dojox.charting.Theme");
      dojo.require("dojox.charting.Series");
      dojo.require("dojox.charting.axis2d.common");




      dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
       // summary:
       //  The keyword arguments that can be passed in a Chart constructor.
       //
       // margins: Object?
       //  Optional margins for the chart, in the form of { l, t, r, b}.
       // stroke: dojox.gfx.Stroke?
       //  An optional outline/stroke for the chart.
       // fill: dojox.gfx.Fill?
       //  An optional fill for the chart.
       // delayInMs: Number
       //  Delay in ms for delayedRender(). Default: 200.
       this.margins = margins;
       this.stroke = stroke;
       this.fill = fill;
       this.delayInMs = delayInMs;
      }


      (function(){
       var df = dojox.lang.functional, dc = dojox.charting, g = dojox.gfx,
        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"),
        getName = df.lambda("item.name");


       dojo.declare("dojox.charting.Chart", null, {
        // summary:
        //  The main chart object in dojox.charting. This will create a two dimensional
        //  chart based on dojox.gfx.
        //
        // description:
        //  dojox.charting.Chart is the primary object used for any kind of charts. It
        //  is simple to create--just pass it a node reference, which is used as the
        //  container for the chart--and a set of optional keyword arguments and go.
        //
        //  Note that like most of dojox.gfx, most of dojox.charting.Chart's methods are
        //  designed to return a reference to the chart itself, to allow for functional
        //  chaining. This makes defining everything on a Chart very easy to do.
        //
        // example:
        //  Create an area chart, with smoothing.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", { type: "Areas", tension: "X" })
        // |  .setTheme(dojox.charting.themes.Shrooms)
        // |  .addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
        // |  .addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
        // |  .addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
        // |  .render();
        //
        // example:
        //  The form of data in a data series can take a number of forms: a simple array,
        //  an array of objects {x,y}, or something custom (as determined by the plot).
        //  Here's an example of a Candlestick chart, which expects an object of
        //  { open, high, low, close }.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", {type: "Candlesticks", gap: 1})
        // |  .addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
        // |  .addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
        // |  .addSeries("Series A", [
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6 },
        // |    { open: 22, close: 18, high: 22, low: 11 },
        // |    { open: 18, close: 29, high: 32, low: 14 },
        // |    { open: 29, close: 24, high: 29, low: 13 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 }
        // |   ],
        // |   { stroke: { color: "green" }, fill: "lightgreen" }
        // |  )
        // |  .render();
        //
        // theme: dojox.charting.Theme?
        //  An optional theme to use for styling the chart.
        // axes: dojox.charting.Axis{}?
        //  A map of axes for use in plotting a chart.
        // stack: dojox.charting.plot2d.Base[]
        //  A stack of plotters.
        // plots: dojox.charting.plot2d.Base{}
        //  A map of plotter indices
        // series: dojox.charting.Series[]
        //  The stack of data runs used to create plots.
        // runs: dojox.charting.Series{}
        //  A map of series indices
        // margins: Object?
        //  The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
        // stroke: dojox.gfx.Stroke?
        //  The outline of the chart (stroke in vector graphics terms).
        // fill: dojox.gfx.Fill?
        //  The color for the chart.
        // node: DOMNode
        //  The container node passed to the constructor.
        // surface: dojox.gfx.Surface
        //  The main graphics surface upon which a chart is drawn.
        // dirty: Boolean
        //  A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
        // coords: Object
        //  The coordinates on a page of the containing node, as returned from dojo.coords.


        constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
         // summary:
         //  The constructor for a new Chart. Initializes all parameters used for a chart.
         // returns: dojox.charting.Chart
         //  The newly created chart.


         // initialize parameters
         if(!kwArgs){ kwArgs = {}; }
         this.margins = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
         this.stroke = kwArgs.stroke;
         this.fill = kwArgs.fill;
         this.delayInMs = kwArgs.delayInMs || 200;
         this.title = kwArgs.title;
         this.titleGap = kwArgs.titleGap;
         this.titlePos = kwArgs.titlePos;
         this.titleFont = kwArgs.titleFont;
         this.titleFontColor = kwArgs.titleFontColor;
         this.chartTitle = null;


         // default initialization
         this.theme = null;
         this.axes = {};  // map of axes
         this.stack = []; // stack of plotters
         this.plots = {}; // map of plotter indices
         this.series = []; // stack of data runs
         this.runs = {};  // map of data run indices
         this.dirty = true;
         this.coords = null;


         // create a surface
         this.node = dojo.byId(node);
         var box = dojo.marginBox(node);
         this.surface = g.createSurface(this.node, box.w || 400, box.h || 300);
        },
        destroy: function(){
         // summary:
         //  Cleanup when a chart is to be destroyed.
         // returns: void
         dojo.forEach(this.series, destroy);
         dojo.forEach(this.stack, destroy);
         df.forIn(this.axes, destroy);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.destroy();
        },
        getCoords: function(){
         // summary:
         //  Get the coordinates and dimensions of the containing DOMNode, as
         //  returned by dojo.coords.
         // returns: Object
         //  The resulting coordinates of the chart. See dojo.coords for details.
         if(!this.coords){
          this.coords = dojo.coords(this.node, true);
         }
         return this.coords; // Object
        },
        setTheme: function(theme){
         // summary:
         //  Set a theme of the chart.
         // theme: dojox.charting.Theme
         //  The theme to be used for visual rendering.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         this.theme = theme.clone();
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        addAxis: function(name, kwArgs){
         // summary:
         //  Add an axis to the chart, for rendering.
         // name: String
         //  The name of the axis.
         // kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
         //  An optional keyword arguments object for use in defining details of an axis.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
      var axis, axisType = kwArgs && kwArgs.type || "Default";
      if(typeof axisType == "string"){
      if(!dc.axis2d || !dc.axis2d[axisType]){
      throw Error("Can't find axis: " + axisType + " - didn't you forget to dojo" + ".require() it?");
      }
      axis = new dc.axis2d[axisType](this, kwArgs);
      }else{
      axis = new axisType(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; // dojox.charting.Chart
        },
        getAxis: function(name){
         // summary:
         //  Get the given axis, by name.
         // name: String
         //  The name the axis was defined by.
         // returns: dojox.charting.axis2d.Default
         //  The axis as stored in the chart's axis map.
         return this.axes[name]; // dojox.charting.axis2d.Default
        },
        removeAxis: function(name){
         // summary:
         //  Remove the axis that was defined using name.
         // name: String
         //  The axis name, as defined in addAxis.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.axes){
          // destroy the axis
          this.axes[name].destroy();
          delete this.axes[name];
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        addPlot: function(name, kwArgs){
         // summary:
         //  Add a new plot to the chart, defined by name and using the optional keyword arguments object.
         //  Note that dojox.charting assumes the main plot to be called "default"; if you do not have
         //  a plot called "default" and attempt to add data series to the chart without specifying the
         //  plot to be rendered on, you WILL get errors.
         // name: String
         //  The name of the plot to be added to the chart. If you only plan on using one plot, call it "default".
         // kwArgs: dojox.charting.plot2d.__PlotCtorArgs
         //  An object with optional parameters for the plot in question.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var plot, plotType = kwArgs && kwArgs.type || "Default";
      if(typeof plotType == "string"){
      if(!dc.plot2d || !dc.plot2d[plotType]){
      throw Error("Can't find plot: " + plotType + " - didn't you forget to dojo" + ".require() it?");
      }
      plot = new dc.plot2d[plotType](this, kwArgs);
      }else{
      plot = new plotType(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; // dojox.charting.Chart
        },
        removePlot: function(name){
         // summary:
         //  Remove the plot defined using name from the chart's plot stack.
         // name: String
         //  The name of the plot as defined using addPlot.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          // get the index and remove the name
          var index = this.plots[name];
          delete this.plots[name];
          // destroy the plot
          this.stack[index].destroy();
          // remove the plot from the stack
          this.stack.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.plots, function(idx, name, plots){
           if(idx > index){
            plots[name] = idx - 1;
           }
          });
      // remove all related series
      var ns = dojo.filter(this.series, function(run){ return run.plot != name; });
      if(ns.length < this.series.length){
      // kill all removed series
      dojo.forEach(this.series, function(run){
      if(run.plot == name){
      run.destroy();
      }
      });
      // rebuild all necessary data structures
      this.runs = {};
      dojo.forEach(ns, function(run, index){
      this.runs[run.plot] = index;
      }, this);
      this.series = ns;
      }
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        getPlotOrder: function(){
         // summary:
         //  Returns an array of plot names in the current order
         //  (the top-most plot is the first).
         // returns: Array
         return df.map(this.stack, getName); // Array
        },
        setPlotOrder: function(newOrder){
         // summary:
         //  Sets new order of plots. newOrder cannot add or remove
         //  plots. Wrong names, or dups are ignored.
         // newOrder: Array:
         //  Array of plot names compatible with getPlotOrder().
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.plots) || (name in names)){
            return false;
           }
           names[name] = 1;
           return true;
          }, this);
         if(order.length < this.stack.length){
          df.forEach(this.stack, function(plot){
           var name = plot.name;
           if(!(name in names)){
            order.push(name);
           }
          });
         }
         var newStack = df.map(order, function(name){
           return this.stack[this.plots[name]];
          }, this);
         df.forEach(newStack, function(plot, i){
          this.plots[plot.name] = i;
         }, this);
         this.stack = newStack;
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        movePlotToFront: function(name){
         // summary:
         //  Moves a given plot to front.
         // name: String:
         //  Plot's name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          var index = this.plots[name];
          if(index){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        movePlotToBack: function(name){
         // summary:
         //  Moves a given plot to back.
         // name: String:
         //  Plot's name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          var index = this.plots[name];
          if(index < this.stack.length - 1){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        addSeries: function(name, data, kwArgs){
         // summary:
         //  Add a data series to the chart for rendering.
         // name: String:
         //  The name of the data series to be plotted.
         // data: Array|Object:
         //  The array of data points (either numbers or objects) that
         //  represents the data to be drawn. Or it can be an object. In
         //  the latter case, it should have a property "data" (an array),
         //  destroy(), and setSeriesObject().
         // kwArgs: dojox.charting.__SeriesCtorArgs?:
         //  An optional keyword arguments object that will be mixed into
         //  the resultant series object.
         // returns: dojox.charting.Chart:
         //  A reference to the current chart for functional chaining.
         var run = new dc.Series(this, data, kwArgs);
         run.name = name;
         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/max
         if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
         if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
         return this; // dojox.charting.Chart
        },
        removeSeries: function(name){
         // summary:
         //  Remove the series defined by name from the chart.
         // name: String
         //  The name of the series as defined by addSeries.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          // get the index and remove the name
          var index = this.runs[name];
          delete this.runs[name];
          // destroy the run
          this.series[index].destroy();
          // remove the run from the stack of series
          this.series.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.runs, function(idx, name, runs){
           if(idx > index){
            runs[name] = idx - 1;
           }
          });
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        updateSeries: function(name, data){
         // summary:
         //  Update the given series with a new set of data points.
         // name: String
         //  The name of the series as defined in addSeries.
         // data: Array|Object:
         //  The array of data points (either numbers or objects) that
         //  represents the data to be drawn. Or it can be an object. In
         //  the latter case, it should have a property "data" (an array),
         //  destroy(), and setSeriesObject().
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var run = this.series[this.runs[name]];
          run.update(data);
          this._invalidateDependentPlots(run.plot, false);
          this._invalidateDependentPlots(run.plot, true);
         }
         return this; // dojox.charting.Chart
        },
        getSeriesOrder: function(plotName){
         // summary:
         //  Returns an array of series names in the current order
         //  (the top-most series is the first) within a plot.
         // plotName: String:
         //  Plot's name.
         // returns: Array
         return df.map(df.filter(this.series, function(run){
           return run.plot == plotName;
          }), getName);
        },
        setSeriesOrder: function(newOrder){
         // summary:
         //  Sets new order of series within a plot. newOrder cannot add
         //  or remove series. Wrong names, or dups are ignored.
         // newOrder: Array:
         //  Array of series names compatible with getPlotOrder(). All
         //  series should belong to the same plot.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var plotName, names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.runs) || (name in names)){
            return false;
           }
           var run = this.series[this.runs[name]];
           if(plotName){
            if(run.plot != plotName){
             return false;
            }
           }else{
            plotName = run.plot;
           }
           names[name] = 1;
           return true;
          }, this);
         df.forEach(this.series, function(run){
          var name = run.name;
          if(!(name in names) && run.plot == plotName){
           order.push(name);
          }
         });
         var newSeries = df.map(order, function(name){
           return this.series[this.runs[name]];
          }, this);
         this.series = newSeries.concat(df.filter(this.series, function(run){
          return run.plot != plotName;
         }));
         df.forEach(this.series, function(run, i){
          this.runs[run.name] = i;
         }, this);
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        moveSeriesToFront: function(name){
         // summary:
         //  Moves a given series to front of a plot.
         // name: String:
         //  Series' name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[0]){
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        moveSeriesToBack: function(name){
         // summary:
         //  Moves a given series to back of a plot.
         // name: String:
         //  Series' name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[newOrder.length - 1]){
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        resize: function(width, height){
         // summary:
         //  Resize the chart to the dimensions of width and height.
         // description:
         //  Resize the chart and its surface to the width and height dimensions.
         //  If no width/height or box is provided, resize the surface to the marginBox of the chart.
         // width: Number
         //  The new width of the chart.
         // height: Number
         //  The new height of the chart.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var box;
         switch(arguments.length){
          // case 0, do not resize the div, just the surface
          case 1:
           // argument, override node box
           box = dojo.mixin({}, width);
           dojo.marginBox(this.node, box);
           break;
          case 2:
           box = {w: width, h: height};
           // argument, override node box
           dojo.marginBox(this.node, box);
           break;
         }
         // in all cases take back the computed box
         box = dojo.marginBox(this.node);
         // and set it on the surface
         this.surface.setDimensions(box.w, box.h);
         this.dirty = true;
         this.coords = null;
         return this.render(); // dojox.charting.Chart
        },
        getGeometry: function(){
         // summary:
         //  Returns a map of information about all axes in a chart and what they represent
         //  in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
         // returns: Object
         //  An map of geometry objects, a one-to-one mapping of axes.
         var ret = {};
         df.forIn(this.axes, function(axis){
          if(axis.initialized()){
           ret[axis.name] = {
            name:  axis.name,
            vertical: axis.vertical,
            scaler:  axis.scaler,
            ticks:  axis.ticks
           };
          }
         });
         return ret; // Object
        },
        setAxisWindow: function(name, scale, offset, zoom){
         // summary:
         //  Zooms an axis and all dependent plots. Can be used to zoom in 1D.
         // name: String
         //  The name of the axis as defined by addAxis.
         // scale: Number
         //  The scale on the target axis.
         // offset: Number
         //  Any offest, as measured by axis tick
         // zoom: Boolean|Object?
         //  The chart zooming animation trigger. This is null by default,
         //  e.g. {duration: 1200}, or just set true.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var axis = this.axes[name];
         if(axis){
          axis.setWindow(scale, offset);
          dojo.forEach(this.stack,function(plot){
           if(plot.hAxis == name || plot.vAxis == name){
            plot.zoom = zoom;
           }
          })
         }
         return this; // dojox.charting.Chart
        },
        setWindow: function(sx, sy, dx, dy, zoom){
         // summary:
         //  Zooms in or out any plots in two dimensions.
         // sx: Number
         //  The scale for the x axis.
         // sy: Number
         //  The scale for the y axis.
         // dx: Number
         //  The pixel offset on the x axis.
         // dy: Number
         //  The pixel offset on the y axis.
         // zoom: Boolean|Object?
         //  The chart zooming animation trigger. This is null by default,
         //  e.g. {duration: 1200}, or just set true.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(!("plotArea" in this)){
          this.calculateGeometry();
         }
         df.forIn(this.axes, function(axis){
          var scale, offset, bounds = axis.getScaler().bounds,
           s = bounds.span / (bounds.upper - bounds.lower);
          if(axis.vertical){
           scale = sy;
           offset = dy / s / scale;
          }else{
           scale = sx;
           offset = dx / s / scale;
          }
          axis.setWindow(scale, offset);
         });
         dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
         return this; // dojox.charting.Chart
        },
        zoomIn: function(name, range){
         // summary:
         //  Zoom the chart to a specific range on one axis. This calls render()
         //  directly as a convenience method.
         // name: String
         //  The name of the axis as defined by addAxis.
         // range: Array
         //  The end points of the zoom range, measured in axis ticks.
         var axis = this.axes[name];
         if(axis){
          var scale, offset, bounds = axis.getScaler().bounds;
          var lower = Math.min(range[0],range[1]);
          var upper = Math.max(range[0],range[1]);
          lower = range[0] < bounds.lower ? bounds.lower : lower;
          upper = range[1] > bounds.upper ? bounds.upper : upper;
          scale = (bounds.upper - bounds.lower) / (upper - lower);
          offset = lower - bounds.lower;
          this.setAxisWindow(name, scale, offset);
          this.render();
         }
        },
        calculateGeometry: function(){
         // summary:
         //  Calculate the geometry of the chart based on the defined axes of
         //  a chart.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(this.dirty){
          return this.fullGeometry();
         }


         // calculate geometry
         var dirty = dojo.filter(this.stack, function(plot){
           return plot.dirty ||
            (plot.hAxis && this.axes[plot.hAxis].dirty) ||
            (plot.vAxis && this.axes[plot.vAxis].dirty);
          }, this);
         calculateAxes(dirty, this.plotArea);


         return this; // dojox.charting.Chart
        },
        fullGeometry: function(){
         // summary:
         //  Calculate the full geometry of the chart. This includes passing
         //  over all major elements of a chart (plots, axes, series, container)
         //  in order to ensure proper rendering.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         this._makeDirty();


         // clear old values
         dojo.forEach(this.stack, clear);


         // rebuild new connections, and add defaults


         // set up a theme
         if(!this.theme){
          this.setTheme(new dojox.charting.Theme(dojox.charting._def));
         }


         // assign series
         dojo.forEach(this.series, function(run){
          if(!(run.plot in this.plots)){
      if(!dc.plot2d || !dc.plot2d.Default){
      throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
      }
           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 axes
         dojo.forEach(this.stack, function(plot){
          if(plot.hAxis){
           plot.setAxis(this.axes[plot.hAxis]);
          }
          if(plot.vAxis){
           plot.setAxis(this.axes[plot.vAxis]);
          }
         }, this);


         // calculate geometry


         // 1st pass
         var dim = this.dim = this.surface.getDimensions();
         dim.width = g.normalizedLength(dim.width);
         dim.height = g.normalizedLength(dim.height);
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, dim);


         // assumption: we don't have stacked axes yet
         var 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 title area
         if(this.title){
          this.titleGap = (this.titleGap==0) ? 0 : this.titleGap || this.theme.chart.titleGap || 20;
          this.titlePos = this.titlePos || this.theme.chart.titlePos || "top";
          this.titleFont = this.titleFont || this.theme.chart.titleFont;
          this.titleFontColor = this.titleFontColor || this.theme.chart.titleFontColor || "black";
          var tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
         }
         // add margins
         df.forIn(this.margins, function(o, i){ offsets[i] += o; });


         // 2nd pass with realistic dimensions
         this.plotArea = {
          width: dim.width - offsets.l - offsets.r,
          height: dim.height - offsets.t - offsets.b
         };
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, this.plotArea);


         return this; // dojox.charting.Chart
        },
        render: function(){
         // summary:
         //  Render the chart according to the current information defined. This should
         //  be the last call made when defining/creating a chart, or if data within the
         //  chart has been changed.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(this.theme){
          this.theme.clear();
         }


         if(this.dirty){
          return this.fullRender();
         }


         this.calculateGeometry();


         // go over the stack backwards
         df.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
        },
        fullRender: function(){
         // summary:
         //  Force a full rendering of the chart, including full resets on the chart itself.
         //  You should not call this method directly unless absolutely necessary.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.


         // calculate geometry
         this.fullGeometry();
         var offsets = this.offsets, dim = this.dim, rect;


         // get required colors
         //var requiredColors = df.foldl(this.stack, "z + plot.getRequiredColors()", 0);
         //this.theme.defineColors({num: requiredColors, cache: false});


         // clear old shapes
         dojo.forEach(this.series, purge);
         df.forIn(this.axes, purge);
         dojo.forEach(this.stack, purge);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.clear();
      this.chartTitle = null;


         // generate shapes


         // draw a plot background
         var t = this.theme,
          fill = t.plotarea && t.plotarea.fill,
          stroke = t.plotarea && t.plotarea.stroke,
          rect = {
           x: offsets.l - 1, y: offsets.t - 1,
           width: dim.width - offsets.l - offsets.r + 2,
           height: dim.height - offsets.t - offsets.b + 2
          };
         if(fill){
          fill = dc.Element.prototype._shapeFill(dc.Element.prototype._plotFill(fill, dim, offsets), rect);
          this.surface.createRect(rect).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 backwards
         df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);


         // pseudo-clipping: matting
         fill = this.fill !== undefined ? this.fill : (t.chart && t.chart.fill);
         stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);


         // TRT: support for "inherit" as a named value in a theme.
         if(fill == "inherit"){
          // find the background color of the nearest ancestor node, and use that explicitly.
          var node = this.node, fill = new dojo.Color(dojo.style(node, "backgroundColor"));
          while(fill.a==0 && node!=document.documentElement){
           fill = new dojo.Color(dojo.style(node, "backgroundColor"));
           node = node.parentNode;
          }
         }


         if(fill){
          fill = dc.Element.prototype._plotFill(fill, dim, offsets);
          if(offsets.l){ // left
           rect = {
            width: offsets.l,
            height: dim.height + 1
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.r){ // right
           rect = {
            x: dim.width - offsets.r,
            width: offsets.r + 1,
            height: dim.height + 2
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.t){ // top
           rect = {
            width: dim.width + 1,
            height: offsets.t
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.b){ // bottom
           rect = {
            y: dim.height - offsets.b,
            width: dim.width + 1,
            height: offsets.b + 2
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
         }
         if(stroke){
          this.surface.createRect({
           width: dim.width - 1,
           height: dim.height - 1
          }).setStroke(stroke);
         }


         //create title: Whether to make chart title as a widget which extends dojox.charting.Element?
         if(this.title){
          var forceHtmlLabels = (g.renderer == "canvas"),
           labelType = forceHtmlLabels || !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
           tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          this.chartTitle = dc.axis2d.common.createText[labelType](
           this,
           this.surface,
           dim.width/2,
           this.titlePos=="top" ? tsize + this.margins.t : dim.height - this.margins.b,
           "middle",
           this.title,
           this.titleFont,
           this.titleFontColor
          );
         }


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
        },
        delayedRender: function(){
         // summary:
         //  Delayed render, which is used to collect multiple updates
         //  within a delayInMs time window.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.


         if(!this._delayedRenderHandle){
          this._delayedRenderHandle = setTimeout(
           dojo.hitch(this, function(){
            clearTimeout(this._delayedRenderHandle);
            this._delayedRenderHandle = null;
            this.render();
           }),
           this.delayInMs
          );
         }


         return this; // dojox.charting.Chart
        },
        connectToPlot: function(name, object, method){
         // summary:
         //  A convenience method to connect a function to a plot.
         // name: String
         //  The name of the plot as defined by addPlot.
         // object: Object
         //  The object to be connected.
         // method: Function
         //  The function to be executed.
         // returns: Array
         //  A handle to the connection, as defined by dojo.connect (see dojo.connect).
         return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null; // Array
        },
        fireEvent: function(seriesName, eventName, index){
         // summary:
         //  Fires a synthetic event for a series item.
         // seriesName: String:
         //  Series name.
         // eventName: String:
         //  Event name to simulate: onmouseover, onmouseout, onclick.
         // index: Number:
         //  Valid data value index for the event.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(seriesName in this.runs){
          var plotName = this.series[this.runs[seriesName]].plot;
          if(plotName in this.plots){
           var plot = this.stack[this.plots[plotName]];
           if(plot){
            plot.fireEvent(seriesName, eventName, index);
           }
          }
         }
         return this; // dojox.charting.Chart
        },
        _makeClean: function(){
         // reset dirty flags
         dojo.forEach(this.axes, makeClean);
         dojo.forEach(this.stack, makeClean);
         dojo.forEach(this.series, makeClean);
         this.dirty = false;
    • returns
      Object|dojox.charting.Chart|dojox.charting.axis2d.Default|Array
    • summary
  • dojox.charting.Chart._makeDirty

    • type
      Function
    • source: [view]
      dojo.provide("dojox.charting.Chart");


      dojo.require("dojox.gfx");
      dojo.require("dojox.lang.functional");
      dojo.require("dojox.lang.functional.fold");
      dojo.require("dojox.lang.functional.reversed");


      dojo.require("dojox.charting.Element");
      dojo.require("dojox.charting.Theme");
      dojo.require("dojox.charting.Series");
      dojo.require("dojox.charting.axis2d.common");




      dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
       // summary:
       //  The keyword arguments that can be passed in a Chart constructor.
       //
       // margins: Object?
       //  Optional margins for the chart, in the form of { l, t, r, b}.
       // stroke: dojox.gfx.Stroke?
       //  An optional outline/stroke for the chart.
       // fill: dojox.gfx.Fill?
       //  An optional fill for the chart.
       // delayInMs: Number
       //  Delay in ms for delayedRender(). Default: 200.
       this.margins = margins;
       this.stroke = stroke;
       this.fill = fill;
       this.delayInMs = delayInMs;
      }


      (function(){
       var df = dojox.lang.functional, dc = dojox.charting, g = dojox.gfx,
        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"),
        getName = df.lambda("item.name");


       dojo.declare("dojox.charting.Chart", null, {
        // summary:
        //  The main chart object in dojox.charting. This will create a two dimensional
        //  chart based on dojox.gfx.
        //
        // description:
        //  dojox.charting.Chart is the primary object used for any kind of charts. It
        //  is simple to create--just pass it a node reference, which is used as the
        //  container for the chart--and a set of optional keyword arguments and go.
        //
        //  Note that like most of dojox.gfx, most of dojox.charting.Chart's methods are
        //  designed to return a reference to the chart itself, to allow for functional
        //  chaining. This makes defining everything on a Chart very easy to do.
        //
        // example:
        //  Create an area chart, with smoothing.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", { type: "Areas", tension: "X" })
        // |  .setTheme(dojox.charting.themes.Shrooms)
        // |  .addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
        // |  .addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
        // |  .addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
        // |  .render();
        //
        // example:
        //  The form of data in a data series can take a number of forms: a simple array,
        //  an array of objects {x,y}, or something custom (as determined by the plot).
        //  Here's an example of a Candlestick chart, which expects an object of
        //  { open, high, low, close }.
        // | new dojox.charting.Chart(node))
        // |  .addPlot("default", {type: "Candlesticks", gap: 1})
        // |  .addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
        // |  .addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
        // |  .addSeries("Series A", [
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6, mid: 18 },
        // |    { open: 22, close: 18, high: 22, low: 11, mid: 21 },
        // |    { open: 18, close: 29, high: 32, low: 14, mid: 27 },
        // |    { open: 29, close: 24, high: 29, low: 13, mid: 27 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 },
        // |    { open: 16, close: 22, high: 26, low: 6 },
        // |    { open: 22, close: 18, high: 22, low: 11 },
        // |    { open: 18, close: 29, high: 32, low: 14 },
        // |    { open: 29, close: 24, high: 29, low: 13 },
        // |    { open: 24, close: 8, high: 24, low: 5 },
        // |    { open: 8, close: 16, high: 22, low: 2 },
        // |    { open: 16, close: 12, high: 19, low: 7 },
        // |    { open: 12, close: 20, high: 22, low: 8 },
        // |    { open: 20, close: 16, high: 22, low: 8 }
        // |   ],
        // |   { stroke: { color: "green" }, fill: "lightgreen" }
        // |  )
        // |  .render();
        //
        // theme: dojox.charting.Theme?
        //  An optional theme to use for styling the chart.
        // axes: dojox.charting.Axis{}?
        //  A map of axes for use in plotting a chart.
        // stack: dojox.charting.plot2d.Base[]
        //  A stack of plotters.
        // plots: dojox.charting.plot2d.Base{}
        //  A map of plotter indices
        // series: dojox.charting.Series[]
        //  The stack of data runs used to create plots.
        // runs: dojox.charting.Series{}
        //  A map of series indices
        // margins: Object?
        //  The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
        // stroke: dojox.gfx.Stroke?
        //  The outline of the chart (stroke in vector graphics terms).
        // fill: dojox.gfx.Fill?
        //  The color for the chart.
        // node: DOMNode
        //  The container node passed to the constructor.
        // surface: dojox.gfx.Surface
        //  The main graphics surface upon which a chart is drawn.
        // dirty: Boolean
        //  A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
        // coords: Object
        //  The coordinates on a page of the containing node, as returned from dojo.coords.


        constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
         // summary:
         //  The constructor for a new Chart. Initializes all parameters used for a chart.
         // returns: dojox.charting.Chart
         //  The newly created chart.


         // initialize parameters
         if(!kwArgs){ kwArgs = {}; }
         this.margins = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
         this.stroke = kwArgs.stroke;
         this.fill = kwArgs.fill;
         this.delayInMs = kwArgs.delayInMs || 200;
         this.title = kwArgs.title;
         this.titleGap = kwArgs.titleGap;
         this.titlePos = kwArgs.titlePos;
         this.titleFont = kwArgs.titleFont;
         this.titleFontColor = kwArgs.titleFontColor;
         this.chartTitle = null;


         // default initialization
         this.theme = null;
         this.axes = {};  // map of axes
         this.stack = []; // stack of plotters
         this.plots = {}; // map of plotter indices
         this.series = []; // stack of data runs
         this.runs = {};  // map of data run indices
         this.dirty = true;
         this.coords = null;


         // create a surface
         this.node = dojo.byId(node);
         var box = dojo.marginBox(node);
         this.surface = g.createSurface(this.node, box.w || 400, box.h || 300);
        },
        destroy: function(){
         // summary:
         //  Cleanup when a chart is to be destroyed.
         // returns: void
         dojo.forEach(this.series, destroy);
         dojo.forEach(this.stack, destroy);
         df.forIn(this.axes, destroy);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.destroy();
        },
        getCoords: function(){
         // summary:
         //  Get the coordinates and dimensions of the containing DOMNode, as
         //  returned by dojo.coords.
         // returns: Object
         //  The resulting coordinates of the chart. See dojo.coords for details.
         if(!this.coords){
          this.coords = dojo.coords(this.node, true);
         }
         return this.coords; // Object
        },
        setTheme: function(theme){
         // summary:
         //  Set a theme of the chart.
         // theme: dojox.charting.Theme
         //  The theme to be used for visual rendering.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         this.theme = theme.clone();
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        addAxis: function(name, kwArgs){
         // summary:
         //  Add an axis to the chart, for rendering.
         // name: String
         //  The name of the axis.
         // kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
         //  An optional keyword arguments object for use in defining details of an axis.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
      var axis, axisType = kwArgs && kwArgs.type || "Default";
      if(typeof axisType == "string"){
      if(!dc.axis2d || !dc.axis2d[axisType]){
      throw Error("Can't find axis: " + axisType + " - didn't you forget to dojo" + ".require() it?");
      }
      axis = new dc.axis2d[axisType](this, kwArgs);
      }else{
      axis = new axisType(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; // dojox.charting.Chart
        },
        getAxis: function(name){
         // summary:
         //  Get the given axis, by name.
         // name: String
         //  The name the axis was defined by.
         // returns: dojox.charting.axis2d.Default
         //  The axis as stored in the chart's axis map.
         return this.axes[name]; // dojox.charting.axis2d.Default
        },
        removeAxis: function(name){
         // summary:
         //  Remove the axis that was defined using name.
         // name: String
         //  The axis name, as defined in addAxis.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.axes){
          // destroy the axis
          this.axes[name].destroy();
          delete this.axes[name];
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        addPlot: function(name, kwArgs){
         // summary:
         //  Add a new plot to the chart, defined by name and using the optional keyword arguments object.
         //  Note that dojox.charting assumes the main plot to be called "default"; if you do not have
         //  a plot called "default" and attempt to add data series to the chart without specifying the
         //  plot to be rendered on, you WILL get errors.
         // name: String
         //  The name of the plot to be added to the chart. If you only plan on using one plot, call it "default".
         // kwArgs: dojox.charting.plot2d.__PlotCtorArgs
         //  An object with optional parameters for the plot in question.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var plot, plotType = kwArgs && kwArgs.type || "Default";
      if(typeof plotType == "string"){
      if(!dc.plot2d || !dc.plot2d[plotType]){
      throw Error("Can't find plot: " + plotType + " - didn't you forget to dojo" + ".require() it?");
      }
      plot = new dc.plot2d[plotType](this, kwArgs);
      }else{
      plot = new plotType(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; // dojox.charting.Chart
        },
        removePlot: function(name){
         // summary:
         //  Remove the plot defined using name from the chart's plot stack.
         // name: String
         //  The name of the plot as defined using addPlot.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          // get the index and remove the name
          var index = this.plots[name];
          delete this.plots[name];
          // destroy the plot
          this.stack[index].destroy();
          // remove the plot from the stack
          this.stack.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.plots, function(idx, name, plots){
           if(idx > index){
            plots[name] = idx - 1;
           }
          });
      // remove all related series
      var ns = dojo.filter(this.series, function(run){ return run.plot != name; });
      if(ns.length < this.series.length){
      // kill all removed series
      dojo.forEach(this.series, function(run){
      if(run.plot == name){
      run.destroy();
      }
      });
      // rebuild all necessary data structures
      this.runs = {};
      dojo.forEach(ns, function(run, index){
      this.runs[run.plot] = index;
      }, this);
      this.series = ns;
      }
          // mark the chart as dirty
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        getPlotOrder: function(){
         // summary:
         //  Returns an array of plot names in the current order
         //  (the top-most plot is the first).
         // returns: Array
         return df.map(this.stack, getName); // Array
        },
        setPlotOrder: function(newOrder){
         // summary:
         //  Sets new order of plots. newOrder cannot add or remove
         //  plots. Wrong names, or dups are ignored.
         // newOrder: Array:
         //  Array of plot names compatible with getPlotOrder().
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.plots) || (name in names)){
            return false;
           }
           names[name] = 1;
           return true;
          }, this);
         if(order.length < this.stack.length){
          df.forEach(this.stack, function(plot){
           var name = plot.name;
           if(!(name in names)){
            order.push(name);
           }
          });
         }
         var newStack = df.map(order, function(name){
           return this.stack[this.plots[name]];
          }, this);
         df.forEach(newStack, function(plot, i){
          this.plots[plot.name] = i;
         }, this);
         this.stack = newStack;
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        movePlotToFront: function(name){
         // summary:
         //  Moves a given plot to front.
         // name: String:
         //  Plot's name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          var index = this.plots[name];
          if(index){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        movePlotToBack: function(name){
         // summary:
         //  Moves a given plot to back.
         // name: String:
         //  Plot's name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.plots){
          var index = this.plots[name];
          if(index < this.stack.length - 1){
           var newOrder = this.getPlotOrder();
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setPlotOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        addSeries: function(name, data, kwArgs){
         // summary:
         //  Add a data series to the chart for rendering.
         // name: String:
         //  The name of the data series to be plotted.
         // data: Array|Object:
         //  The array of data points (either numbers or objects) that
         //  represents the data to be drawn. Or it can be an object. In
         //  the latter case, it should have a property "data" (an array),
         //  destroy(), and setSeriesObject().
         // kwArgs: dojox.charting.__SeriesCtorArgs?:
         //  An optional keyword arguments object that will be mixed into
         //  the resultant series object.
         // returns: dojox.charting.Chart:
         //  A reference to the current chart for functional chaining.
         var run = new dc.Series(this, data, kwArgs);
         run.name = name;
         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/max
         if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
         if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
         return this; // dojox.charting.Chart
        },
        removeSeries: function(name){
         // summary:
         //  Remove the series defined by name from the chart.
         // name: String
         //  The name of the series as defined by addSeries.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          // get the index and remove the name
          var index = this.runs[name];
          delete this.runs[name];
          // destroy the run
          this.series[index].destroy();
          // remove the run from the stack of series
          this.series.splice(index, 1);
          // update indices to reflect the shift
          df.forIn(this.runs, function(idx, name, runs){
           if(idx > index){
            runs[name] = idx - 1;
           }
          });
          this.dirty = true;
         }
         return this; // dojox.charting.Chart
        },
        updateSeries: function(name, data){
         // summary:
         //  Update the given series with a new set of data points.
         // name: String
         //  The name of the series as defined in addSeries.
         // data: Array|Object:
         //  The array of data points (either numbers or objects) that
         //  represents the data to be drawn. Or it can be an object. In
         //  the latter case, it should have a property "data" (an array),
         //  destroy(), and setSeriesObject().
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var run = this.series[this.runs[name]];
          run.update(data);
          this._invalidateDependentPlots(run.plot, false);
          this._invalidateDependentPlots(run.plot, true);
         }
         return this; // dojox.charting.Chart
        },
        getSeriesOrder: function(plotName){
         // summary:
         //  Returns an array of series names in the current order
         //  (the top-most series is the first) within a plot.
         // plotName: String:
         //  Plot's name.
         // returns: Array
         return df.map(df.filter(this.series, function(run){
           return run.plot == plotName;
          }), getName);
        },
        setSeriesOrder: function(newOrder){
         // summary:
         //  Sets new order of series within a plot. newOrder cannot add
         //  or remove series. Wrong names, or dups are ignored.
         // newOrder: Array:
         //  Array of series names compatible with getPlotOrder(). All
         //  series should belong to the same plot.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var plotName, names = {},
          order = df.filter(newOrder, function(name){
           if(!(name in this.runs) || (name in names)){
            return false;
           }
           var run = this.series[this.runs[name]];
           if(plotName){
            if(run.plot != plotName){
             return false;
            }
           }else{
            plotName = run.plot;
           }
           names[name] = 1;
           return true;
          }, this);
         df.forEach(this.series, function(run){
          var name = run.name;
          if(!(name in names) && run.plot == plotName){
           order.push(name);
          }
         });
         var newSeries = df.map(order, function(name){
           return this.series[this.runs[name]];
          }, this);
         this.series = newSeries.concat(df.filter(this.series, function(run){
          return run.plot != plotName;
         }));
         df.forEach(this.series, function(run, i){
          this.runs[run.name] = i;
         }, this);
         this.dirty = true;
         return this; // dojox.charting.Chart
        },
        moveSeriesToFront: function(name){
         // summary:
         //  Moves a given series to front of a plot.
         // name: String:
         //  Series' name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[0]){
           newOrder.splice(index, 1);
           newOrder.unshift(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        moveSeriesToBack: function(name){
         // summary:
         //  Moves a given series to back of a plot.
         // name: String:
         //  Series' name to move.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(name in this.runs){
          var index = this.runs[name],
           newOrder = this.getSeriesOrder(this.series[index].plot);
          if(name != newOrder[newOrder.length - 1]){
           newOrder.splice(index, 1);
           newOrder.push(name);
           return this.setSeriesOrder(newOrder); // dojox.charting.Chart
          }
         }
         return this; // dojox.charting.Chart
        },
        resize: function(width, height){
         // summary:
         //  Resize the chart to the dimensions of width and height.
         // description:
         //  Resize the chart and its surface to the width and height dimensions.
         //  If no width/height or box is provided, resize the surface to the marginBox of the chart.
         // width: Number
         //  The new width of the chart.
         // height: Number
         //  The new height of the chart.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var box;
         switch(arguments.length){
          // case 0, do not resize the div, just the surface
          case 1:
           // argument, override node box
           box = dojo.mixin({}, width);
           dojo.marginBox(this.node, box);
           break;
          case 2:
           box = {w: width, h: height};
           // argument, override node box
           dojo.marginBox(this.node, box);
           break;
         }
         // in all cases take back the computed box
         box = dojo.marginBox(this.node);
         // and set it on the surface
         this.surface.setDimensions(box.w, box.h);
         this.dirty = true;
         this.coords = null;
         return this.render(); // dojox.charting.Chart
        },
        getGeometry: function(){
         // summary:
         //  Returns a map of information about all axes in a chart and what they represent
         //  in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
         // returns: Object
         //  An map of geometry objects, a one-to-one mapping of axes.
         var ret = {};
         df.forIn(this.axes, function(axis){
          if(axis.initialized()){
           ret[axis.name] = {
            name:  axis.name,
            vertical: axis.vertical,
            scaler:  axis.scaler,
            ticks:  axis.ticks
           };
          }
         });
         return ret; // Object
        },
        setAxisWindow: function(name, scale, offset, zoom){
         // summary:
         //  Zooms an axis and all dependent plots. Can be used to zoom in 1D.
         // name: String
         //  The name of the axis as defined by addAxis.
         // scale: Number
         //  The scale on the target axis.
         // offset: Number
         //  Any offest, as measured by axis tick
         // zoom: Boolean|Object?
         //  The chart zooming animation trigger. This is null by default,
         //  e.g. {duration: 1200}, or just set true.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         var axis = this.axes[name];
         if(axis){
          axis.setWindow(scale, offset);
          dojo.forEach(this.stack,function(plot){
           if(plot.hAxis == name || plot.vAxis == name){
            plot.zoom = zoom;
           }
          })
         }
         return this; // dojox.charting.Chart
        },
        setWindow: function(sx, sy, dx, dy, zoom){
         // summary:
         //  Zooms in or out any plots in two dimensions.
         // sx: Number
         //  The scale for the x axis.
         // sy: Number
         //  The scale for the y axis.
         // dx: Number
         //  The pixel offset on the x axis.
         // dy: Number
         //  The pixel offset on the y axis.
         // zoom: Boolean|Object?
         //  The chart zooming animation trigger. This is null by default,
         //  e.g. {duration: 1200}, or just set true.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(!("plotArea" in this)){
          this.calculateGeometry();
         }
         df.forIn(this.axes, function(axis){
          var scale, offset, bounds = axis.getScaler().bounds,
           s = bounds.span / (bounds.upper - bounds.lower);
          if(axis.vertical){
           scale = sy;
           offset = dy / s / scale;
          }else{
           scale = sx;
           offset = dx / s / scale;
          }
          axis.setWindow(scale, offset);
         });
         dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
         return this; // dojox.charting.Chart
        },
        zoomIn: function(name, range){
         // summary:
         //  Zoom the chart to a specific range on one axis. This calls render()
         //  directly as a convenience method.
         // name: String
         //  The name of the axis as defined by addAxis.
         // range: Array
         //  The end points of the zoom range, measured in axis ticks.
         var axis = this.axes[name];
         if(axis){
          var scale, offset, bounds = axis.getScaler().bounds;
          var lower = Math.min(range[0],range[1]);
          var upper = Math.max(range[0],range[1]);
          lower = range[0] < bounds.lower ? bounds.lower : lower;
          upper = range[1] > bounds.upper ? bounds.upper : upper;
          scale = (bounds.upper - bounds.lower) / (upper - lower);
          offset = lower - bounds.lower;
          this.setAxisWindow(name, scale, offset);
          this.render();
         }
        },
        calculateGeometry: function(){
         // summary:
         //  Calculate the geometry of the chart based on the defined axes of
         //  a chart.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(this.dirty){
          return this.fullGeometry();
         }


         // calculate geometry
         var dirty = dojo.filter(this.stack, function(plot){
           return plot.dirty ||
            (plot.hAxis && this.axes[plot.hAxis].dirty) ||
            (plot.vAxis && this.axes[plot.vAxis].dirty);
          }, this);
         calculateAxes(dirty, this.plotArea);


         return this; // dojox.charting.Chart
        },
        fullGeometry: function(){
         // summary:
         //  Calculate the full geometry of the chart. This includes passing
         //  over all major elements of a chart (plots, axes, series, container)
         //  in order to ensure proper rendering.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         this._makeDirty();


         // clear old values
         dojo.forEach(this.stack, clear);


         // rebuild new connections, and add defaults


         // set up a theme
         if(!this.theme){
          this.setTheme(new dojox.charting.Theme(dojox.charting._def));
         }


         // assign series
         dojo.forEach(this.series, function(run){
          if(!(run.plot in this.plots)){
      if(!dc.plot2d || !dc.plot2d.Default){
      throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
      }
           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 axes
         dojo.forEach(this.stack, function(plot){
          if(plot.hAxis){
           plot.setAxis(this.axes[plot.hAxis]);
          }
          if(plot.vAxis){
           plot.setAxis(this.axes[plot.vAxis]);
          }
         }, this);


         // calculate geometry


         // 1st pass
         var dim = this.dim = this.surface.getDimensions();
         dim.width = g.normalizedLength(dim.width);
         dim.height = g.normalizedLength(dim.height);
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, dim);


         // assumption: we don't have stacked axes yet
         var 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 title area
         if(this.title){
          this.titleGap = (this.titleGap==0) ? 0 : this.titleGap || this.theme.chart.titleGap || 20;
          this.titlePos = this.titlePos || this.theme.chart.titlePos || "top";
          this.titleFont = this.titleFont || this.theme.chart.titleFont;
          this.titleFontColor = this.titleFontColor || this.theme.chart.titleFontColor || "black";
          var tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
         }
         // add margins
         df.forIn(this.margins, function(o, i){ offsets[i] += o; });


         // 2nd pass with realistic dimensions
         this.plotArea = {
          width: dim.width - offsets.l - offsets.r,
          height: dim.height - offsets.t - offsets.b
         };
         df.forIn(this.axes, clear);
         calculateAxes(this.stack, this.plotArea);


         return this; // dojox.charting.Chart
        },
        render: function(){
         // summary:
         //  Render the chart according to the current information defined. This should
         //  be the last call made when defining/creating a chart, or if data within the
         //  chart has been changed.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(this.theme){
          this.theme.clear();
         }


         if(this.dirty){
          return this.fullRender();
         }


         this.calculateGeometry();


         // go over the stack backwards
         df.forEachRev(this.stack, function(plot){ plot.render(this.dim, this.offsets); }, this);


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(this.dim, this.offsets); }, this);


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
        },
        fullRender: function(){
         // summary:
         //  Force a full rendering of the chart, including full resets on the chart itself.
         //  You should not call this method directly unless absolutely necessary.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.


         // calculate geometry
         this.fullGeometry();
         var offsets = this.offsets, dim = this.dim, rect;


         // get required colors
         //var requiredColors = df.foldl(this.stack, "z + plot.getRequiredColors()", 0);
         //this.theme.defineColors({num: requiredColors, cache: false});


         // clear old shapes
         dojo.forEach(this.series, purge);
         df.forIn(this.axes, purge);
         dojo.forEach(this.stack, purge);
      if(this.chartTitle && this.chartTitle.tagName){
      // destroy title if it is a DOM node
          dojo.destroy(this.chartTitle);
      }
         this.surface.clear();
      this.chartTitle = null;


         // generate shapes


         // draw a plot background
         var t = this.theme,
          fill = t.plotarea && t.plotarea.fill,
          stroke = t.plotarea && t.plotarea.stroke,
          rect = {
           x: offsets.l - 1, y: offsets.t - 1,
           width: dim.width - offsets.l - offsets.r + 2,
           height: dim.height - offsets.t - offsets.b + 2
          };
         if(fill){
          fill = dc.Element.prototype._shapeFill(dc.Element.prototype._plotFill(fill, dim, offsets), rect);
          this.surface.createRect(rect).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 backwards
         df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);


         // pseudo-clipping: matting
         fill = this.fill !== undefined ? this.fill : (t.chart && t.chart.fill);
         stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);


         // TRT: support for "inherit" as a named value in a theme.
         if(fill == "inherit"){
          // find the background color of the nearest ancestor node, and use that explicitly.
          var node = this.node, fill = new dojo.Color(dojo.style(node, "backgroundColor"));
          while(fill.a==0 && node!=document.documentElement){
           fill = new dojo.Color(dojo.style(node, "backgroundColor"));
           node = node.parentNode;
          }
         }


         if(fill){
          fill = dc.Element.prototype._plotFill(fill, dim, offsets);
          if(offsets.l){ // left
           rect = {
            width: offsets.l,
            height: dim.height + 1
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.r){ // right
           rect = {
            x: dim.width - offsets.r,
            width: offsets.r + 1,
            height: dim.height + 2
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.t){ // top
           rect = {
            width: dim.width + 1,
            height: offsets.t
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
          if(offsets.b){ // bottom
           rect = {
            y: dim.height - offsets.b,
            width: dim.width + 1,
            height: offsets.b + 2
           };
           this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
          }
         }
         if(stroke){
          this.surface.createRect({
           width: dim.width - 1,
           height: dim.height - 1
          }).setStroke(stroke);
         }


         //create title: Whether to make chart title as a widget which extends dojox.charting.Element?
         if(this.title){
          var forceHtmlLabels = (g.renderer == "canvas"),
           labelType = forceHtmlLabels || !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
           tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
          this.chartTitle = dc.axis2d.common.createText[labelType](
           this,
           this.surface,
           dim.width/2,
           this.titlePos=="top" ? tsize + this.margins.t : dim.height - this.margins.b,
           "middle",
           this.title,
           this.titleFont,
           this.titleFontColor
          );
         }


         // go over axes
         df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });


         this._makeClean();


         // BEGIN FOR HTML CANVAS
         if(this.surface.render){ this.surface.render(); };
         // END FOR HTML CANVAS


         return this; // dojox.charting.Chart
        },
        delayedRender: function(){
         // summary:
         //  Delayed render, which is used to collect multiple updates
         //  within a delayInMs time window.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.


         if(!this._delayedRenderHandle){
          this._delayedRenderHandle = setTimeout(
           dojo.hitch(this, function(){
            clearTimeout(this._delayedRenderHandle);
            this._delayedRenderHandle = null;
            this.render();
           }),
           this.delayInMs
          );
         }


         return this; // dojox.charting.Chart
        },
        connectToPlot: function(name, object, method){
         // summary:
         //  A convenience method to connect a function to a plot.
         // name: String
         //  The name of the plot as defined by addPlot.
         // object: Object
         //  The object to be connected.
         // method: Function
         //  The function to be executed.
         // returns: Array
         //  A handle to the connection, as defined by dojo.connect (see dojo.connect).
         return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null; // Array
        },
        fireEvent: function(seriesName, eventName, index){
         // summary:
         //  Fires a synthetic event for a series item.
         // seriesName: String:
         //  Series name.
         // eventName: String:
         //  Event name to simulate: onmouseover, onmouseout, onclick.
         // index: Number:
         //  Valid data value index for the event.
         // returns: dojox.charting.Chart
         //  A reference to the current chart for functional chaining.
         if(seriesName in this.runs){
          var plotName = this.series[this.runs[seriesName]].plot;
          if(plotName in this.plots){
           var plot = this.stack[this.plots[plotName]];
           if(plot){
            plot.fireEvent(seriesName, eventName, index);
           }
          }
         }
         return this; // dojox.charting.Chart
        },
        _makeClean: function(){
         // reset dirty flags
         dojo.forEach(this.axes, makeClean);
         dojo.forEach(this.stack, makeClean);
         dojo.forEach(this.series, makeClean);
         this.dirty = false;
        },
        _makeDirty: function(){
         // reset dirty flags
         dojo.forEach(this.axes, makeDirty);
         dojo.forEach(this.stack, makeDirty);
         dojo.forEach(this.series, makeDirty);
         this.dirty = true;
    • returns
      Object|dojox.charting.Chart|dojox.charting.axis2d.Default|Array
    • summary
  • dojox.charting.Chart._invalidateDependentPlots

    • type
      Function
    • parameters:
      • plotName: (typeof )
      • verticalAxis: (typeof Boolean)
    • source: [view]
         if(plotName in this.plots){
          var plot = this.stack[this.plots[plotName]], axis,
           axisName = verticalAxis ? "vAxis" : "hAxis";
          if(plot[axisName]){
           axis = this.axes[plot[axisName]];
           if(axis && axis.dependOnData()){
            axis.dirty = true;
            // find all plots and mark them dirty
            dojo.forEach(this.stack, function(p){
             if(p[axisName] && p[axisName] == plot[axisName]){
              p.dirty = true;
             }
            });
           }
          }else{
           plot.dirty = true;
          }
         }
    • summary
  • dojox.charting.Chart.coords

    • summary
  • dojox.charting.Chart.theme

    • summary
  • dojox.charting.Chart.dirty

    • summary
  • dojox.charting.Chart.setTheme.theme

    • type
      dojox.charting.Theme
    • summary
      The theme to be used for visual rendering.
  • dojox.charting.Chart.runs

    • summary
  • dojox.charting.Chart.series

    • summary
  • dojox.charting.Chart.stack

    • summary
  • dojox.charting.Chart.dim

    • summary
  • dojox.charting.Chart.offsets

    • summary
  • dojox.charting.Chart.titleGap

    • summary
  • dojox.charting.Chart.titlePos

    • summary
  • dojox.charting.Chart.titleFont

    • summary
  • dojox.charting.Chart.titleFontColor

    • summary
  • dojox.charting.Chart.plotArea

    • summary
  • dojox.charting.Chart.chartTitle

    • summary
  • dojox.charting.Chart._delayedRenderHandle

    • summary
  • dojox.charting.Chart.margins

    • summary
  • dojox.charting.Chart.stroke

    • summary
  • dojox.charting.Chart.fill

    • summary
  • dojox.charting.Chart.delayInMs

    • summary
  • dojox.charting.Chart.title

    • summary
  • dojox.charting.Chart.axes

    • summary
  • dojox.charting.Chart.plots

    • summary
  • dojox.charting.Chart.node

    • summary
  • dojox.charting.Chart.surface

    • summary
  • dojox.charting.__ChartCtorArgs

    • type
      Function
    • parameters:
      • margins: (typeof Object)
        Optional margins for the chart, in the form of { l, t, r, b}.
      • stroke: (typeof dojox.gfx.Stroke)
        An optional outline/stroke for the chart.
      • fill: (typeof dojox.gfx.Fill)
        An optional fill for the chart.
      • delayInMs: (typeof Number)
        Delay in ms for delayedRender(). Default: 200.
    • source: [view]
       this.margins = margins;
       this.stroke = stroke;
       this.fill = fill;
       this.delayInMs = delayInMs;
    • summary
      The keyword arguments that can be passed in a Chart constructor.
  • dojox.charting.__ChartCtorArgs.margins

    • type
      Object?
    • summary
      Optional margins for the chart, in the form of { l, t, r, b}.
  • dojox.charting.__ChartCtorArgs.stroke

    • type
      dojox.gfx.Stroke?
    • summary
      An optional outline/stroke for the chart.
  • dojox.charting.__ChartCtorArgs.fill

    • type
      dojox.gfx.Fill?
    • summary
      An optional fill for the chart.
  • dojox.charting.__ChartCtorArgs.delayInMs

    • type
      Number
    • summary
      Delay in ms for delayedRender(). Default: 200.
  • clear

    • summary
  • purge

    • summary
  • destroy

    • summary
  • makeClean

    • summary
  • makeDirty

    • summary
  • getName

    • summary
  • stats.hmin

    • summary
  • stats.hmax

    • summary
  • stats.vmin

    • summary
  • stats.vmax

    • summary
  • target.min

    • summary
  • target.max

    • summary
  • dojox.charting

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary