1 //Class c.protovis.BarChart : Chart 2 //This is the custom wrapper class for protovis bar charts 3 4 //Constructor 5 wso2vis.s.chart.protovis.BarChart = function(canvas, chartTitle, chartDesc) { 6 wso2vis.s.chart.Chart.call(this, canvas, chartTitle, chartDesc); 7 8 /* @private */ 9 this.vis = null; 10 this.y = null; 11 this.x = null; 12 13 this.legendText("Data 1"); 14 } 15 16 // this makes c.protovis.BarChart.prototype inherits 17 // from Chart.prototype 18 wso2vis.extend(wso2vis.s.chart.protovis.BarChart, wso2vis.s.chart.Chart); 19 20 wso2vis.s.chart.protovis.BarChart.prototype 21 .property("dataField") 22 .property("dataValue") 23 .property("dataLabel") 24 .property("ySuffix") 25 .property("xSuffix") 26 .property("titleTop") 27 .property("titleLeft") 28 .property("titleRight") 29 .property("titleBottom") 30 .property("xTitle") 31 .property("yTitle") 32 .property("legendText") 33 .property("segmentBorderColor"); 34 35 //Public function load 36 //Loads the chart inside the given HTML element 37 wso2vis.s.chart.protovis.BarChart.prototype.load = function (w, h) { 38 if ( w !== undefined ) { 39 this.width(w); 40 } 41 if ( h !== undefined ) { 42 this.height(h); 43 } 44 45 var thisObject = this; 46 47 this.x = pv.Scale.linear(0, 1).range(0, this.width()); 48 this.y = pv.Scale.ordinal(pv.range(3)).splitBanded(0, this.height(), 4/5); 49 50 this.vis = new pv.Panel() 51 .canvas(function() { return thisObject.divEl(); }) 52 .width(function() { return thisObject.width(); }) 53 .height(function() { return thisObject.height(); }); 54 55 var chart = this.vis.add(pv.Panel) 56 .width(function() { return (thisObject.width() - thisObject.paddingLeft() - thisObject.paddingRight()); }) 57 .height(function() { return (thisObject.height() - thisObject.paddingTop() - thisObject.paddingBottom()); }) 58 .top(thisObject.paddingTop()) 59 .bottom(thisObject.paddingBottom()) 60 .left(thisObject.paddingLeft()) 61 .right(thisObject.paddingRight()); 62 63 /* Draw Bars */ 64 var bar = chart.add(pv.Bar) 65 .data(function() { return thisObject.getData(thisObject); }) 66 .top(function() { return thisObject.y(this.index); }) 67 .height(function() { return thisObject.y.range().band; }) 68 .width(thisObject.x) 69 .left(0) 70 //.strokeStyle("rgba(15, 55, 90, .9)") 71 .fillStyle("rgba(31, 119, 180, 1)") 72 .title(function() { 73 var dataObj = thisObject.traverseToDataField(thisObject.data, thisObject.dataField()); 74 if( dataObj instanceof Array ) { 75 return thisObject.onTooltip(dataObj[this.index]); 76 } 77 else { 78 return thisObject.onTooltip(dataObj); 79 } 80 }) 81 .event("click", function() { 82 var dataObj = thisObject.traverseToDataField(thisObject.data, thisObject.dataField()); 83 if( dataObj instanceof Array ) { 84 return thisObject.onClick(dataObj[this.index]); 85 } 86 else { 87 return thisObject.onClick(dataObj); 88 } 89 }); 90 91 /* marks */ 92 bar.anchor("right").add(pv.Label) 93 .visible(function() { return thisObject.marks(); }) 94 .textStyle("white") 95 .textMargin(5) 96 .text(function(d) { return d; }); 97 98 /* legend */ 99 chart.add(pv.Dot) 100 .data(function() { return [thisObject.legendText()]; }) 101 .visible(function() { return thisObject.legend(); }) 102 .left(function() { return thisObject.legendX(); }) 103 .top(function() { return thisObject.legendY(); }) 104 .fillStyle(function() { return bar.fillStyle(); }) 105 .size(20) 106 .lineWidth(1) 107 .strokeStyle("#000") 108 .anchor("right").add(pv.Label); 109 110 bar.anchor("left").add(pv.Label) 111 .textMargin(5) 112 .textAlign("right") 113 .text(function() { return thisObject.getDataLabel(this.index); }) 114 .font(function() { return thisObject.labelFont(); }) 115 .textStyle("rgb(0,0,0)"); 116 117 chart.add(pv.Rule) 118 .data(function() { return thisObject.x.ticks(); }) 119 .left(function(d) { return (Math.round(thisObject.x(d)) - 0.5); }) 120 .strokeStyle(function(d) { return (d ? "rgba(128,128,128,.3)" : "rgba(128,128,128,.8)"); }) 121 .add(pv.Rule) 122 .bottom(0) 123 .height(5) 124 .strokeStyle("rgba(128,128,128,1)") 125 .anchor("bottom").add(pv.Label) 126 .text(function(d) { return d.toFixed(); }) 127 .font(function() { return thisObject.labelFont(); }) 128 .textStyle("rgb(0,0,0)"); 129 130 this.vis.add(pv.Label) 131 .left(this.width() / 2) 132 .visible(function() { return !(thisObject.title() === ""); }) 133 .top(16) 134 .textAlign("center") 135 .text(function() { return thisObject.title(); }) 136 .font(function() { return thisObject.titleFont(); }); 137 }; 138 139 /** 140 * @private 141 */ 142 wso2vis.s.chart.protovis.BarChart.prototype.titleSpacing = function () { 143 if(this.title() === "") { 144 return 1; 145 } 146 else { 147 return 0.9; 148 } 149 }; 150 151 /** 152 * @private 153 */ 154 wso2vis.s.chart.protovis.BarChart.prototype.populateData = function (thisObject) { 155 var _dataField = thisObject.traverseToDataField(thisObject.data, thisObject.dataField()); 156 157 var dataGrpCount = 1; 158 if( _dataField instanceof Array ) { 159 dataGrpCount = _dataField.length; 160 } 161 162 thisObject.formattedData = pv.range(dataGrpCount).map( genDataMap ); 163 164 165 var maxVal = thisObject.formattedData.max(); 166 if (maxVal < 5) maxVal = 5; // fixing value repeating issue. 167 168 thisObject.x.domain(0, maxVal).range(0, (thisObject.width() - thisObject.paddingLeft() - thisObject.paddingRight()) ); 169 thisObject.y.domain(pv.range(dataGrpCount)).splitBanded(0, (thisObject.height() - thisObject.paddingTop() - thisObject.paddingBottom()), 4/5); 170 171 function genDataMap(x) { 172 var rootObj; 173 if( _dataField instanceof Array ) { 174 rootObj = _dataField[x]; 175 } 176 else { 177 rootObj = _dataField; 178 } 179 return parseInt(thisObject.traverseToDataField(rootObj, thisObject.dataValue())); 180 } 181 }; 182 183 wso2vis.s.chart.protovis.BarChart.prototype.getData = function (thisObject) { 184 return thisObject.formattedData; 185 }; 186 187 wso2vis.s.chart.protovis.BarChart.prototype.update = function () { 188 this.populateData(this); 189 this.vis.render(); 190 if(this.tooltip() === true) { 191 tooltip.init(); 192 } 193 }; 194 195 wso2vis.s.chart.protovis.BarChart.prototype.getDataLabel = function (i) { 196 if (this.data !== null){ 197 198 var rootObj = this.traverseToDataField(this.data, this.dataField()); 199 if( rootObj instanceof Array ) { 200 return this.traverseToDataField(rootObj[i], this.dataLabel()); 201 } 202 else { 203 return this.traverseToDataField(rootObj, this.dataLabel()); 204 } 205 } 206 207 return i; 208 }; 209 210