1 wso2vis.s.chart.raphael.FunnelChart = function(canvas, chartTitle, chartDesc) { 2 wso2vis.s.chart.Chart.call(this, canvas, chartTitle, chartDesc); 3 4 this.colscheme(20) 5 .gap(4) 6 .labelRelief(15) 7 .labelSpan(1) 8 .showPercent(true) 9 .showValue(true); 10 } 11 12 // inherits from Chart 13 wso2vis.extend(wso2vis.s.chart.raphael.FunnelChart, wso2vis.s.chart.Chart); 14 15 wso2vis.s.chart.raphael.FunnelChart.prototype 16 .property("colscheme") 17 .property("dataField") 18 .property("dataValue") 19 .property("dataLabel") 20 .property("gap") 21 .property("showPercent") 22 .property("showValue") 23 .property("labelRelief") 24 .property("labelSpan"); 25 26 27 wso2vis.s.chart.raphael.FunnelChart.prototype.load = function (w, h) { 28 if (w !== undefined) { 29 this.width(w); 30 } 31 if (h !== undefined) { 32 this.height(h); 33 } 34 35 this.r = Raphael(this.divEl(), this.width(), this.height()); 36 37 this.wf = this.width() / 406.01; 38 this.hf = this.height() / 325.01; 39 this.eh = 1007.9 * this.hf; 40 this.ew = 663 * this.wf; 41 this.e1x = -560 * this.wf + 5; 42 this.e2x = 173 * this.wf + 5; 43 this.ey = -136 * this.hf; 44 this.fc = 139 * this.wf + 5; 45 46 return this; 47 }; 48 49 wso2vis.s.chart.raphael.FunnelChart.prototype.update = function () { 50 this.convertData(this); 51 52 var total = 0; 53 54 for (var i = 0; i < this.formattedData.length; i++) { 55 total += this.formattedData[i]["value"]; 56 } 57 58 var funnelHeightRatio = (this.height() - this.gap() * (this.formattedData.length - 1) - this.labelRelief() * this.formattedData.length) / total; 59 60 var colors = wso2vis.util.generateColors(this.formattedData.length, this.colscheme()); 61 62 var is_label_visible = false, 63 leave_timer; 64 65 var currY = 0; 66 var df = this.traverseToDataField(this.data, this.dataField()); 67 if (df instanceof Array) { 68 df = df; 69 } 70 else { 71 df = [df]; 72 } 73 74 var first; 75 76 for (i = 0; i < this.formattedData.length; i++) { 77 var crect; 78 if (i != 0) { 79 this.r.rect(0, currY, this.width(), this.gap()).attr({fill:"#fff", stroke:"#fff"}); 80 crect = this.r.rect(0, currY + this.gap(), this.width(), funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief()).attr({fill:colors[i], stroke:"#fff"}); 81 currY += this.gap() + funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(); 82 } 83 else { 84 crect = this.r.rect(0, 0, this.width(), funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief()).attr({fill:colors[i], stroke:"#fff"}); 85 currY += funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(); 86 first = this.formattedData[i]["value"]; 87 } 88 89 if (this.tooltip()) { 90 (function (data, lbl, func, org) { 91 $(crect.node).hover(function (e) { 92 clearTimeout(leave_timer); 93 var tip = func({label:lbl, value:data, total:total, first:first, raw:org}); 94 wso2vis.environment.tooltip.show(e.pageX, e.pageY, tip); 95 is_label_visible = true; 96 }, function () { 97 leave_timer = setTimeout(function () { 98 wso2vis.environment.tooltip.hide(); 99 is_label_visible = false; 100 }, 2); 101 }); 102 })(this.formattedData[i]["value"], this.formattedData[i]["label"], this.onTooltip, df[i]);//(this.fc - frame.attrs.width/2 , crect.attrs.y + crect.attrs.height, this.formattedData[i]["value"], this.formattedData[i]["label"]); 103 104 (function (data, lbl, func, org) { 105 $(crect.node).mousemove(function (e) { 106 if (is_label_visible) { 107 clearTimeout(leave_timer); 108 var tip = func({label:lbl, value:data, total:total, first:first, raw:org}); 109 wso2vis.environment.tooltip.show(e.pageX, e.pageY, tip); 110 } 111 }); 112 })(this.formattedData[i]["value"], this.formattedData[i]["label"], this.onTooltip, df[i]);//(this.fc - frame.attrs.width/2 , crect.attrs.y + crect.attrs.height, this.formattedData[i]["value"], this.formattedData[i]["label"]); 113 } 114 } 115 116 var el1 = this.r.ellipse(-560 * this.wf + 5 + 663 * this.wf / 2, -136 * this.hf + 1007.9 * this.hf / 2, 663 * this.wf / 2, 1007.9 * this.hf / 2); 117 var el2 = this.r.ellipse(173 * this.wf + 5 + 663 * this.wf / 2, -136 * this.hf + 1007.9 * this.hf / 2, 663 * this.wf / 2, 1007.9 * this.hf / 2); 118 119 el1.attr({fill:"#fff", opacity:0.9, stroke:"#fff"}); 120 el2.attr({fill:"#fff", opacity:0.8, stroke:"#fff"}); 121 122 currY = 0; 123 for (i = 0; i < this.formattedData.length; i++) { 124 var t2; 125 if (i != 0) { 126 var t = this.r.text(this.width(), currY + this.gap() + funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(), this.formattedData[i]["label"]).attr({fill:colors[i]}); 127 t.attr({"font-size":12}); 128 var bbox = t.getBBox(); 129 t.translate(-bbox.width/2 - 2 * this.labelSpan(), -bbox.height/2 - this.labelSpan()); 130 var str = this.showValue()?this.formattedData[i]["value"]:""; 131 if ((this.formattedData[0]["value"] != 0) && this.showPercent()) { 132 str += "(" + (this.formattedData[i]["value"] * 100/ this.formattedData[0]["value"]).toFixed() + "%)"; 133 } 134 t2 = this.r.text(this.fc, currY + this.gap() + funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(), str).attr({fill:"#fff"}); 135 t2.attr({"font-size":10}); 136 bbox = t2.getBBox(); 137 t2.translate(0, -bbox.height/2 - this.labelSpan()); 138 currY += this.gap() + funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(); 139 } 140 else { 141 var t = this.r.text(this.width(), funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(), this.formattedData[i]["label"]).attr({fill:colors[i]}); 142 t.attr({"font-size":12}); 143 var bbox = t.getBBox(); 144 t.translate(-bbox.width/2 - 2 * this.labelSpan(), -bbox.height/2 - this.labelSpan()); 145 var str = this.showValue()?this.formattedData[i]["value"]:""; 146 if ((this.formattedData[0]["value"] != 0) && this.showPercent()) { 147 str += "(" + (this.formattedData[i]["value"] * 100/ this.formattedData[0]["value"]).toFixed() + "%)"; 148 } 149 t2 = this.r.text(this.fc, funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(), str).attr({fill:"#fff"}); 150 t2.attr({"font-size":10}); 151 bbox = t2.getBBox(); 152 t2.translate(0, -bbox.height/2 - this.labelSpan()); 153 currY += funnelHeightRatio * this.formattedData[i]["value"] + this.labelRelief(); 154 } 155 } 156 this.r.rect(0, 0, this.width()-1, this.height()-1); 157 }; 158 159 wso2vis.s.chart.raphael.FunnelChart.prototype.convertData = function (that) { 160 var df = that.traverseToDataField(that.data, that.dataField()); 161 var dcount = 1; 162 if (df instanceof Array) { 163 dcount = df.length; 164 } 165 166 that.formattedData = []; 167 168 for (var i = 0; i < dcount; i++) { 169 that.formattedData.push({"label":getLbl(i), "value":getVal(i)}); 170 } 171 172 function getVal(x) { 173 var r; 174 if (df instanceof Array) { 175 r = df[x]; 176 } 177 else { 178 r = df; 179 } 180 return parseInt(that.traverseToDataField(r, that.dataValue())); 181 } 182 183 function getLbl(x) { 184 var r; 185 if (df instanceof Array) { 186 r = df[x]; 187 } 188 else { 189 r = df; 190 } 191 return that.traverseToDataField(r, that.dataLabel()); 192 } 193 }; 194 195 wso2vis.s.chart.raphael.FunnelChart.prototype.onTooltip = function (data) { 196 return data.label + ":" + data.value; 197 }; 198 199 200 201 202