dojox/charting/plot2d/Pie.js

  • Provides:

    • dojox.charting.plot2d.Pie
  • Requires:

    • dojox.charting.Element in common
    • dojox.charting.axis2d.common in common
    • dojox.charting.plot2d.common in common
    • dojox.charting.plot2d._PlotEvents in common
    • dojox.lang.functional in common
    • dojox.lang.utils in common
    • dojox.gfx in common
  • dojox.charting.plot2d.__PieCtorArgs

    • type
      Function
    • chains:
      • dojox.charting.plot2d.__DefaultCtorArgs: (prototype)
      • dojox.charting.plot2d.__DefaultCtorArgs: (call)
    • summary
      Specialized keyword arguments object for use in defining parameters on a Pie chart.
  • dojox.charting.plot2d.__PieCtorArgs.labels

    • type
      Boolean
    • summary
      Whether or not to draw labels within each pie slice.  Default is true.
  • dojox.charting.plot2d.__PieCtorArgs.ticks

    • type
      Boolean
    • summary
      Whether or not to draw ticks to labels within each slice. Default is false.
  • dojox.charting.plot2d.__PieCtorArgs.fixed

    • type
      Boolean
    • summary
      TODO
  • dojox.charting.plot2d.__PieCtorArgs.precision

    • type
      Number
    • summary
      The precision at which to sum/add data values. Default is 1.
  • dojox.charting.plot2d.__PieCtorArgs.labelOffset

    • type
      Number
    • summary
      The amount in pixels by which to offset labels.  Default is 20.
  • dojox.charting.plot2d.__PieCtorArgs.labelStyle

    • type
      String
    • summary
      Options as to where to draw labels.  Values include "default", "rows", and "auto". Default is "default".
  • dojox.charting.plot2d.__PieCtorArgs.htmlLabels

    • type
      Boolean
    • summary
      Whether or not to use HTML to render slice labels. Default is true.
  • dojox.charting.plot2d.__PieCtorArgs.radGrad

    • type
      String
    • summary
      The type of radial gradient to use in rendering.  Default is "native".
  • dojox.charting.plot2d.__PieCtorArgs.fanSize

    • type
      Number
    • summary
      The amount for a radial gradient.  Default is 5.
  • dojox.charting.plot2d.__PieCtorArgs.startAngle

    • type
      Number
    • summary
      Where to being rendering gradients in slices, in degrees.  Default is 0.
  • dojox.charting.plot2d.__PieCtorArgs.radius

    • type
      Number
    • summary
      The size of the radial gradient.  Default is 0.
  • dojox.charting.plot2d.Pie

    • type
      Function
    • chains:
      • dojox.charting.Element: (prototype)
      • dojox.charting.Element: (call)
      • dojox.charting.plot2d._PlotEvents: (call)
    • mixins:
      • dojox.charting.plot2d._PlotEvents.prototype: (prototype)
    • summary
      Create a pie plot.
    • parameters:
      • chart: (typeof )
      • kwArgs: (typeof )
    • source: [view]
         this.opt = dojo.clone(this.defaultParams);
         du.updateWithObject(this.opt, kwArgs);
         du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
         this.run = null;
         this.dyn = [];
  • dojox.charting.plot2d.Pie.defaultParams

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.optionalParams

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.clear

    • type
      Function
    • source: [view]
         this.dirty = true;
         this.dyn = [];
         this.run = null;
         return this; // dojox.charting.plot2d.Pie
    • summary
      Clear out all of the information tied to this plot.
    • return_summary
      dojox.charting.plot2d.Pie
      A reference to this plot for functional chaining.
    • returns
      dojox.charting.plot2d.Pie
  • dojox.charting.plot2d.Pie.setAxis

    • type
      Function
    • parameters:
      • axis: (typeof )
    • source: [view]
         return this; // dojox.charting.plot2d.Pie
    • summary
      Dummy method, since axes are irrelevant with a Pie chart.
    • return_summary
      dojox.charting.plot2d.Pie
      The reference to this plot for functional chaining.
    • returns
      dojox.charting.plot2d.Pie
  • dojox.charting.plot2d.Pie.addSeries

    • type
      Function
    • parameters:
      • run: (typeof )
    • source: [view]
         this.run = run;
         return this; // dojox.charting.plot2d.Pie
    • summary
      Add a series of data to this plot.
    • return_summary
      dojox.charting.plot2d.Pie
      The reference to this plot for functional chaining.
    • returns
      dojox.charting.plot2d.Pie
  • dojox.charting.plot2d.Pie.getSeriesStats

    • type
      Function
    • source: [view]
         return dojo.delegate(dc.defaultStats);
    • summary
      Returns default stats (irrelevant for this type of plot).
    • return_summary
      Object
      {hmin, hmax, vmin, vmax} min/max in both directions.
  • dojox.charting.plot2d.Pie.initializeScalers

    • type
      Function
    • source: [view]
         return this;
    • summary
      Does nothing (irrelevant for this type of plot).
  • dojox.charting.plot2d.Pie.getRequiredColors

    • type
      Function
    • source: [view]
         return this.run ? this.run.data.length : 0;
    • summary
      Return the number of colors needed to draw this plot.
  • dojox.charting.plot2d.Pie.render

    • type
      Function
    • parameters:
      • dim: (typeof Object)
        An object of the form { width, height }.
      • offsets: (typeof Object)
        An object of the form { l, r, t, b }.
    • source: [view]
         if(!this.dirty){ return this; }
         this.resetEvents();
         this.dirty = false;
         this._eventSeries = {};
         this.cleanGroup();
         var s = this.group, t = this.chart.theme;


         if(!this.run || !this.run.data.length){
          return this;
         }


         // calculate the geometry
         var rx = (dim.width - offsets.l - offsets.r) / 2,
          ry = (dim.height - offsets.t - offsets.b) / 2,
          r = Math.min(rx, ry),
          taFont = "font" in this.opt ? this.opt.font : t.axis.font,
          size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
          taFontColor = "fontColor" in this.opt ? this.opt.fontColor : t.axis.fontColor,
          startAngle = m._degToRad(this.opt.startAngle),
          start = startAngle, step, filteredRun, slices, labels, shift, labelR,
          run = this.run.data,
          events = this.events();
         if(typeof run[0] == "number"){
          filteredRun = df.map(run, "x ? Math.max(x, 0) : 0");
          if(df.every(filteredRun, "<= 0")){
           return this;
          }
          slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
          if(this.opt.labels){
           labels = dojo.map(slices, function(x){
            return x > 0 ? this._getLabel(x * 100) + "%" : "";
           }, this);
          }
         }else{
          filteredRun = df.map(run, "x ? Math.max(x.y, 0) : 0");
          if(df.every(filteredRun, "<= 0")){
           return this;
          }
          slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
          if(this.opt.labels){
           labels = dojo.map(slices, function(x, i){
            if(x <= 0){ return ""; }
            var v = run[i];
            return "text" in v ? v.text : this._getLabel(x * 100) + "%";
           }, this);
          }
         }
         var themes = df.map(run, function(v, i){
          if(v === null || typeof v == "number"){
           return t.next("slice", [this.opt, this.run], true);
          }
          return t.next("slice", [this.opt, this.run, v], true);
         }, this);
         if(this.opt.labels){
          shift = df.foldl1(df.map(labels, function(label, i){
           var font = themes[i].series.font;
           return dojox.gfx._base._getTextBox(label, {font: font}).w;
          }, this), "Math.max(a, b)") / 2;
          if(this.opt.labelOffset < 0){
           r = Math.min(rx - 2 * shift, ry - size) + this.opt.labelOffset;
          }
          labelR = r - this.opt.labelOffset;
         }
         if("radius" in this.opt){
          r = this.opt.radius;
          labelR = r - this.opt.labelOffset;
         }
         var circle = {
           cx: offsets.l + rx,
           cy: offsets.t + ry,
           r: r
          };


         this.dyn = [];
         // draw slices
         var eventSeries = new Array(slices.length);
         dojo.some(slices, function(slice, i){
          if(slice <= 0){
           // degenerated slice
           return false; // continue
          }
          var v = run[i], theme = themes[i], specialFill;
          if(slice >= 1){
           // whole pie
           specialFill = this._plotFill(theme.series.fill, dim, offsets);
           specialFill = this._shapeFill(specialFill,
            {
             x: circle.cx - circle.r, y: circle.cy - circle.r,
             width: 2 * circle.r, height: 2 * circle.r
            });
           specialFill = this._pseudoRadialFill(specialFill, {x: circle.cx, y: circle.cy}, circle.r);
           var shape = s.createCircle(circle).setFill(specialFill).setStroke(theme.series.stroke);
           this.dyn.push({fill: specialFill, stroke: theme.series.stroke});


           if(events){
            var o = {
             element: "slice",
             index: i,
             run: this.run,
             shape: shape,
             x: i,
             y: typeof v == "number" ? v : v.y,
             cx: circle.cx,
             cy: circle.cy,
             cr: r
            };
            this._connectEvents(o);
            eventSeries[i] = o;
           }


           return true; // stop iteration
          }
          // calculate the geometry of the slice
          var end = start + slice * 2 * Math.PI;
          if(i + 1 == slices.length){
           end = startAngle + 2 * Math.PI;
          }
          var step = end - start,
           x1 = circle.cx + r * Math.cos(start),
           y1 = circle.cy + r * Math.sin(start),
           x2 = circle.cx + r * Math.cos(end),
           y2 = circle.cy + r * Math.sin(end);
          // draw the slice
          var fanSize = m._degToRad(this.opt.fanSize);
          if(theme.series.fill && theme.series.fill.type === "radial" && this.opt.radGrad === "fan" && step > fanSize){
           var group = s.createGroup(), nfans = Math.ceil(step / fanSize), delta = step / nfans;
           specialFill = this._shapeFill(theme.series.fill,
            {x: circle.cx - circle.r, y: circle.cy - circle.r, width: 2 * circle.r, height: 2 * circle.r});
           for(var j = 0; j < nfans; ++j){
            var fansx = j == 0 ? x1 : circle.cx + r * Math.cos(start + (j - FUDGE_FACTOR) * delta),
             fansy = j == 0 ? y1 : circle.cy + r * Math.sin(start + (j - FUDGE_FACTOR) * delta),
             fanex = j == nfans - 1 ? x2 : circle.cx + r * Math.cos(start + (j + 1 + FUDGE_FACTOR) * delta),
             faney = j == nfans - 1 ? y2 : circle.cy + r * Math.sin(start + (j + 1 + FUDGE_FACTOR) * delta),
             fan = group.createPath({}).
              moveTo(circle.cx, circle.cy).
              lineTo(fansx, fansy).
              arcTo(r, r, 0, delta > Math.PI, true, fanex, faney).
              lineTo(circle.cx, circle.cy).
              closePath().
              setFill(this._pseudoRadialFill(specialFill, {x: circle.cx, y: circle.cy}, r, start + (j + 0.5) * delta, start + (j + 0.5) * delta));
           }
           group.createPath({}).
            moveTo(circle.cx, circle.cy).
            lineTo(x1, y1).
            arcTo(r, r, 0, step > Math.PI, true, x2, y2).
            lineTo(circle.cx, circle.cy).
            closePath().
            setStroke(theme.series.stroke);
           shape = group;
          }else{
           shape = s.createPath({}).
            moveTo(circle.cx, circle.cy).
            lineTo(x1, y1).
            arcTo(r, r, 0, step > Math.PI, true, x2, y2).
            lineTo(circle.cx, circle.cy).
            closePath().
            setStroke(theme.series.stroke);
           var specialFill = theme.series.fill;
           if(specialFill && specialFill.type === "radial"){
            specialFill = this._shapeFill(specialFill, {x: circle.cx - circle.r, y: circle.cy - circle.r, width: 2 * circle.r, height: 2 * circle.r});
            if(this.opt.radGrad === "linear"){
             specialFill = this._pseudoRadialFill(specialFill, {x: circle.cx, y: circle.cy}, r, start, end);
            }
           }else if(specialFill && specialFill.type === "linear"){
            specialFill = this._plotFill(specialFill, dim, offsets);
            specialFill = this._shapeFill(specialFill, shape.getBoundingBox());
           }
           shape.setFill(specialFill);
          }
          this.dyn.push({fill: specialFill, stroke: theme.series.stroke});


          if(events){
           var o = {
            element: "slice",
            index: i,
            run: this.run,
            shape: shape,
            x: i,
            y: typeof v == "number" ? v : v.y,
            cx: circle.cx,
            cy: circle.cy,
            cr: r
           };
           this._connectEvents(o);
           eventSeries[i] = o;
          }


          start = end;


          return false; // continue
         }, this);
         // draw labels
         if(this.opt.labels){
          if(this.opt.labelStyle == "default"){
           start = startAngle;
           dojo.some(slices, function(slice, i){
            if(slice <= 0){
             // degenerated slice
             return false; // continue
            }
            var theme = themes[i];
            if(slice >= 1){
             // whole pie
             var v = run[i], elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"](
               this.chart, s, circle.cx, circle.cy + size / 2, "middle", labels[i],
               theme.series.font, theme.series.fontColor);
             if(this.opt.htmlLabels){
              this.htmlElements.push(elem);
             }
             return true; // stop iteration
            }
            // calculate the geometry of the slice
            var end = start + slice * 2 * Math.PI, v = run[i];
            if(i + 1 == slices.length){
             end = startAngle + 2 * Math.PI;
            }
            var labelAngle = (start + end) / 2,
             x = circle.cx + labelR * Math.cos(labelAngle),
             y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
            // draw the label
            var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
              (this.chart, s, x, y, "middle", labels[i], theme.series.font, theme.series.fontColor);
            if(this.opt.htmlLabels){
             this.htmlElements.push(elem);
            }
            start = end;
            return false; // continue
           }, this);
          }else if(this.opt.labelStyle == "columns"){
           start = startAngle;
           //calculate label angles
           var labeledSlices = [];
           dojo.forEach(slices, function(slice, i){
            var end = start + slice * 2 * Math.PI;
            if(i + 1 == slices.length){
             end = startAngle + 2 * Math.PI;
            }
            var labelAngle = (start + end) / 2;
            labeledSlices.push({
             angle: labelAngle,
             left: Math.cos(labelAngle) < 0,
             theme: themes[i],
             index: i,
             omit: end - start < 0.001
            });
            start = end;
           });
           //calculate label radius to each slice
           var labelHeight = dojox.gfx._base._getTextBox("a",{font:taFont}).h;
           this._getProperLabelRadius(labeledSlices, labelHeight, circle.r * 1.1);
           //draw label and wiring
           dojo.forEach(labeledSlices, function(slice, i){
            if (!slice.omit) {
             var leftColumn = circle.cx - circle.r * 2,
              rightColumn = circle.cx + circle.r * 2,
              labelWidth = dojox.gfx._base._getTextBox(labels[i], {font: taFont}).w,
              x = circle.cx + slice.labelR * Math.cos(slice.angle),
              y = circle.cy + slice.labelR * Math.sin(slice.angle),
              jointX = (slice.left) ? (leftColumn + labelWidth) : (rightColumn - labelWidth),
              labelX = (slice.left) ? leftColumn : jointX;
             var wiring = s.createPath().moveTo(circle.cx + circle.r * Math.cos(slice.angle), circle.cy + circle.r * Math.sin(slice.angle))
             if (Math.abs(slice.labelR * Math.cos(slice.angle)) < circle.r * 2 - labelWidth) {
              wiring.lineTo(x, y);
             }
             wiring.lineTo(jointX, y).setStroke(slice.theme.series.labelWiring);
             var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"](
              this.chart, s, labelX, y, "left", labels[i], slice.theme.series.font, slice.theme.series.fontColor);
             if (this.opt.htmlLabels) {
              this.htmlElements.push(elem);
             }
            }
           },this);
          }
         }
         // post-process events to restore the original indexing
         var esi = 0;
         this._eventSeries[this.run.name] = df.map(run, function(v){
          return v <= 0 ? null : eventSeries[esi++];
         });
         return this; // dojox.charting.plot2d.Pie
    • summary
      Render the plot on the chart.
    • return_summary
      dojox.charting.plot2d.Pie
      A reference to this plot for functional chaining.
    • returns
      continue|stop iteration|dojox.charting.plot2d.Pie
  • dojox.charting.plot2d.Pie._getProperLabelRadius

    • type
      Function
    • parameters:
      • slices: (typeof )
      • labelHeight: (typeof )
      • minRidius: (typeof )
    • source: [view]
         var leftCenterSlice = {},rightCenterSlice = {},leftMinSIN = 1, rightMinSIN = 1;
         if (slices.length == 1) {
          slices[0].labelR = minRidius;
          return;
         }
         for(var i = 0;i    var tempSIN = Math.abs(Math.sin(slices[i].angle));
          if(slices[i].left){
           if(leftMinSIN > tempSIN){
            leftMinSIN = tempSIN;
            leftCenterSlice = slices[i];
           }
          }else{
           if(rightMinSIN > tempSIN){
            rightMinSIN = tempSIN;
            rightCenterSlice = slices[i];
           }
          }
         }
         leftCenterSlice.labelR = rightCenterSlice.labelR = minRidius;
         this._caculateLabelR(leftCenterSlice,slices,labelHeight);
         this._caculateLabelR(rightCenterSlice,slices,labelHeight);
    • summary
  • dojox.charting.plot2d.Pie._caculateLabelR

    • type
      Function
    • parameters:
      • firstSlice: (typeof )
      • slices: (typeof )
      • labelHeight: (typeof )
    • source: [view]
         var i = firstSlice.index,length = slices.length,
          currentLabelR = firstSlice.labelR;
         while(!(slices[i%length].left ^ slices[(i+1)%length].left)){
          if (!slices[(i + 1) % length].omit) {
           var nextLabelR = (Math.sin(slices[i % length].angle) * currentLabelR + ((slices[i % length].left) ? (-labelHeight) : labelHeight)) /
           Math.sin(slices[(i + 1) % length].angle);
           currentLabelR = (nextLabelR < firstSlice.labelR) ? firstSlice.labelR : nextLabelR;
           slices[(i + 1) % length].labelR = currentLabelR;
          }
          i++;
         }
         i = firstSlice.index,j = (i == 0)?length-1 : i - 1;
         while(!(slices[i].left ^ slices[j].left)){
          if (!slices[j].omit) {
           var nextLabelR = (Math.sin(slices[i].angle) * currentLabelR + ((slices[i].left) ? labelHeight : (-labelHeight))) /
           Math.sin(slices[j].angle);
           currentLabelR = (nextLabelR < firstSlice.labelR) ? firstSlice.labelR : nextLabelR;
           slices[j].labelR = currentLabelR;
          }
          i--;j--;
          i = (i < 0)?i+slices.length:i;
          j = (j < 0)?j+slices.length:j;
         }
    • summary
  • dojox.charting.plot2d.Pie._getLabel

    • type
      Function
    • parameters:
      • number: (typeof )
    • source: [view]
         return dc.getLabel(number, this.opt.fixed, this.opt.precision);
    • summary
  • dojox.charting.plot2d.Pie.defaultParams.labels

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.ticks

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.fixed

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.precision

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.labelOffset

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.labelStyle

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.htmlLabels

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.radGrad

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.fanSize

    • summary
  • dojox.charting.plot2d.Pie.defaultParams.startAngle

    • summary
  • dojox.charting.plot2d.Pie.optionalParams.radius

    • summary
  • dojox.charting.plot2d.Pie.optionalParams.stroke

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.optionalParams.outline

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.optionalParams.shadow

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.optionalParams.fill

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.optionalParams.font

    • summary
  • dojox.charting.plot2d.Pie.optionalParams.fontColor

    • summary
  • dojox.charting.plot2d.Pie.optionalParams.labelWiring

    • type
      Object
    • summary
  • dojox.charting.plot2d.Pie.dirty

    • summary
  • dojox.charting.plot2d.Pie.dyn

    • summary
  • dojox.charting.plot2d.Pie.run

    • summary
  • dojox.charting.plot2d.Pie._eventSeries

    • summary
  • dojox.charting.plot2d.Pie.opt.radGrad

    • summary
  • dojox.charting.plot2d.Pie.opt.labelStyle

    • summary
  • dojox.charting.plot2d.Pie.opt

    • summary
  • dc

    • summary
  • da

    • summary
  • g

    • summary
  • FUDGE_FACTOR

    • summary
  • dojox.charting.plot2d

    • type
      Object
    • summary
  • dojox.charting

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary