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