StackedColumns.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. define("dojox/charting/plot2d/StackedColumns", ["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Columns", "./common",
  2. "dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/functional/sequence"],
  3. function(lang, arr, declare, Columns, dc, df, dfr, dfs){
  4. var purgeGroup = dfr.lambda("item.purgeGroup()");
  5. /*=====
  6. var Columns = dojox.charting.plot2d.Columns;
  7. =====*/
  8. return declare("dojox.charting.plot2d.StackedColumns", Columns, {
  9. // summary:
  10. // The plot object representing a stacked column chart (vertical bars).
  11. getSeriesStats: function(){
  12. // summary:
  13. // Calculate the min/max on all attached series in both directions.
  14. // returns: Object
  15. // {hmin, hmax, vmin, vmax} min/max in both directions.
  16. var stats = dc.collectStackedStats(this.series);
  17. this._maxRunLength = stats.hmax;
  18. stats.hmin -= 0.5;
  19. stats.hmax += 0.5;
  20. return stats;
  21. },
  22. render: function(dim, offsets){
  23. // summary:
  24. // Run the calculations for any axes for this plot.
  25. // dim: Object
  26. // An object in the form of { width, height }
  27. // offsets: Object
  28. // An object of the form { l, r, t, b}.
  29. // returns: dojox.charting.plot2d.StackedColumns
  30. // A reference to this plot for functional chaining.
  31. if(this._maxRunLength <= 0){
  32. return this;
  33. }
  34. // stack all values
  35. var acc = df.repeat(this._maxRunLength, "-> 0", 0);
  36. for(var i = 0; i < this.series.length; ++i){
  37. var run = this.series[i];
  38. for(var j = 0; j < run.data.length; ++j){
  39. var value = run.data[j];
  40. if(value !== null){
  41. var v = typeof value == "number" ? value : value.y;
  42. if(isNaN(v)){ v = 0; }
  43. acc[j] += v;
  44. }
  45. }
  46. }
  47. // draw runs in backwards
  48. if(this.zoom && !this.isDataDirty()){
  49. return this.performZoom(dim, offsets);
  50. }
  51. this.resetEvents();
  52. this.dirty = this.isDirty();
  53. if(this.dirty){
  54. arr.forEach(this.series, purgeGroup);
  55. this._eventSeries = {};
  56. this.cleanGroup();
  57. var s = this.group;
  58. df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
  59. }
  60. var t = this.chart.theme, f, gap, width,
  61. ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
  62. vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
  63. events = this.events();
  64. f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
  65. gap = f.gap;
  66. width = f.size;
  67. for(var i = this.series.length - 1; i >= 0; --i){
  68. var run = this.series[i];
  69. if(!this.dirty && !run.dirty){
  70. t.skip();
  71. this._reconnectEvents(run.name);
  72. continue;
  73. }
  74. run.cleanGroup();
  75. var theme = t.next("column", [this.opt, run]), s = run.group,
  76. eventSeries = new Array(acc.length);
  77. for(var j = 0; j < acc.length; ++j){
  78. var value = run.data[j];
  79. if(value !== null){
  80. var v = acc[j],
  81. height = vt(v),
  82. finalTheme = typeof value != "number" ?
  83. t.addMixin(theme, "column", value, true) :
  84. t.post(theme, "column");
  85. if(width >= 1 && height >= 0){
  86. var rect = {
  87. x: offsets.l + ht(j + 0.5) + gap,
  88. y: dim.height - offsets.b - vt(v),
  89. width: width, height: height
  90. };
  91. var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
  92. specialFill = this._shapeFill(specialFill, rect);
  93. var shape = s.createRect(rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
  94. run.dyn.fill = shape.getFill();
  95. run.dyn.stroke = shape.getStroke();
  96. if(events){
  97. var o = {
  98. element: "column",
  99. index: j,
  100. run: run,
  101. shape: shape,
  102. x: j + 0.5,
  103. y: v
  104. };
  105. this._connectEvents(o);
  106. eventSeries[j] = o;
  107. }
  108. if(this.animate){
  109. this._animateColumn(shape, dim.height - offsets.b, height);
  110. }
  111. }
  112. }
  113. }
  114. this._eventSeries[run.name] = eventSeries;
  115. run.dirty = false;
  116. // update the accumulator
  117. for(var j = 0; j < run.data.length; ++j){
  118. var value = run.data[j];
  119. if(value !== null){
  120. var v = typeof value == "number" ? value : value.y;
  121. if(isNaN(v)){ v = 0; }
  122. acc[j] -= v;
  123. }
  124. }
  125. }
  126. this.dirty = false;
  127. return this; // dojox.charting.plot2d.StackedColumns
  128. }
  129. });
  130. });