var homeCbbcBandChart = { guid : 0, chart : null, colors : {bull : "#E9A115", bear: "#00716C", bullhover : "#D19012", bearhover: "#005E59"}, furtherData : null, init : function(spread, callback){ var self = this; this.guid = guid(); spread = (spread == undefined || spread == "")?200:spread; $.getJSON('/'+lang+'/data/chart/cbbcBandChart?ucode=hsi&spread='+spread+'&sdate=&step=6', function(_data) { self.furtherData = _data.furtherData; var data = self.decode(_data); $('#homeCbbcBandChartContainer').highcharts(self.getJSON(data), function(chart){ self.chart = chart; if (callback!==undefined){ callback(_data); } }); self.drawBackground(); //****************** if($("#homeCbbcBandChartContainer").find(".link_table_a").length == 0){ $("#homeCbbcBandChartContainer").find(".highcharts-container").attr("aria-hidden","true"); var _text = []; if (lang == "tc"){ _text[0] = "查看圖表數據"; _text[1] = "於表單查看街貨數據"; }else if (lang == "sc"){ _text[0] = "查看图表数据"; _text[1] = "於表单查看街货数据"; }else{ _text[0] = "View detailed data"; _text[1] = "View CBBC map chart detail from table"; } $("#homeCbbcBandChartContainer").append(''+_text[1]+''); } //****************** }); }, decode : function(data){ var _data = data.mainData; var chartdata = {}; chartdata.cate = []; chartdata.away = []; chartdata.os = []; chartdata.ddelta = []; chartdata.dmax = 0; this.furtherData.hsilast = this.furtherData.hsilast*1; var sumBull = this.furtherData.sumBull[0]*1; var sumBear = this.furtherData.sumBear[0]*1; var ratio_bull=1; var ratio_bear=1; if (sumBull==0 || sumBear==0){ if (sumBull==0 && sumBear==0){ ratio_bull = 0; ratio_bear = 0; }else if (sumBull==0){ ratio_bull = 0; }else if (sumBear==0){ ratio_bear = 0; } }else if (sumBull>sumBear){ ratio_bull = sumBull/sumBear; }else{ ratio_bear = sumBear/sumBull; } if (ratio_bull.toFixed(1) == ratio_bear.toFixed(1)){ ratio_bull = ratio_bull.toFixed(2); ratio_bear = ratio_bear.toFixed(2); }else{ ratio_bull = ratio_bull.toFixed(1); ratio_bear = ratio_bear.toFixed(1); } this.furtherData.ratio = ratio_bull + ":" + ratio_bear; for (j=0;j<_data.length;j++){ i = _data.length - j - 1; if (_data[i].fr == 0){ chartdata.cate.push(""); chartdata.away.push("0%"); }else{ chartdata.cate.push(addcomma(_data[i].fr)+" - "+addcomma(_data[i].to)); chartdata.away.push(calCall2Spot(this.furtherData.hsilast,(_data[i].fr + _data[i].to+1)/2)); } //d7d8d6 if (i>_data.length/2){ chartdata.os.push({o:_data[i].o1,type: "bear", color: this.colors.bear, y:_data[i].d1, dchng:Math.round(_data[i].d1)-Math.round(_data[i].d2), states: { hover: {color: this.colors.bearhover} }}); }else{ chartdata.os.push({o:_data[i].o1,type: "bull", color: this.colors.bull, y:_data[i].d1, dchng:Math.round(_data[i].d1)-Math.round(_data[i].d2), states: { hover: {color: this.colors.bullhover} }}); } if (i == 0){ this.furtherData.min = _data[i].fr; }else if (i == _data.length - 1){ this.furtherData.max = _data[i].to; }else if (i == ((_data.length+1)/2)){ this.furtherData.bearMin = _data[i].fr; }else if (i == ((_data.length-1)/2)-1){ this.furtherData.bullMax = _data[i].to; } chartdata.dmax = Math.max(_data[i].d1,chartdata.dmax); } return chartdata; }, getJSON : function(data){ var dp = 0; var self = this; var dmax = data.dmax*1.5; return { chart:{ className: "homeCbbcBandChartChart"+self.guid, marginTop: 40, marginRight: 84, marginLeft: 140, marginBottom: 8, events: { redraw: function(event) { self.redraw(); } } }, title: { text: null }, xAxis: [{ title: { text: self.labels[lang].yTitle1, margin: 16, useHTML: true, }, categories: data.cate, lineWidth: 0, tickLength:0, offset: -5, }, { min : self.furtherData.min, reversed: false, tickInterval : self.furtherData.spread, tickAmount : (self.furtherData.step+1)*2, visible: false }, { min : (self.furtherData.max - self.furtherData.spread*((self.furtherData.step+1)*2-1)), reversed: false, tickInterval : self.furtherData.spread, tickAmount : (self.furtherData.step+1)*2, visible: false }, { title: { text: self.labels[lang].yTitle2, rotation: 270, margin: 26, }, linkedTo: 0, gridLineWidth: 1, gridLineColor: "#D7D8D6", lineWidth: 0, tickLength:0, offset: -5, opposite: true, labels:{ align:'left', formatter: function () { return data.away[this.value]; }, }, } ], yAxis: [{ min: 0, max: dmax, title: { text: self.labels[lang].xTitle, }, labels:{ formatter: function () { return addcomma(this.value); }, }, opposite : true, tickAmount: 5, tickLength: 12, tickColor: "#D7D8D6", offset: -5, tickWidth: 1, showFirstLabel: false, showLastLabel: false, }, { title: { text: null }, tickPositioner: function () { return [0,10,20,30,40]; }, visible: true, tickLength: 12, tickColor: "#D7D8D6", tickWidth: 1, }], plotOptions: { bar: { dataLabels: { enabled: true, color: '#333333', formatter: function () { return addcomma(Math.round(this.point.y))+"["+((this.point.dchng>0)?"+":"")+Math.round(this.point.dchng)+"]"; } } }, scatter: { events: { click : function (e){ window.location.href = genURL(e.point.data.code); } }, cursor : "pointer", } }, legend: { enabled: false }, series: [{ type : "bar", name : "barchart", data : data.os, groupPadding : 0.1, pointPadding :0.1 }], exporting : { enabled: false }, tooltip: { backgroundColor: 'none', borderWidth: 0, shadow: false, useHTML: true, padding: 0, formatter: function () { var html = ""; var wtypeclass = this.point.type; if (this.point.series.name == 'barchart'){ var delta = addcomma(Math.round(this.point.y)); html = '
'; html += '
'+((wtypeclass=="bear")?self.labels[lang].bear:self.labels[lang].bull)+'
'; html += '
'+ self.labels[lang].calllv +''+(this.point.category.replace(" - ", " "+self.labels[lang].to+" "))+'
'; html += '
'+self.labels[lang].os+''+(addcomma(this.point.o/1000) + self.labels[lang].ounit)+'
'; html += '
'+self.labels[lang].xTitle+''+delta+' '+self.labels[lang].dunit+'
'; html += '
'; }else{ html = '
'; html += '
'+this.point.data.name+" "+ this.point.data.code +'
'; html += '
'+self.labels[lang].calllv + ''+addcomma(this.point.data.calllv)+'
'; html += '
'+self.labels[lang].maturity+''+this.point.data.mdate + '
'; html += '
'+self.labels[lang].gearing+''+formatPercent(this.point.data.gearing)+' '+self.labels[lang].x+'
'; html += '
'+self.labels[lang].issuer+''+self.labels[lang].hs+'
'; html += '
'+self.labels[lang].cratio+''+ addcomma(this.point.data.cratio) +'
'; html += '
'; } return html; } }, }; }, setBarChartStatus : function(status){ var chart = this.chart; var opts = chart.series[0].options; if (status == 1){ for (i=0;iopts.data.length/2){ opts.data[i].color = this.colors.bear; opts.data[i].states.hover.color = this.colors.bearhover; }else{ opts.data[i].color = this.colors.bull; opts.data[i].states.hover.color = this.colors.bullhover; } } //opts.dataLabels.enabled = true; chart.series[0].update(opts); for(i = chart.series.length - 1; i > 0; i--) { chart.series[i].remove(); } }else{ for (i=0;i -1; i--){ if(chart.series[i].name.substring(0, 4) == "bull" || chart.series[i].name.substring(0, 4) == "bear"){ chart.series[i].remove(); } } var data = self.knockoutDecode(_data); chart.addSeries({ name: "bull0",type: "scatter", marker: { symbol: 'url(/home/images/chart/grey_point_up.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data0["bull"], fillOpacity: 0.0,xAxis: 1,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bull1",type: "scatter", marker: { symbol: 'url(/home/images/chart/green_point_up.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data1["bull"], fillOpacity: 0.0,xAxis: 1,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bull2",type: "scatter", marker: { symbol: 'url(/home/images/chart/orange_point_up.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data2["bull"], fillOpacity: 0.0,xAxis: 1,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bull3",type: "scatter", marker: { symbol: 'url(/home/images/chart/red_point_up.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data3["bull"], fillOpacity: 0.0,xAxis: 1,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bull4",type: "scatter", marker: { symbol: 'url(/home/images/chart/red_circle.png)', width: circleWidht, height: circleWidht }, color: 'rgba(255, 255, 255, 1)', data: data.data4["bull"], fillOpacity: 0.0,xAxis: 1,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bear0",type: "scatter", marker: { symbol: 'url(/home/images/chart/grey_point_down.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data0["bear"], fillOpacity: 0.0,xAxis: 2,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bear1",type: "scatter", marker: { symbol: 'url(/home/images/chart/green_point_down.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data1["bear"], fillOpacity: 0.0,xAxis: 2,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bear2",type: "scatter", marker: { symbol: 'url(/home/images/chart/orange_point_down.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data2["bear"], fillOpacity: 0.0,xAxis: 2,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bear3",type: "scatter", marker: { symbol: 'url(/home/images/chart/red_point_down.png)', width: pointWidth, height: pointHeight }, color: 'rgba(255, 255, 255, 1)', data: data.data3["bear"], fillOpacity: 0.0,xAxis: 2,yAxis: 1,zIndex: 1 }); chart.addSeries({ name: "bear4",type: "scatter", marker: { symbol: 'url(/home/images/chart/red_circle.png)', width: circleWidht, height: circleWidht }, color: 'rgba(255, 255, 255, 1)', data: data.data4["bear"], fillOpacity: 0.0,xAxis: 2,yAxis: 1,zIndex: 1 }); /*$('#homeCbbcBandChartContainer').highcharts(self.getJSON(data)); if (callback!==undefined){ callback(chart,data); }*/ }); }, knockoutDecode : function(_data){ var mainData = _data.mainData; //var ulast; var data0 = {bull:[], bear:[]}; var data1 = {bull:[], bear:[]}; var data2 = {bull:[], bear:[]}; var data3 = {bull:[], bear:[]}; var data4 = {bull:[], bear:[]}; //ulast = mainData[0].ulast; for (var i =0; i=this.furtherData.max || mainData[i].calllv<=this.furtherData.min){ continue; } //var risk = ((mainData[i].calllv-ulast)/ulast)*100; var _gearing = mainData[i].gearing; if (_gearing>30){ //_gearing = 30 + (Math.log(Math.min((_gearing-29), 40))/ Math.log(40))*10; _gearing = 30 + (Math.pow(Math.min((_gearing-29),40),0.8)/ Math.pow(40,0.8))*9.5; //console.log( mainData[i].gearing +" -> "+_gearing); } var _obj = { x: mainData[i].calllv, y: _gearing, data: mainData[i] }; if (mainData[i].wtype == "bull" && mainData[i].calllv>this.furtherData.bullMax){ _obj.x=this.furtherData.bullMax; }else if (mainData[i].wtype == "bear" && mainData[i].calllv10 && Math.abs(mainData[i].gearing)<=20){ data2[mainData[i].wtype].push(_obj); }else if (Math.abs(mainData[i].gearing)>20){ data3[mainData[i].wtype].push(_obj); }else{} }else{ data0[mainData[i].wtype].push(_obj); } if (mainData[i].prefer*1>0){ data4[mainData[i].wtype].push(_obj); } } data = {data0:data0, data1:data1, data2:data2, data3:data3, data4:data4}; return data; }, drawBackground: function(){ var chart = this.chart; var self = this; chart.renderer.text(self.labels[lang].bull, 10 , chart.plotHeight/2+163).css({ color: '#333333', }).attr({ zIndex: 1, }).add(); chart.renderer.image("/home/images/map_bull.jpg", 6 , chart.plotHeight/2+120, 30,30).add(); chart.renderer.text(self.labels[lang].bear, 8 , chart.plotHeight/2-47).css({ color: '#333333', }).attr({ zIndex: 1, }).add(); chart.renderer.image("/home/images/map_bear.jpg", 6 , chart.plotHeight/2-90, 30,30).add(); }, redraw: function(){ var chart = this.chart; var self = this; $("#chartBackground").remove(); $("#chartLegend").remove(); $("#chartBackgroundLine1").remove(); $("#chartBackgroundLine2").remove(); /* chart.renderer.rect(chart.margin[3]-0.5, chart.margin[0] + chart.plotHeight/2 - 9.5, chart.plotWidth+1, 20, 0).attr({ fill: '#ffffff', stroke: '#d7d8d6', 'stroke-width': 1, id :'chartBackground', zIndex: 1, }).add(); var _text = self.labels[lang].pclose + addcomma(formatPrice(self.furtherData.hsilast)) + " "+ self.labels[lang].ratio + this.furtherData.ratio; chart.renderer.text(_text, chart.margin[3]+5, chart.margin[0] + chart.plotHeight/2 + 4).css({ color: '#333333', }).attr({ id :'chartLegend', zIndex: 1, }).add(); */ chart.renderer.rect(chart.margin[3]-0.5, chart.margin[0] + chart.plotHeight/2 - 9.5, chart.plotWidth+1, 20, 0).attr({ fill: '#333', stroke: '#d7d8d6', 'stroke-width': 1, id :'chartBackground', zIndex: 1, }).add(); var _text = self.labels[lang].pclose + addcomma(formatPrice(self.furtherData.hsilast)) + " "+ self.labels[lang].ratio + this.furtherData.ratio; chart.renderer.text(_text, chart.margin[3]+5, chart.margin[0] + chart.plotHeight/2 + 4).css({ color: '#ffffff', }).attr({ id :'chartLegend', zIndex: 1, }).add(); chart.renderer.path(['M', 0, chart.margin[0] -4.5,'L', chart.plotWidth+chart.margin[3]+10, chart.margin[0]-4.5]).attr({ stroke: '#929292', 'stroke-width': 1, opacity: 1, id :'chartBackgroundLine1', zIndex: 2, }).add(); chart.renderer.path(['M', 0, chart.margin[0]+ chart.plotHeight+4.5,'L', chart.plotWidth+chart.margin[3]+10, chart.margin[0]+ chart.plotHeight+4.5]).attr({ stroke: '#929292', 'stroke-width': 1, opacity: 1, id :'chartBackgroundLine2', zIndex: 2, }).add(); }, labels : { tc :{ xTitle : "相對期指張數", yTitle1 : "收回價", yTitle2 : "收回價距離前收市價", calllv : "收回價", bull : "牛證", bear : "熊證", to : "至", os : "街貨量", ounit : "百萬", dunit : "", maturity : "到期日", gearing : "實際槓桿", issuer : "發行商", pclose : "恒指收市價: ", ratio : "恒指牛熊對沖張數比例", cratio : "換股比率", hs:"滙豐", x:"倍", }, sc :{ xTitle : "相对期指张数", yTitle1 : "收回价", yTitle2 : "收回价距离前收市价", calllv : "收回价", bull : "牛证", bear : "熊证", to : "至", os : "街货量", ounit : "百万", dunit : "", maturity : "到期日", gearing : "有效杠杆", issuer : "发行商", pclose : "恒指收市价: ", ratio : "恒指牛熊对冲张数比例", cratio : "换股比率", hs:"汇丰", x:"倍", }, en :{ xTitle : "Related futures quantity", yTitle1 : "Call level", yTitle2 : "Away from previous close", calllv : "Call level", bull : "Bull", bear : "Bear", to : "to", os : "Outstanding", ounit : "M", dunit : "", maturity : "Maturity", gearing : "E.Gearing", issuer : "Issuer", pclose : "HSI previous close: ", ratio : "HSI bull bear ratio ", cratio : "Entitlement ratio ", hs:"HS", x:"X", }, }, }