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