1 //Class AreaChart2 : Chart
  2 //This is the custom wrapper class for protovis area/line charts
  3 
  4 //Constructor
  5 wso2vis.s.chart.protovis.AreaChart2 = function(div, chartTitle, chartDesc) {
  6     wso2vis.s.chart.Chart.call(this, div, chartTitle, chartDesc);
  7 
  8     this.band(12)
  9         .xSuffix("")
 10         .ySuffix("");
 11 
 12     /* @private */
 13     this.vis = null;
 14     this.x = null;
 15     this.y = null;
 16     this.customXticks = null;
 17 };
 18 
 19 // this makes AreaChart2.prototype inherit from Chart
 20 wso2vis.extend(wso2vis.s.chart.protovis.AreaChart2, wso2vis.s.chart.Chart);
 21 
 22 wso2vis.s.chart.protovis.AreaChart2.prototype
 23     .property("dataField")
 24     .property("subDataField")
 25     .property("xDataValue")
 26     .property("yDataValue")
 27     .property("dataLabel")
 28     .property("xSuffix")
 29     .property("ySuffix")
 30     .property("xLabel")
 31     .property("band");
 32 
 33 //Public function load
 34 //Loads the chart inside the given HTML element
 35 wso2vis.s.chart.protovis.AreaChart2.prototype.load = function (w, h) {
 36     if ( w !== undefined ) {
 37         this.width(w);
 38     }
 39     if ( h !== undefined ) {
 40         this.height(h);
 41     }
 42 
 43     var thisObject = this;
 44 
 45     this.x = pv.Scale.linear(0, 4).range(0, this.width());
 46     this.y = pv.Scale.linear(0, 50).range(0, this.height()*0.9);
 47     this.customXticks = [];
 48  
 49     this.vis = new pv.Panel()
 50         .canvas(function() { return thisObject.divEl(); })
 51         .width(function() { return thisObject.width(); })
 52         .height(function() { return thisObject.height(); })
 53         .bottom(20)
 54         .top(0)
 55         .left(30)
 56         .right(10);
 57 
 58     var panel = this.vis.add(pv.Panel)
 59         .data(function() { return thisObject.getData(thisObject); })
 60         .top(function() { return (thisObject.height() * (1 - thisObject.titleSpacing())); })
 61         .height(function() { return (thisObject.height() * thisObject.titleSpacing()); })
 62         .strokeStyle("#ccc");
 63 
 64     var area = panel.add(pv.Area)
 65         .data(function(a) { return a; })
 66         .left(function(d) { return thisObject.x(d.x); })
 67         .bottom(0)//pv.Layout.stack())
 68         .height(function(d) { return thisObject.y(d.y); })
 69         .title(function() {
 70             var dataObj = thisObject.traverseToDataField(thisObject.data, thisObject.dataField());
 71             if( dataObj instanceof Array ) {
 72                 return thisObject.onTooltip(dataObj[this.parent.index]);
 73             }
 74             else {
 75                 return thisObject.onTooltip(dataObj);
 76             }
 77         })
 78         .event("click", function() {
 79             var dataObj = thisObject.traverseToDataField(thisObject.data, thisObject.dataField());
 80             if( dataObj instanceof Array ) {
 81                 return thisObject.onClick(dataObj[this.parent.index]);
 82             }
 83             else {
 84                 return thisObject.onClick(dataObj);
 85             }
 86         });
 87 
 88     var areaDot = area.anchor("top").add(pv.Dot).title(function(d) { return d.y; })
 89         .visible(function() { return thisObject.marks(); })
 90         .fillStyle("#fff")
 91         .size(10);
 92         //.add(pv.Label);
 93 
 94     /* Legend */
 95     panel.add(pv.Dot)
 96         .visible(function() { return thisObject.legend(); })
 97         .right(100)
 98         .fillStyle(function() { return area.fillStyle(); })
 99         .bottom(function() { return (this.parent.index * 15) + 10; })
100         .size(20) 
101         .lineWidth(1)
102         .strokeStyle("#000")
103       .anchor("right").add(pv.Label)
104         .text(function() { return thisObject.getDataLabel(this.parent.index); });
105      
106     panel.add(pv.Rule)
107         .data(function() { return thisObject.customXticks; /*thisObject.x.ticks();*/ })
108         .visible(function(d) { return (d > 0); })
109         .left(function(d) { return (Math.round(thisObject.x(d)) - 0.5); })
110         .strokeStyle("rgba(128,128,128,.1)")
111       .anchor("bottom").add(pv.Label)
112         .text(function(d) { return d.toFixed() + thisObject.xSuffix(); })
113         .font(function() { return thisObject.labelFont(); })
114         .textStyle("rgba(128,128,128,0.5)");
115      
116     panel.add(pv.Rule)
117         .data(function() { return thisObject.y.ticks(); })
118         .visible(function() { return !(this.parent.index % 2); })
119         .bottom(function(d) { return (Math.round(thisObject.y(d)) - 0.5); })
120         .strokeStyle("rgba(128,128,128,.2)")
121       .anchor("left").add(pv.Label)
122         .text(function(d) {return d.toFixed() + thisObject.ySuffix(); })
123         .font(function() { return thisObject.labelFont(); })
124         .textStyle("rgba(128,128,128,0.5)");
125 
126     this.vis.add(pv.Label)
127         .left(this.width() / 2)
128         .visible(function() { return !(thisObject.title() === ""); })
129         .top(16)
130         .textAlign("center")
131         .text(function() { return thisObject.title(); })
132         .font(function() { return thisObject.titleFont(); });
133 };
134 
135 /**
136 * @private
137 */
138 wso2vis.s.chart.protovis.AreaChart2.prototype.titleSpacing = function () {
139     if(this.title() === "") {
140         return 1;
141     }
142     else {
143         return 0.9;
144     }
145 };
146 
147 /**
148 * @private 
149 */
150 wso2vis.s.chart.protovis.AreaChart2.prototype.populateData = function (thisObject) {
151     var _dataField = thisObject.traverseToDataField(thisObject.data, thisObject.dataField());
152     var tempDataArray = [];
153 
154     var dataGrpCount = 1;
155     if( _dataField instanceof Array ) {
156         dataGrpCount = _dataField.length;
157     }
158 
159     thisObject.formattedData = pv.range(dataGrpCount).map(genDataMap);
160     var xMax = 0;
161     var xMin = Infinity;
162 
163     for (var x=0; x<thisObject.formattedData.length; x++) {
164         var dataSet = thisObject.formattedData[x];
165         for (var y=0; y<dataSet.length; y++) {
166             xMax = (xMax < dataSet[y].x) ? dataSet[y].x : xMax;
167             xMin = (xMin > dataSet[y].x) ? dataSet[y].x : xMin;
168             //TODO clean up this. we need only one data set
169             thisObject.customXticks[y] = dataSet[y].x;
170         }
171     }
172 
173     var maxheight = tempDataArray.max();
174     if (maxheight < 5) maxheight = 5; // fixing value repeating issue.
175     if (thisObject.xDataValue() === undefined) {
176         thisObject.x.domain(0, thisObject.band()).range(0, this.width());
177     }
178     else {
179         //thisObject.x.domain(thisObject.formattedData[0], function(d) { return d.x; }).range(0, this.width());
180         thisObject.x.domain(xMin, xMax).range(0, this.width());
181     }
182     thisObject.y.domain(0, maxheight).range(0, (thisObject.height() * thisObject.titleSpacing()) - 35);
183     thisObject.y.nice();
184     
185     function genDataMap(x) {
186         var innerArray = [];
187         var rootObja;
188         if( _dataField instanceof Array ) {
189             rootObja = _dataField[x];
190         }
191         else {
192             rootObja = _dataField;
193         }
194 
195         var _subDataField = thisObject.traverseToDataField(rootObja, thisObject.subDataField());
196 
197         var subDataGrpCount = 1;
198         if( _subDataField instanceof Array ) {
199             subDataGrpCount = _subDataField.length;
200         }
201 
202         for(var y=0; y<subDataGrpCount; y++) {
203             var rootObjb;
204             if( _subDataField instanceof Array ) {
205                 rootObjb = _subDataField[y];
206             }
207             else {
208                 rootObjb = _subDataField;
209             }
210 
211             var valObjY = parseInt(thisObject.traverseToDataField(rootObjb, thisObject.yDataValue()));
212             tempDataArray.push(valObjY);
213 
214             if (thisObject.xDataValue() === undefined) {
215                 innerArray.push(valObjY);
216             }
217             else {
218                 var valObjX = parseInt(thisObject.traverseToDataField(rootObjb, thisObject.xDataValue()));
219                 innerArray.push({ x: valObjX, y: valObjY });
220             }
221         }
222         return innerArray;
223     }
224 };
225 
226 wso2vis.s.chart.protovis.AreaChart2.prototype.getData = function (thisObject) {
227     return thisObject.formattedData;
228 };
229 
230 wso2vis.s.chart.protovis.AreaChart2.prototype.update = function () {
231     this.populateData(this);
232     this.vis.render();
233     if(this.tooltip() === true) {
234         tooltip.init();
235     }
236 };
237 
238 wso2vis.s.chart.protovis.AreaChart2.prototype.getDataLabel = function (i) {
239     if (this.data !== null){
240         var rootObj = this.traverseToDataField(this.data, this.dataField());
241         if( rootObj instanceof Array ) {
242             return  this.traverseToDataField(rootObj[i], this.dataLabel());
243         }
244         else {
245             return  this.traverseToDataField(rootObj, this.dataLabel());
246         }
247     }
248     return i;
249 };
250 
251