highstock实现股票分时

 

highchart学习网站
www.highcharts.com
http://www.hcharts.cn/docs/index.php
http://www.hcharts.cn/api/highstock.php
实现效果:
//谷歌手机浏览器酷似有bug,不过在iPhone5上图正确显示
传入数据:股票交易的时间早上9:30-11:30 下午13:00-15:00   对应的最新价、成交量、平均价
请求地址如下:
http://open.hundsun.com:8081/quote/v1/trend?prod_code=600570.SS&fields=last_px,business_amount,avg_px
数据格式如下:
{"data":{"trend":{"fields":["min_time","last_px","business_amount","avg_px"],"600570.SS":[[201505050930,115.800000,48400,115.990000],...}
技术难点:
1.刻度分隔问题:由于highstock的x轴是按照时间升序的,但是中间11:30到13:00无数据,故x与y轴刻度分隔问题,同时中间位11:30/13:00可见x轴坐标需要定制化?
在x与y坐标提供labels:{formatter:function(){return this.value;//这里改变}}和tickPositioner:function(){return array[]}来定制输出的标签和那些数据显示。
2.y轴左右两边问题,一般坐标轴只有1份或在左边或在右边,如何使y轴左右两边都有并且数据对应?
图表的右边的y轴,存的数据与图表左边y轴的一样,但是显示的时候labels:{}这里处理输出的值
3.基线问题:在0.00%处需要定制化一条基线如上图蓝色的基线
利用var chart = $(DIVID).highcharts();
chart.removePlotLine();
chart.addPlotLine({});
4.标注问题:如上图 112 13:02 -5.08%的显示
采用标志带:
chart.removePlotBand();
chart.addPlotBand({});
5.手指触摸问题:本应用可实现上下整体拖动,左右十字线移动。
touchmove、touchstart事件的绑定

document.getElementById("line_map").removeEventListener("touchstart",createKlineChart.kline_touchstart,false);
document.getElementById("line_map").addEventListener("touchstart", createTrendChart.trend_touchstart);
document.getElementById("line_map").removeEventListener("touchmove",createKlineChart.kline_touchmove,false);

6:手指左右移动十字线跟随移动问题

首先判断手指斜向上角度大于45度就判断为上下移动,否则则判断手指左右移动。

当手指左右移动的时候捕获事件获取pagex,pageY针对父控件手指的x、y坐标,然后做映射

i=x/chart.width*data.length;

data.length与 chart.plotwidth宽度  对应i为平均分布在宽度chart.plotwidth上的数据,找到i之后就可以从data中取值data[i][0]x轴事件 data[i][1]y轴的值

 代码:

需要引入highstock.js  jquery.js

html

1 <div id="report" class="klineMap-report"></div>
2 <div class="kline_map" id="line_map" style="height: 200px;width: 100%" >       

 

trend.js

  1 var Trend_Url=js_lib.getTrendUrl();
  2 //http://open.hundsun.com:8081/quote/v1/trend?prod_code=600570.SS&fields=last_px,business_amount,avg_px
  3 var Real_Url=js_lib.getCommonRealUrl();
  4 //http://open.hundsun.com:8081/quote/v1/real?en_prod_code=600570.SS&fields=open_px,preclose_px
  5 var DIVID='#line_map';
  6 //接收个股代码
  7 var STOCK_CODE = js_lib.getQueryStringByName("stock_code");
  8 /*
  9  * 分时
 10  */
 11 if(STOCK_CODE==""){
 12     STOCK_CODE="600570.SS";
 13 }
 14 function clickTrend(obj){
 15     var price_param="en_prod_code="+STOCK_CODE+"&fields=open_px,preclose_px";
 16     js_lib.ajax(Real_Url,callbackReal, 'get',price_param,failCallback);
 17     $(obj).parent().parent().children().each(function(){
 18         $(this).removeClass("hover");
 19     });
 20     $(obj).parent().addClass("hover");
 21 }
 22 function clickTrend_Show(val){
 23     var jsonText = JSON.parse(val);    
 24     if(typeof(jsonText.error_info)!='undefined'){
 25         failCallback();
 26         return ;
 27     }
 28     var data=jsonText.data.trend;
 29     data=data[STOCK_CODE];
 30     //画图
 31     trendChart(DIVID,data);
 32 }
 33 //图表上的成交量第一条的数据红绿的判断 是根据昨日的收盘价preclose_px 和今日的最新价last_px进行对比
 34 //同时获取的昨日收盘价  用于涨幅的计算
 35 var isFirstLineColorflag=true;
 36 //保存昨收数据
 37 var yesterdayClose;
 38 //可以获取今开 与昨收
 39 function callbackReal(val){
 40     var jsonText = JSON.parse(val);    
 41     var price_data=jsonText.data.snapshot;
 42     if(typeof(price_data[STOCK_CODE])=='undefined'){
 43         failCallback();
 44         return ;
 45     }
 46     //今开
 47     var open_px=price_data[STOCK_CODE][2];
 48     //昨收
 49     var preclose_px=price_data[STOCK_CODE][3];
 50     yesterdayClose=preclose_px;
 51     isFirstLineColorflag=open_px>preclose_px?true:false;
 52     //获取分时数据
 53     var kline_params = "prod_code="+STOCK_CODE+"&fields=last_px,business_amount,avg_px";
 54     js_lib.ajax(Trend_Url, clickTrend_Show, 'get',kline_params,failCallback);
 55 }
 56 /*
 57  * 5日
 58  */
 59 function clickFiveDayTrend(obj){
 60     $(obj).parent().parent().children().each(function(){
 61         $(this).removeClass("hover");
 62     });
 63     $(obj).parent().addClass("hover");
 64 }
 65 var avg_pxyAxisMin;
 66 var avg_pxyAxisMax;
 67 var percentageyAxisMin;
 68 var percentageyAxisMax;
 69 var volume_yAxisMin;
 70 var volume_yAxisMax;
 71 var red="#ff0000";
 72 var blue="#00a800";
 73 function trendChart(DIVID,data)
 74 {  
 75     var ohlc = [],
 76     volume = [],//昨日开盘价
 77     i = 0;
 78     //容错判断
 79     if(data!=undefined&&data!=null&&data.length==0){
 80         failCallback();
 81         return;
 82     }
 83     // split the data set into ohlc and volume
 84     //数据处理
 85     for (i; i < data.length; i += 1) {
 86         var dateUTC=getDateUTCOrNot(data[i][0],true);
 87         var business_amount=data[i][2];
 88         var columnColor = red;
 89         if(i==0){//第一笔的 红绿柱 判断依据是根据 今天开盘价与昨日收盘价比较
 90             if(isFirstLineColorflag==false){
 91                 columnColor = blue;
 92             }
 93             avg_pxyAxisMin=data[i][3];
 94             avg_pxyAxisMax=data[i][3];
 95             percentageyAxisMin=Number(100*(data[i][1]/yesterdayClose-1));
 96             percentageyAxisMax=Number(100*(data[i][1]/yesterdayClose-1));
 97             volume_yAxisMin=data[i][2];
 98             volume_yAxisMax=data[i][2];
 99         }
100         else {
101             //除了第一笔,其它都是  返回的 last_px 与前一个对比
102             if(data[i-1][1]-data[i][1]>0){
103                 columnColor = blue;
104                 }
105             business_amount=data[i][2]-data[i-1][2];
106             }
107         avg_pxyAxisMin=avg_pxyAxisMin>data[i][1]?data[i][1]:avg_pxyAxisMin;
108         avg_pxyAxisMax=avg_pxyAxisMax>data[i][1]?avg_pxyAxisMax:data[i][1];
109         percentageyAxisMin=percentageyAxisMin>Number(100*(data[i][1]/yesterdayClose-1))?Number(100*(data[i][1]/yesterdayClose-1)):percentageyAxisMin;
110         percentageyAxisMax=percentageyAxisMax>Number(100*(data[i][1]/yesterdayClose-1))?percentageyAxisMax:Number(100*(data[i][1]/yesterdayClose-1));
111         volume_yAxisMin=volume_yAxisMin>business_amount?business_amount:volume_yAxisMin;
112         volume_yAxisMax=volume_yAxisMax>business_amount?volume_yAxisMax:business_amount;
113         //将数据放入 ohlc volume 数组中
114         ohlc.push({x:dateUTC,y:Number(data[i][1])});
115         volume.push({x:dateUTC,y:Number(business_amount),color:columnColor});
116     }
117     //将剩下的时间信息补全
118     appendTimeMessage(ohlc,volume,data);
119     createTrendChart(data,ohlc,volume);
120 };
121 function createTrendChart(data,ohlc,volume){
122     var date;
123     if(data.length>0){
124         date=data[data.length-1][0]+"";
125         var dArr = new Array();
126         for(var hh=0;hh<5;hh++){
127             var numb ;
128             if(hh==0){
129                 numb = Number(date.slice(0,4));
130             }
131             else {
132                 numb= Number(date.slice((hh-1)*2+4,hh*2+4));
133                 };
134             dArr.push(numb);
135         }
136     }
137     var last_dataTime=new Date(dArr[0],dArr[1]-1,dArr[2],dArr[3],dArr[4]);
138     var $reporting = $("#report");
139     $reporting.html("");
140      // Create the chart
141     var am_startTime=new Date(last_dataTime);
142     am_startTime.setHours(9, 30, 0, 0);
143     var am_startTimeUTC=Number(Date.UTC(am_startTime.getFullYear(),am_startTime.getMonth(),am_startTime.getDate(),am_startTime.getHours(),am_startTime.getMinutes()));
144     
145     var am_midTime=new Date(last_dataTime);
146     am_midTime.setHours(10, 30, 0, 0);
147     var am_midTimeUTC=Number(Date.UTC(am_midTime.getFullYear(),am_midTime.getMonth(),am_midTime.getDate(),am_midTime.getHours(),am_midTime.getMinutes()));
148     
149     //股票交易早上最后的时间
150     var am_lastTime=new Date(last_dataTime);
151     am_lastTime.setHours(11, 30, 0, 0);
152     var am_lastTimeUTC=Number(Date.UTC(am_lastTime.getFullYear(),am_lastTime.getMonth(),am_lastTime.getDate(),am_lastTime.getHours(),am_lastTime.getMinutes()));
153     //股票交易下午最后的时间
154     var pm_startTime=new Date(last_dataTime);
155     pm_startTime.setHours(13, 1, 0, 0);
156     var pm_startTimeUTC=Number(Date.UTC(pm_startTime.getFullYear(),pm_startTime.getMonth(),pm_startTime.getDate(),pm_startTime.getHours(),pm_startTime.getMinutes()));
157 
158     var pm_midTime=new Date(last_dataTime);
159     pm_midTime.setHours(14, 0, 0, 0);
160     var pm_midTimeUTC=Number(Date.UTC(pm_midTime.getFullYear(),pm_midTime.getMonth(),pm_midTime.getDate(),pm_midTime.getHours(),pm_midTime.getMinutes()));
161 
162     var pm_lastTime=new Date(last_dataTime);
163     pm_lastTime.setHours(15, 0, 0, 0);
164     var pm_lastTimeUTC=Number(Date.UTC(pm_lastTime.getFullYear(),pm_lastTime.getMonth(),pm_lastTime.getDate(),pm_lastTime.getHours(),pm_lastTime.getMinutes()));
165     //常量本地化
166     Highcharts.setOptions({
167         global : {
168             useUTC : true
169         }
170     });
171     
172     var startX,startY,swipeX,swipeY;
173     createTrendChart.trend_touchstart=function(event){
174         var touch = event.touches[0];
175         startX=touch.pageX;
176         startY=touch.pageY;
177         swipeX=swipeY=false;
178         document.getElementById("line_map").addEventListener("touchmove", createTrendChart.trend_touchmove);
179     }
180     createTrendChart.trend_touchmove=function (event){
181         var touch = event.touches[0];
182         var currenX=touch.pageX;
183         var currentY=touch.pageY;
184         if(true==swipeX){//先左右就一直左右  上下也不影响
185             swipeY=false;
186         }
187         else if(true==swipeY){//向上下移动的标志
188             swipeX=false;
189         }else{
190             if(Math.abs(currentY-startY)>Math.abs(currenX-startX)){//上下移动
191                 swipeY=true;
192                 }
193             else{
194                 swipeX=true;
195                 }
196         }
197         if(true==swipeY){//上下移动   先重画线 人后删除事件
198             document.getElementById("line_map").removeEventListener("touchmove", createTrendChart.trend_touchmove,false);
199         }else if(true==swipeX){ 
200             event.stopPropagation();
201             event.preventDefault();
202         }
203         //不管 上下 还是 左右 都需要先画标示线
204         var chart = $(DIVID).highcharts();
205         var left=chart.yAxis[0].left+(chart.yAxis[0].axisLine.strokeWidth==undefined?0:chart.yAxis[0].axisLine.strokeWidth);
206         var y ;
207         var x = touch.pageX-left-7;
208         //x点 =x/chart宽度 * 总体点的个数
209         x=(x/chart.plotWidth)*ohlc.length;
210         var i=0;
211        i=Number(Math.ceil(x));
212        if(i>=data.length||i<0){
213            return;}
214        //计算图表x轴
215        x=ohlc[i].x;//utc格式时间数据
216        y=data[i][1];
217        var last_px=data[i][1].toFixed(2);
218        var business_amount=data[i][2];
219        var avg_price=data[i][3].toFixed(2);
220        var zfz=(100*(ohlc[i].y/yesterdayClose-1)).toFixed(2);
221        var time=Highcharts.dateFormat('%H:%M ', x);
222          //除了第一笔,其它都是  返回的 last_px 与前一个对比
223         if(i!=0){
224              business_amount=data[i][2]-data[i-1][2];
225          }
226          $reporting.html(
227                  '<div class="detail">'+
228                                '<ul>'+
229                          '<li class="value-2">'+ '价格:  <span>'+last_px+'</span></li>'+
230                          '<li class="value-2">'+ '成交量:  <span>'+business_amount+'</span></li>'+
231                                                          '<li class="value-2">'+ '均价:  <span>'+avg_price+'</span></li>'+
232                      '<li class="value-2">'+ '涨幅值:  <span>'+zfz+'%</span></li>'+
233                      '</ul>'+
234                  '</div>'
235                  );
236          var chart = $(DIVID).highcharts();           // Highcharts构造函数
237          chart.xAxis[0].removePlotBand("plotBand-x");
238          chart.xAxis[0].addPlotBand({
239             borderColor:'red',
240             borderWidth:0.1,
241             color: 'red',
242             from: x-0.000001,//,Date.UTC(2015, 3, 27,10,50),
243             to:  x+0.000001,//Date.UTC(2015, 3, 27,10,51),
244             label: {
245                 useHTML:true,
246                 text: '<span class="value" style="font-size:10px;background-color:rgba(0,0,0,.6); color:#fff; height:15px; line-height:15px; padding:0 5px;">'+time+'</span>',
247                 textAlign: 'bottom',
248                 y:5,
249                 x:-30
250             },
251             id:'plotBand-x',
252             zIndex:1001
253          });
254          chart.yAxis[0].removePlotBand("plotBand-y0");
255          chart.yAxis[0].addPlotBand({
256              borderColor:'red',
257              borderWidth:0.1,
258              color: 'red',
259                 from: y-0.000001,//,Date.UTC(2015, 3, 27,10,50),
260                 to:   y+0.000001,//Date.UTC(2015, 3, 27,10,51),
261                 label: {
262                     useHTML:true,
263                     style: {         //字体样式
264                         font: 'normal 5px Verdana, sans-serif'
265                         },
266                     text: '<span class="value" style="font-size:10px;background-color:rgba(0,0,0,.6); color:#fff; height:15px; line-height:15px; padding:0 5px;">'+y+'</span>',
267                     verticalAlign:'top',
268                     textAlign: 'left',
269                     x:-25,
270                     y:-2
271                 },
272                 id:'plotBand-y0',
273                 zIndex:1001
274 
275          });
276          chart.yAxis[0].removePlotBand("plotBand-y1");
277          chart.yAxis[0].addPlotBand({
278              color: '#BEBEBE',
279              borderColor:'#BEBEBE',
280              borderWidth:0.1,
281                 from: y-0.000001,//,Date.UTC(2015, 3, 27,10,50),
282                 to:  y+0.000001,//Date.UTC(2015, 3, 27,10,51),
283                 label: {
284                     useHTML:true,
285                     style: {         //字体样式
286                         font: 'normal 5px Verdana, sans-serif'
287                         },
288                     text: '<span class="value" style="font-size:10px;background-color:rgba(0,0,0,.6); color:#fff; height:15px; line-height:15px; padding:0 5px;">'+zfz+"%"+'</span>',
289                     textAlign: 'right',
290                     verticalAlign:'bottom',
291                     x:280,
292                     y:-2
293                 },
294                 id:'plotBand-y1',
295                 zIndex:1001
296          });
297     }
298     document.getElementById("line_map").removeEventListener("touchstart",createKlineChart.kline_touchstart,false);
299     document.getElementById("line_map").addEventListener("touchstart", createTrendChart.trend_touchstart);
300     document.getElementById("line_map").removeEventListener("touchmove",createKlineChart.kline_touchmove,false);
301     //开始画图
302     $(DIVID).highcharts('StockChart', {
303          chart:{
304              //关闭平移
305             panning:false,
306             zoomType: 'none',
307             pinchType:'none',
308              renderTo : "line_map",
309             margin: [25, 25,25, 25],
310             spacing: [0,0,0,0],
311              plotBorderColor: '#3C94C4',
312              plotBorderWidth: 0,
313             events:{
314                 load:function(){
315                     x=ohlc[data.length-1].x;
316                     y=ohlc[data.length-1].y;
317                     var chart = $(DIVID).highcharts();           // Highcharts构造函数
318                      //基准线
319                      chart.yAxis[0].addPlotLine({           //在x轴上增加
320                          value:yesterdayClose,                           //在值为2的地方
321                          width:0.1,                           //标示线的宽度为2px
322                          color: '#FFA500',                  //标示线的颜色
323                          zIndex:1001
324                      });
325                      chart.xAxis[0].removePlotBand("plotBand-x");
326                      chart.xAxis[0].addPlotBand({
327                         borderColor:'#BEBEBE',
328                         borderWidth:0.1,
329                         color: '#BEBEBE',
330                         from: ohlc[data.length-1].x-0.000001,//,Date.UTC(2015, 3, 27,10,50),
331                         to:  ohlc[data.length-1].x+0.000001,//Date.UTC(2015, 3, 27,10,51),
332                         label: {
333                             useHTML:true,
334                             text: '<span class="value" style="font-size:10px;background-color:rgba(0,0,0,.6); color:#fff; height:15px; line-height:15px; padding:0 5px;">'+Highcharts.dateFormat('%H:%M ', ohlc[data.length-1].x)+'</span>',
335                             textAlign: 'top',
336                             y:5,
337                             x:-30
338                         },
339                         id:'plotBand-x',
340                         zIndex:1001
341                      });
342                      chart.yAxis[0].removePlotBand("plotBand-y0");
343                      chart.yAxis[0].addPlotBand({
344                          borderColor:'#BEBEBE',
345                          borderWidth:0.1,
346                          color: '#BEBEBE',
347                             from: ohlc[data.length-1].y-0.0001,//,Date.UTC(2015, 3, 27,10,50),
348                             to:  ohlc[data.length-1].y+0.0001,//Date.UTC(2015, 3, 27,10,51),
349                             label: {
350                                 useHTML:true,
351                                 style: {         //字体样式
352                                     font: 'normal 5px Verdana, sans-serif'
353                                     },
354                                 text: '<span class="value" style="font-size:10px;background-color:rgba(0,0,0,.6); color:#fff; height:15px; line-height:15px; padding:0 5px;">'+ohlc[data.length-1].y.toFixed(2)+'</span>',
355                                 verticalAlign:'top',
356                                 textAlign: 'left',
357                                 x:-25,
358                                 y:-2
359                             },
360                             id:'plotBand-y0',
361                             zIndex:1001
362                      });
363                      chart.yAxis[0].removePlotBand("plotBand-y1");
364                      chart.yAxis[0].addPlotBand({
365                          color: '#BEBEBE',
366                          borderWidth:0.1,
367                          borderColor:'#BEBEBE',
368                             from: ohlc[data.length-1].y-0.0001,//,Date.UTC(2015, 3, 27,10,50),
369                             to:  ohlc[data.length-1].y+0.0001,//Date.UTC(2015, 3, 27,10,51),
370                             label: {
371                                 useHTML:true,
372                                 style: {         //字体样式
373                                     font: 'normal 5px Verdana, sans-serif'
374                                     },
375                                 text: '<span class="value" style="font-size:10px;background-color:rgba(0,0,0,.6); color:#fff; height:15px; line-height:15px; padding:0 5px;">'+(100*(ohlc[data.length-1].y/yesterdayClose-1)).toFixed(2)+"%"+'</span>',
376                                 textAlign: 'right',
377                                 verticalAlign:'bottom',
378                                 x:280,
379                                 y:-2
380                             },
381                             id:'plotBand-y1',
382                             zIndex:1001
383                      });
384                      $reporting.html(
385                              '<div class="detail">'+
386                              '<ul>'+
387                              '<li class="value-2">'+ '价格:  <span>'+data[data.length-1][1].toFixed(2)+'</span></li>'+
388                              '<li class="value-2">'+ '成交量:  <span>'+data[data.length-1][2]+'</span></li>'+
389                              '<li class="value-2">'+ '均价:  <span>'+data[data.length-1][3].toFixed(2)+'</span></li>'+
390                              '<li class="value-2">'+ '涨幅值:  <span>'+(100*(data[data.length-1][3]/yesterdayClose-1)).toFixed(2)+'%</span></li>'+
391                              '</ul>'+
392                              '</div>'
393                      ); 
394                 }
395             }
396          },
397          tooltip:{
398             enabled:false,
399             crosshairs:false
400          },
401         rangeSelector:{
402             enabled: false,
403         },
404          /*导出配置*/
405         exporting: {
406             enabled: false,
407         },
408           /*创建者信息*/
409         credits: {
410             enabled: false,
411         },
412         /*下部时间拖拉选择*/
413         navigator: {
414             enabled: false,
415             /*关闭时间选择*/
416             baseseries: 10
417         },
418         scrollbar: {
419             enabled: false /*关闭下方滚动条*/
420         },
421         /*底部滚动条*/
422         scrollbar: {
423             enabled: false
424         },
425         plotOptions:{
426             //去掉分时线上的hover事件
427             series:{
428                 states: {
429                     hover: {
430                         enabled: false
431                     }
432                 },
433             line: {
434                 marker: {
435                     enabled: false
436                 }
437              },
438           }
439         },
440         xAxis:{
441             showFirstLabel: true,
442             showLastLabel:true,
443             scrollbar:{enabled:true},
444             labels: {
445                // staggerLines:5
446                 style: {         //字体样式
447                     font: 'normal 5px Verdana, sans-serif'
448                     },
449                 formatter:function(){
450                     var returnTime=Highcharts.dateFormat('%H:%M ', this.value);
451                     if(returnTime=="11:30 ")
452                     {
453                         return "11:30/13:00";
454                     }
455                     return returnTime;
456                 },
457             },
458             tickPositioner:function(){
459                 var positions=[am_startTimeUTC,am_midTimeUTC,am_lastTimeUTC,pm_midTimeUTC,pm_lastTimeUTC];
460                 return positions;
461             },
462              gridLineWidth: 1,
463         },
464         yAxis: [{
465             opposite: false,//是否把它显示到另一边(右边)
466             labels: {
467                 style: {         //字体样式
468                     font: 'normal 5px Verdana, sans-serif'
469                     },
470                      overflow: 'justify',
471                 align: 'right',
472                 x: -3,
473                 y:5,
474                 formatter:function(){
475                     //最新价  px_last/preclose昨收盘-1
476                     return (this.value).toFixed(2);
477                   }
478             },
479             title: {
480                 text: ''
481             },
482             top:'0%',
483             height: '65%',
484             lineWidth: 1,
485             showFirstLabel: true,
486             showLastLabel:true,
487             
488             tickPositioner:function(){    //以yesterdayClose为界限,统一间隔值,从 最小到最大步进
489                 positions = [],
490                 tick = Number((avg_pxyAxisMin)),
491                 increment = Number(((avg_pxyAxisMax - avg_pxyAxisMin) / 5));
492                   var tickMin=Number((avg_pxyAxisMin)),tickMax=Number((avg_pxyAxisMax));
493                 if(0==data.length){//还没有数据时,yesterdayClose 的幅值 在 -1% - 1%上下浮动
494                     tickMin=0.99*yesterdayClose;
495                     tickMax=1.01*yesterdayClose;
496                 }else if(0==increment){//有数据了  但是数据都是一样的幅值
497                     if(yesterdayClose>Number(avg_pxyAxisMin)){
498                         tickMin=Number(avg_pxyAxisMin);
499                         tickMax=2*yesterdayClose-Number(avg_pxyAxisMin);
500                     }else if(yesterdayClose<Number(avg_pxyAxisMin)){
501                         tickMax=Number(avg_pxyAxisMax);
502                         tickMin=yesterdayClose-(Number(avg_pxyAxisMax)-yesterdayClose);
503                     }else{
504                         tickMin=0.99*yesterdayClose;
505                         tickMax=1.01*yesterdayClose;
506                     }
507                 }else if(avg_pxyAxisMin-yesterdayClose<0&&avg_pxyAxisMax-yesterdayClose>0){//最小值在昨日收盘价下面,最大值在昨日收盘价上面
508                     var limit=Math.max(Math.abs(avg_pxyAxisMin-yesterdayClose),Math.abs(avg_pxyAxisMax-yesterdayClose));
509                     tickMin=yesterdayClose-limit;
510                     tickMax=yesterdayClose+limit;
511                 }else if(avg_pxyAxisMin>yesterdayClose&&avg_pxyAxisMax>yesterdayClose){//最小最大值均在昨日收盘价上面
512                     tickMax=avg_pxyAxisMax;
513                     tickMin=yesterdayClose-(tickMax-yesterdayClose);
514                     
515                 }else if(avg_pxyAxisMin<yesterdayClose&&avg_pxyAxisMax<yesterdayClose){//最小最大值均在昨日收盘价下面
516                     tickMin=avg_pxyAxisMin;
517                     tickMax=yesterdayClose+(yesterdayClose-tickMin);
518                 }
519                 if(tickMax>2*yesterdayClose){//数据超过100%了
520                     tickMax=2*yesterdayClose;
521                     tickMin=0;
522                 }
523                 var interval=Number(tickMax-yesterdayClose)/10;
524                 tickMax+=interval;
525                 tickMin=yesterdayClose-(tickMax-yesterdayClose);
526                 increment=(tickMax-yesterdayClose)/3;
527                 tick=tickMin;
528                 var i=0;
529                 for (tick;i ++ <7  ; tick += increment) {
530                     positions.push(Number(tick));
531                     }
532                 
533             return positions;
534             },
535         },
536         {
537             opposite: true,//是否把它显示到另一边(右边)
538             showFirstLabel: true,
539             showLastLabel:true,
540             labels: {
541                 overflow: 'justify',
542                 style: {         //字体样式
543                     font: 'normal 5px Verdana, sans-serif'
544                     },
545                 align: 'right',
546                 x: 25,
547                 y:5,
548                 formatter:function(){//最新价  px_last/preclose昨收盘-1
549                     return (100*(this.value/yesterdayClose-1)).toFixed(2)+"%";
550                   }
551             },
552             title: {
553                 text: ''
554             },
555             lineWidth: 1,
556             top:'0%',
557             height: '65%',
558             gridLineWidth: 1,
559             tickPositioner:function(){
560                 return positions;
561             }
562         },
563         {
564             opposite: false,//是否把它显示到另一边(右边)
565             labels: {
566                 overflow: 'justify',
567                 style: {         //字体样式
568                     font: 'normal 5px Verdana, sans-serif'
569                     },
570                 align: 'right',
571                 x: -3,
572                 y:5,
573                 formatter:function(){
574                     if(this.value>1000000000){
575                         return Number((this.value/1000000000).toFixed(2))+"G";
576                     }else if(this.value>1000000){
577                         return Number((this.value/1000000).toFixed(2))+"M";
578                     }else if(this.value>1000){
579                         return Number((this.value/1000).toFixed(2))+"K";
580                     }else{
581                         return Number(this.value.toFixed(2));
582                     }
583                 }
584             },
585             title: {
586                 text: ''
587             },
588             top: '70%',
589             height: '30%',
590             width:'100%',
591             offset: 0,
592             lineWidth: 1,
593             showFirstLabel: true,
594             showLastLabel:true,
595             tickPositioner:function(){
596                 var positions = [],
597                 tickMax=volume_yAxisMax,
598                 tickMin=volume_yAxisMin,
599                 tick = 0,
600                 increment = 0;
601                 var limit=tickMax/2;
602                 tickMax+=limit;
603                 increment=tickMax/2;
604                 tick=0;
605                 for (tick; tick  <= tickMax; tick += increment) {
606                     positions.push(Number(tick.toFixed(2)));
607                     if(increment==0){
608                         break;
609                     }
610                 }
611                 return positions;
612             },
613         }],
614         series : [{
615                     name : 'AAPL Stock Price',
616                     data : ohlc,
617                     type : 'areaspline',
618                     tooltip : {
619                         valueDecimals : 2
620                     },
621                     fillColor : {
622                         linearGradient : {
623                             x1: 0,
624                             y1: 0,
625                             x2: 0,
626                             y2: 1
627                         },
628                         stops : [
629                             [0, Highcharts.getOptions().colors[0]],
630                             [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
631                         ]
632                     },
633                     yAxis:0,
634                 },
635                 {
636                     name : 'AAPL Stock Price',
637                     data : ohlc,
638                     type : 'scatter',
639                     cursor:'pointer',
640                     onSeries : 'candlestick',
641                     color:'transparent',
642                     tooltip : {
643                         valueDecimals : 2
644                     },
645                     style:{
646                            fontSize: '0px',
647                            fontWeight: '0',
648                            textAlign: 'center'
649                        },
650                     zIndex:-1000,
651                     yAxis:1,
652                 },
653                 {
654                     type: 'column',
655                     name: '成交量',
656                     data: volume,
657                     dataGrouping: {
658                         enabled: false,
659                         forced: true
660                     },
661                     yAxis:2,
662                     zIndex:-1000
663                 }]
664     });
665 }
666 /**
667  * 错误处理
668  */
669 function failCallback(){
670     var last_dataTime=new Date();
671     var $reporting = $("#report");
672     $reporting.html("");
673      // Create the chart
674     var am_startTime=new Date(last_dataTime);
675     am_startTime.setHours(9, 30, 0, 0);
676     var am_startTimeUTC=Number(Date.UTC(am_startTime.getFullYear(),am_startTime.getMonth(),am_startTime.getDate(),am_startTime.getHours(),am_startTime.getMinutes()));
677     
678     var am_midTime=new Date(last_dataTime);
679     am_midTime.setHours(10, 30, 0, 0);
680     var am_midTimeUTC=Number(Date.UTC(am_midTime.getFullYear(),am_midTime.getMonth(),am_midTime.getDate(),am_midTime.getHours(),am_midTime.getMinutes()));
681     
682     //股票交易早上最后的时间
683     var am_lastTime=new Date(last_dataTime);
684     am_lastTime.setHours(11, 30, 0, 0);
685     var am_lastTimeUTC=Number(Date.UTC(am_lastTime.getFullYear(),am_lastTime.getMonth(),am_lastTime.getDate(),am_lastTime.getHours(),am_lastTime.getMinutes()));
686     //股票交易下午最后的时间
687     var pm_startTime=new Date(last_dataTime);
688     pm_startTime.setHours(13, 1, 0, 0);
689     var pm_startTimeUTC=Number(Date.UTC(pm_startTime.getFullYear(),pm_startTime.getMonth(),pm_startTime.getDate(),pm_startTime.getHours(),pm_startTime.getMinutes()));
690 
691     var pm_midTime=new Date(last_dataTime);
692     pm_midTime.setHours(14, 0, 0, 0);
693     var pm_midTimeUTC=Number(Date.UTC(pm_midTime.getFullYear(),pm_midTime.getMonth(),pm_midTime.getDate(),pm_midTime.getHours(),pm_midTime.getMinutes()));
694 
695     
696     var pm_lastTime=new Date(last_dataTime);
697     pm_lastTime.setHours(15, 0, 0, 0);
698     var pm_lastTimeUTC=Number(Date.UTC(pm_lastTime.getFullYear(),pm_lastTime.getMonth(),pm_lastTime.getDate(),pm_lastTime.getHours(),pm_lastTime.getMinutes()));
699     var data=[];
700     data.push({x:am_startTimeUTC,y:1});
701     data.push({x:am_midTimeUTC,y:2});
702     data.push({x:am_lastTimeUTC,y:3});
703     data.push({x:pm_midTimeUTC,y:4});
704     data.push({x:pm_lastTimeUTC,y:5});
705     //常量本地化
706     Highcharts.setOptions({
707         global : {
708             useUTC : true
709         }
710     });
711     $(DIVID).highcharts('StockChart', {
712          chart:{
713              renderTo : "line_map",
714              margin: [25, 25,25, 25],
715               plotBorderColor: '#3C94C4',
716               plotBorderWidth: 0.3,
717              // zoomType:false,
718          },
719          tooltip:{
720              enabled:false
721         },
722         rangeSelector:{
723             enabled: false,
724         },
725          /*导出配置*/
726         exporting: {
727             enabled: false,
728         },
729           /*创建者信息*/
730         credits: {
731             enabled: false,
732         },
733         /*下部时间拖拉选择*/
734         navigator: {
735             enabled: false,
736             /*关闭时间选择*/
737             baseseries: 10
738         },
739         /*底部滚动条*/
740         scrollbar: {
741             enabled: false
742         },
743         plotOptions:{
744             //去掉分时线上的hover事件
745             series: {
746                 states: {
747                     hover: {
748                         enabled: false
749                     }
750                 },
751             line: {
752                 marker: {
753                     enabled: false
754                 }
755              },
756             },
757         },
758         xAxis:{
759             showFirstLabel: true,
760             showLastLabel:true,
761              tickInterval: 1,
762             labels: {
763                 style: {         //字体样式
764                     font: 'normal 5px Verdana, sans-serif'
765                     },
766                 formatter:function(){
767                     var labels=['9:30','10:30','11:30/13:00','14:00','15:00']
768                     return labels[this.value];
769                 },
770             },
771             categories:['9:30','10:30','11:30/13:00','14:00','15:00'],
772             gridLineWidth: 1,
773         },
774         yAxis: [{
775             showFirstLabel: true,
776             showLastLabel:true,
777             opposite: false,//是否把它显示到另一边(右边)
778             labels: {
779                 align: 'right',
780                 x: -3,
781                 y:5
782             },
783             title: {
784                 text: ''
785             },
786             height: '50%',
787             lineWidth: 1,
788             gridLineWidth: 1,
789         },
790         {
791             showFirstLabel: true,
792             showLastLabel:true,
793             opposite: false,//是否把它显示到另一边(右边)
794             labels: {
795                 align: 'right',
796                 x: -3,
797                 y:5
798             },
799             title: {
800                 text: ''
801             },
802             top: '60%',
803             height: '40%',
804             offset: 0,
805             lineWidth: 1,
806             gridLindeWidth:1,
807         }],
808         series : [{
809                     name : 'AAPL Stock Price',
810                     data :[10,20,30,40,50],// [["9:30",200],["10:30",205]["11:30/13:00",210],["14:00",215],["15:00",220]],
811                     type:'column',
812                     color:'transparent',
813                     fillColor : {
814                         linearGradient : {
815                             x1: 0,
816                             y1: 0,
817                             x2: 0,
818                             y2: 1
819                         },
820                         stops : [
821                             [0, Highcharts.getOptions().colors[0]],
822                             [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
823                         ]
824                     },
825                     dataGrouping: {
826                         enabled: false,
827                         forced: true
828                     },
829                     yAxis:0,
830                 },
831                 {
832                     type: 'column',
833                     name: '成交量',
834                     fillColor : {
835                         linearGradient : {
836                             x1: 0,
837                             y1: 0,
838                             x2: 0,
839                             y2: 1
840                         },
841                         stops : [
842                             [0, Highcharts.getOptions().colors[0]],
843                             [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
844                         ]
845                         },
846                     data : [10,20,30,40,50],//[[0, 15], [10, -50], [20, -56.5], [30, -46.5], [40, -22.1],
847                                    //[50, -2.5], [60, -27.7], [70, -55.7], [80, -76.5]],
848                     color:'transparent',
849                        yAxis: 1,
850                     dataGrouping: {
851                         enabled: false,
852                         forced: true
853                     },
854                 yAxis:1,
855                 }]
856     });
857 }
858 /**
859  * 获取日期对象,如果isUTC为true获取 日期的UTC对象,false则获取普通日期对象
860  * @param date
861  * @param isUTC
862  * @returns
863  */
864 function getDateUTCOrNot(date,isUTC){
865         if(! (date instanceof String))
866         {    
867             date+="";
868         }
869         var dArr = new Array();
870         for(var hh=0;hh<5;hh++){
871             var numb ;
872             if(hh==0){
873                 numb = Number(date.slice(0,4));
874             }
875             else {
876                 numb= Number(date.slice((hh-1)*2+4,hh*2+4));
877                 };
878             dArr.push(numb);
879         }
880         if(isUTC==false){
881             return new Date(dArr[0],dArr[1]-1,dArr[2],dArr[3],dArr[4]);
882         }
883         var dateUTC = Number(Date.UTC(dArr[0],dArr[1]-1,dArr[2],dArr[3],dArr[4]));//得出的UTC时间
884         return dateUTC;
885 }
886 
887 //数据补全
888 function appendTimeMessage(ohlc,volume,data){
889     var date=data[data.length-1][0]+"";
890     var last_dataTime=getDateUTCOrNot(date,false);
891     
892     //股票交易早上最后的时间
893     var am_lastTime=new Date(last_dataTime);
894     am_lastTime.setHours(11, 30, 0, 0);
895     //股票交易下午最后的时间
896     var pm_startTime=new Date(last_dataTime);
897     pm_startTime.setHours(13, 1, 0, 0);
898     var pm_lastTime=new Date(last_dataTime);
899     pm_lastTime.setHours(15, 0, 0, 0);
900     //把时间日期格式转化成utc格式
901     function convertDateToUTC(date){
902         return Number(Date.UTC(date.getFullYear(),date.getMonth(),date.getDate(),date.getHours(),date.getMinutes()));
903     }
904 //如果获取的时间11::30之前的计算
905     if(last_dataTime<am_lastTime){
906         var i=last_dataTime;
907         i.setMinutes((i.getMinutes()+1));
908         for(;i<=am_lastTime;i.setMinutes((i.getMinutes()+1)))
909         {
910             ohlc.push({x:convertDateToUTC(i)});
911             volume.push({x:convertDateToUTC(i)});
912         }
913         i=pm_startTime;
914         for(;i<=pm_lastTime;i.setMinutes((i.getMinutes()+1)))
915         {
916             ohlc.push({x:convertDateToUTC(i)});
917             volume.push({x:convertDateToUTC(i)});
918         }
919     }else if(last_dataTime<pm_lastTime){    //获取的时间下午13:00之后的计算
920         var i;
921         if(Number(last_dataTime)==Number(am_lastTime)){
922             i=pm_startTime;
923         }else{
924             i=last_dataTime;
925         }
926         i.setMinutes((i.getMinutes()+1));
927         for(;i<=pm_lastTime;i.setMinutes((i.getMinutes()+1)))
928         {
929             ohlc.push({x:convertDateToUTC(i)});
930             volume.push({x:convertDateToUTC(i)});
931         }
932     }
933 }

 

 

posted on 2015-05-05 19:55  wf110  阅读(11053)  评论(16编辑  收藏  举报