diff --git a/vuehqchart/src/jscommon/umychart.complier.js b/vuehqchart/src/jscommon/umychart.complier.js index b66ff4c557971521dfd25c61d39e8c99e8b8c6aa..f1c62d5f4462de228ac459039a91db3611b9d054 100644 --- a/vuehqchart/src/jscommon/umychart.complier.js +++ b/vuehqchart/src/jscommon/umychart.complier.js @@ -9073,7 +9073,7 @@ function ScriptIndex(name,script,args,option) return; } - //清空指标图形 + //清空主指标图形 hqChart.DeleteIndexPaint(windowIndex); if (windowIndex==0) hqChart.ShowKLine(true); @@ -9232,6 +9232,595 @@ function ScriptIndex(name,script,args,option) } } +function OverlayScriptIndex(name,script,args,option) +{ + this.newMethod=ScriptIndex; //派生 + this.newMethod(name,script,args,option); + delete this.newMethod; + + //叠加指标 + this.OverlayIndex=null; // { IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame } + + this.BindData=function(hqChart,windowIndex,hisData) + { + if (!this.OverlayIndex || this.OverlayIndex.IsOverlay!=true) return; + + this.OverlayIndex.Frame.ChartPaint=[]; + if (this.OutVar==null || this.OutVar.length<0) return; + + /*叠加一个K线背景 + if (this.KLineType!=null) + { + if (this.KLineType===0 || this.KLineType===1 || this.KLineType===2) this.CreateSelfKLine(hqChart,windowIndex,hisData); + else if (this.KLineType===-1 && windowIndex==0) hqChart.ShowKLine(false); + } + + if (windowIndex>=1 && hqChart.Frame) + { + hqChart.Frame.SubFrame[windowIndex].Frame.YSplitOperator.FloatPrecision=this.FloatPrecision; + if (this.YSpecificMaxMin) hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin=this.YSpecificMaxMin; //最大最小值 + if (this.YSplitScale) hqChart.Frame.SubFrame[windowIndex].Frame.YSplitScale=this.YSplitScale; //固定刻度 + } + */ + + //指标名字 + var titleInfo={ Data:[], Title:this.Name }; + let indexParam=''; + for(var i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + if (indexParam.length>0) titleInfo.Title=this.Name+'('+indexParam+')'; + + var titleIndex=windowIndex+1; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.set(this.OverlayIndex.Identify,titleInfo); + + for(var i in this.OutVar) + { + let item=this.OutVar[i]; + if (item.IsExData===true) continue; //扩展数据不显示图形 + + if (item.Type==0) + { + this.CreateLine(hqChart,windowIndex,item,i); + } + else if (item.Type==1) + { + switch(item.Draw.DrawType) + { + case 'STICKLINE': + this.CreateBar(hqChart,windowIndex,item,i); + break; + case 'DRAWTEXT': + case 'SUPERDRAWTEXT': + this.CreateText(hqChart,windowIndex,item,i); + break; + case 'DRAWLINE': + this.CreateStraightLine(hqChart,windowIndex,item,i); + break; + case 'DRAWBAND': + this.CreateBand(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE_IF': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'POLYLINE': + this.CreatePolyLine(hqChart,windowIndex,item,i); + break; + case 'DRAWNUMBER': + this.CreateNumberText(hqChart,windowIndex,item,i); + break; + case 'DRAWICON': + this.CreateIcon(hqChart,windowIndex,item,i); + break; + case 'DRAWCHANNEL': + this.CreateChannel(hqChart,windowIndex,item,i); + break; + } + } + else if (item.Type==2) + { + this.CreateMACD(hqChart,windowIndex,item,i); + } + else if (item.Type==3) + { + this.CreatePointDot(hqChart,windowIndex,item,i); + } + else if (item.Type==4) + { + this.CreateLineStick(hqChart,windowIndex,item,i); + } + else if (item.Type==5) + { + this.CreateStick(hqChart,windowIndex,item,i); + } + else if (item.Type==6) + { + this.CreateVolStick(hqChart,windowIndex,item,i,hisData); + } + } + + + /* + hqChart.TitlePaint[titleIndex].Title=this.Name; + + let indexParam=''; + for(let i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + + if (indexParam.length>0) hqChart.TitlePaint[titleIndex].Title=this.Name+'('+indexParam+')'; + */ + + return true; + } + + //指标执行完成 + this.RecvResultData=function(outVar,param) + { + let hqChart=param.HQChart; + let windowIndex=param.WindowIndex; + let hisData=param.HistoryData; + param.Self.OutVar=outVar; + param.Self.BindData(hqChart,windowIndex,hisData); + + param.HQChart.UpdataDataoffset(); //更新数据偏移 + param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值 + param.HQChart.Draw(); + + var event=hqChart.GetOverlayIndexEvent(); //指标计算完成回调 + if (event) + { + var self=param.Self; + var data={ OutVar:self.OutVar, WindowIndex: windowIndex, Name: self.Name, Arguments: self.Arguments, HistoryData: hisData, + Identify:self.OverlayIndex.Identify, + Stock: {Symbol:hqChart.Symbol,Name:hqChart.Name} }; + event.Callback(event,data,self); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + // 图形创建 + ///////////////////////////////////////////////////////////////////////////////////// + + this.CreateLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.DrawType=1; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) line.LineWidth=width; + } + + if (varItem.IsShow==false) line.IsShow=false; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + //创建柱子 + this.CreateBar=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStickLine(); + chart.Canvas=hqChart.Canvas; + if (varItem.Draw.Width>0) chart.LineWidth=varItem.Draw.Width; + else chart.LineWidth=1; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建文本 + this.CreateText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + chart.Text=varItem.Draw.Text; + if (varItem.Draw.Direction>0) chart.Direction=varItem.Draw.Direction; + if (varItem.Draw.YOffset>0) chart.YOffset=varItem.Draw.YOffset; + if (varItem.Draw.TextAlign) chart.TextAlign=varItem.Draw.TextAlign; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //COLORSTICK + this.CreateMACD=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartMACD(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,this.GetDefaultColor(id)); + + frame.ChartPaint.push(chart); + } + + this.CreatePointDot=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartPointDot(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.Radius) chart.Radius=varItem.Radius; + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.Radius=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateLineStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLineStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStraightLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.DrawType=1; + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(line.Data,varItem.Name,line.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateVolStick=function(hqChart,windowIndex,varItem,id,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartVolStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + chart.KLineDrawType=hqChart.KLineDrawType; //设置K线显示类型 + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + chart.HistoryData=hisData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateBand=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartBand(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.FirstColor = varItem.Draw.Color[0]; + chart.SecondColor = varItem.Draw.Color[1]; + chart.Data.Data=varItem.Draw.DrawData; + + frame.ChartPaint.push(chart); + } + + //创建K线图 + this.CreateKLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data.Data=varItem.Draw.DrawData; + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + + if (varItem.Color) //如果设置了颜色,使用外面设置的颜色 + chart.UnchagneColor=chart.DownColor=chart.UpColor=this.GetColor(varItem.Color); + + frame.ChartPaint.push(chart); + } + + this.CreatePolyLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(line.Data,' ',line.Color); //给一个空的标题 + + frame.ChartPaint.push(chart); + } + + this.CreateNumberText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData.Value; + chart.Text=varItem.Draw.DrawData.Text; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建图标 + this.CreateIcon=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + chart.TextAlign='center'; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var icon=varItem.Draw.Icon; + if (icon.IconFont==true) + { + chart.IconFont={ Family:icon.Family, Text:icon.Symbol, Color:icon.Color }; + } + else + { + chart.Text=icon.Symbol; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else if (icon.Color) chart.Color=icon.Color; + else chart.Color='rgb(0,0,0)'; + } + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建通道 + this.CreateChannel=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartChannel(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + if(varItem.Draw.AreaColor) chart.AreaColor=varItem.Draw.AreaColor; + else if (varItem.Color) chart.AreaColor=this.GetColor(varItem.Color); + else chart.AreaColor=this.GetDefaultColor(id); + + if (varItem.Draw.Border.Color) chart.LineColor=varItem.Draw.Border.Color; + else chart.LineColor=null; + + if (varItem.Draw.Border.Dotted) chart.LineDotted=varItem.Draw.Border.Dotted; + if (varItem.Draw.Border.Width>0) chart.LineWidth=varItem.Draw.Border.Width; + + //let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + frame.ChartPaint.push(chart); + } + + //创建K线 + this.CreateSelfKLine=function(hqChart,windowIndex,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name="Self Kline" + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data=hisData + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + chart.DrawType=this.KLineType; + + frame.ChartPaint.push(chart); + } + + //给一个默认的颜色 + this.GetDefaultColor=function(id) + { + let COLOR_ARRAY= + [ + "rgb(24,71,178)", + "rgb(42,230,215)", + "rgb(252,96,154)", + "rgb(0,128,255)", + "rgb(229,0,79)", + "rgb(68,114,196)", + "rgb(255,174,0)", + "rgb(25,199,255)", + "rgb(175,95,162)", + "rgb(236,105,65)", + ]; + + let number=parseInt(id); + return COLOR_ARRAY[number%(COLOR_ARRAY.length-1)]; + } +} + //后台执行指标 function APIScriptIndex(name,script,args,option) { diff --git a/vuehqchart/src/jscommon/umychart.index.data.js b/vuehqchart/src/jscommon/umychart.index.data.js index b763756175595584c7b3b013b622b8d64f821e1b..367a0f82cc96074a2dfb1eb4afd8f4ae4dac3c7f 100644 --- a/vuehqchart/src/jscommon/umychart.index.data.js +++ b/vuehqchart/src/jscommon/umychart.index.data.js @@ -43,7 +43,7 @@ function JSIndexScript() ['DMI', this.DMI],['CR', this.CR],['PSY', this.PSY], ['CCI', this.CCI],['DMA', this.DMA],['TRIX', this.TRIX], ['VR', this.VR],['EMV', this.EMV],['ROC', this.ROC], - ['MTM', this.MIM],['FSL', this.FSL],['CYR', this.CYR], + ['MTM', this.MTM],['FSL', this.FSL],['CYR', this.CYR], ['MASS', this.MASS],['WAD', this.WAD],['CHO', this.CHO], ['ADTM', this.ADTM],['HSL', this.HSL],['BIAS36', this.BIAS36], ['BIAS_QL', this.BIAS_QL],['DPO', this.DPO],['OSC', this.OSC], diff --git a/vuehqchart/src/jscommon/umychart.js b/vuehqchart/src/jscommon/umychart.js index 75ac9bad18c6e130911e13ef36b424ae0dbebe94..f0da77903fd26961a1627a224636bca511f824d8 100644 --- a/vuehqchart/src/jscommon/umychart.js +++ b/vuehqchart/src/jscommon/umychart.js @@ -245,9 +245,19 @@ function JSChart(divElement) if (item.Modify!=null) chart.Frame.SubFrame[i].Frame.ModifyIndex=item.Modify; if (item.Change!=null) chart.Frame.SubFrame[i].Frame.ChangeIndex=item.Change; if (item.Close!=null) chart.Frame.SubFrame[i].Frame.CloseIndex=item.Close; + if (item.Overlay!=null) chart.Frame.SubFrame[i].Frame.OverlayIndex=item.Overlay; if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight=item.TitleHeight; } + + //叠加指标 + for (var i in option.OverlayIndex) + { + var item=option.OverlayIndex[i]; + if (item.Windows>=chart.Frame.SubFrame.length) continue; + chart.CreateOverlayWindowsIndex(item.Windows,item.Index); + } + this.AdjustTitleHeight(chart); return chart; @@ -1012,6 +1022,7 @@ var JSCHART_EVENT_ID= RECV_TRAIN_MOVE_STEP:4, //接收K线训练,移动一次K线 CHART_STATUS:5, //每次Draw() 以后会调用 BARRAGE_PLAY_END:6, //单个弹幕播放完成 + RECV_OVERLAY_INDEX_DATA:7,//接收叠加指标数据 } var JSCHART_OPERATOR_ID= @@ -1100,13 +1111,22 @@ function JSChartContainer(uielement) this.mapEvent.delete(eventid); } + this.GetEventCallback=function(id) //获取事件回调 + { + if (!this.mapEvent.has(id)) return null; + var item=this.mapEvent.get(id); + return item; + } + //接收指标数据 this.GetIndexEvent=function() { - if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_INDEX_DATA)) return null; + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_INDEX_DATA); + } - var item=this.mapEvent.get(JSCHART_EVENT_ID.RECV_INDEX_DATA); - return item; + this.GetOverlayIndexEvent=function() + { + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_OVERLAY_INDEX_DATA); } uielement.onmousemove=function(e) @@ -1603,6 +1623,8 @@ function JSChartContainer(uielement) item.Draw(); } + this.Frame.DrawOveraly(); //画叠加指标 + //固定扩展图形 for(var i in this.ExtendChartPaint) { @@ -2189,6 +2211,17 @@ function JSChartContainer(uielement) } item.Frame.XYSplit=true; } + + //更新子坐标 + for(var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + overlayItem.UpdateFrameMaxMin(); + } + } } this.DataMoveLeft=function() @@ -2243,6 +2276,23 @@ function JSChartContainer(uielement) if (!item.Data) continue; item.Data.DataOffset=data.DataOffset; } + + //叠加指标当前显示的数据偏移 + for (var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + for(var k in overlayItem.ChartPaint) + { + var item=overlayItem.ChartPaint[k]; + if (!item.Data) continue; + item.Data.DataOffset=data.DataOffset; + } + } + } + } this.DataMove=function(step,isLeft) @@ -2384,7 +2434,7 @@ function JSChartContainer(uielement) if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存 console.log('[JSChartContainer::SaveToImage]', this.UIElement); - clrBG='rgb(255,255,255)'; + var clrBG='rgb(255,255,255)'; if (colorGB) clrBG=colorGB; this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height); this.Canvas.fillStyle=clrBG; @@ -3416,6 +3466,7 @@ function KLineFrame() this.ModifyIndex=true; //是否显示'改参数'菜单 this.ChangeIndex=true; //是否显示'换指标'菜单 this.CloseIndex=true; //是否显示'关闭指标窗口'菜单 + this.OverlayIndex=false; //是否显示叠加指标 this.ModifyIndexEvent; //改参数 点击事件 this.ChangeIndexEvent; //换指标 点击事件 @@ -3433,7 +3484,7 @@ function KLineFrame() this.ChartBorder.UIElement.parentNode.appendChild(divToolbar); } - if (!this.ModifyIndex && !this.ChangeIndex) + if (!this.ModifyIndex && !this.ChangeIndex && !this.OverlayIndex) { divToolbar.style.display='none'; return; @@ -3450,7 +3501,8 @@ function KLineFrame() var left=chartWidth-(this.ChartBorder.Right/pixelTatio)-toolbarWidth; var top=this.ChartBorder.GetTop()/pixelTatio; var spanIcon = "  " + - ""; + "  " + + ""; if (this.Identify!==0 && this.CloseIndex) //第1个窗口不能关闭 { @@ -3479,13 +3531,32 @@ function KLineFrame() },this.ModifyIndexEvent); if (!this.ChangeIndex) //隐藏'换指标' + { $("#"+divToolbar.id+" .index_change").hide(); + } else if (typeof(this.ChangeIndexEvent)=='function') + { $("#"+divToolbar.id+" .index_change").click( { Chart:this.ChartBorder.UIElement.JSChartContainer, - Identify:this.Identify + Identify:this.Identify, + IsOverlay:false + },this.ChangeIndexEvent); + } + + if (!this.OverlayIndex) + { + $("#"+divToolbar.id+" .index_overlay").hide(); + } + else + { + $("#"+divToolbar.id+" .index_overlay").click( + { + Chart:this.ChartBorder.UIElement.JSChartContainer, + Identify:this.Identify, + IsOverlay:true },this.ChangeIndexEvent); + } $("#"+divToolbar.id+" .index_close").click( { @@ -3724,6 +3795,93 @@ function KLineFrame() } } +function OverlayKLineFrame() +{ + this.newMethod=KLineFrame; //派生 + this.newMethod(); + delete this.newMethod; + + this.MainFrame=null; //主框架 + this.RightOffset=50; + this.PenBorder=g_JSChartResource.OverlayFrameBolderPen; //'rgb(0,0,0)' + + this.Draw=function() + { + this.SplitXYCoordinate(); + + this.DrawVertical(); + this.DrawHorizontal(); + + this.SizeChange=false; + this.XYSplit=false; + } + + //分割x,y轴坐标信息 + this.SplitXYCoordinate=function() + { + if (this.XYSplit==false) return; + if (this.YSplitOperator!=null) this.YSplitOperator.Operator(); + // if (this.XSplitOperator!=null) this.XSplitOperator.Operator(); 子坐标和主坐标X轴一致 所以不用计算 + } + + //画Y轴 + this.DrawHorizontal=function() + { + var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom = this.ChartBorder.GetBottom(); + var top = this.ChartBorder.GetTopTitle(); + var borderRight=this.ChartBorder.Right; + right+=this.RightOffset; + + var yPrev=null; //上一个坐标y的值 + for(var i=this.HorizontalInfo.length-1; i>=0; --i) //从上往下画分割线 + { + var item=this.HorizontalInfo[i]; + var y=this.GetYFromData(item.Value); + if (y!=null && Math.abs(y-yPrev)= bottom - 2) this.Canvas.textBaseline = 'bottom'; + else if (y <= top + 2) this.Canvas.textBaseline = 'top'; + else this.Canvas.textBaseline = "middle"; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(right-5,ToFixedPoint(y)); + this.Canvas.lineTo(right,ToFixedPoint(y)); + this.Canvas.stroke(); + + //坐标信息 右边 间距小于10 不画坐标 + if (item.Message[1]!=null && borderRight>10) + { + if (item.Font!=null) this.Canvas.font=item.Font; + + this.Canvas.fillStyle=item.TextColor; + this.Canvas.textAlign="left"; + this.Canvas.fillText(item.Message[1],right+2,y); + } + + yPrev=y; + } + } + + //画X轴 + this.DrawVertical=function() + { + var top=this.ChartBorder.GetTopEx(); + //var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom=this.ChartBorder.GetBottomEx(); + right+=this.RightOffset; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(ToFixedPoint(right),ToFixedPoint(top)); + this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(bottom)); + this.Canvas.stroke(); + } +} + //K线横屏框架 function KLineHScreenFrame() { @@ -4005,6 +4163,36 @@ function SubFrameItem() { this.Frame; this.Height; + this.OverlayIndex=[]; //叠加指标 + this.Interval=50; //子坐标间间距 +} + +function OverlayIndexItem() +{ + this.Frame; + this.ChartPaint=[]; + this.Identify=Guid(); + this.Scprit; //脚本 + + this.UpdateFrameMaxMin=function() //调整坐标最大 最小值 + { + var value={Max:null, Min:null} + for(var i in this.ChartPaint) + { + var paint=this.ChartPaint[i]; + var range=paint.GetMaxMin(); + + if (value.Max==null || value.Maxrange.Min) value.Min=range.Min + } + + if (value.Max!=null && value.Min!=null) + { + this.Frame.HorizontalMax=value.Max; + this.Frame.HorizontalMin=value.Min; + this.Frame.XYSplit=true; + } + } } //行情框架 @@ -4053,10 +4241,41 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.Draw(); + + var rightOffset=item.Interval; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + //把主坐标部分设置给子坐标下来 + overlayItem.Frame.DataWidth=item.Frame.DataWidth; + overlayItem.Frame.DistanceWidth=item.Frame.DistanceWidth; + overlayItem.Frame.XPointCount=item.Frame.XPointCount; + if (overlayItem.ChartPaint.length>0) + overlayItem.Frame.RightOffset=rightOffset; + overlayItem.Frame.Draw(); + rightOffset+=item.Interval; + } } this.SizeChange=false; } + + this.DrawOveraly=function() + { + for(var i in this.SubFrame) + { + var item=this.SubFrame[i]; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + for(k in overlayItem.ChartPaint) + { + overlayItem.ChartPaint[k].Draw(); + } + } + } + } + this.DrawLock=function() { for (var i in this.SubFrame) @@ -4083,6 +4302,12 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.SizeChange=sizeChange; + + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + if (overlayItem.Frame) overlayItem.Frame.SizeChange=sizeChange; + } } //画布的位置 @@ -4163,12 +4388,26 @@ function HQTradeFrame() this.ZoomUp=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomUp(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -4177,12 +4416,26 @@ function HQTradeFrame() this.ZoomDown=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomDown(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -5474,6 +5727,7 @@ function ChartKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartKLine'; //类名 this.Symbol; //股票代码 this.DrawType=0; // 0=实心K线柱子 1=收盘价线 2=美国线 3=空心K线柱子 this.CloseLineColor=g_JSChartResource.CloseLineColor; @@ -6522,10 +6776,10 @@ function ChartOverlayKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartOverlayKLine'; //类名 this.Color="rgb(65,105,225)"; this.MainData; //主图K线数据 this.SourceData; //叠加的原始数据 - this.Name="ChartOverlayKLine"; this.Title; this.DrawType=0; @@ -6993,6 +7247,7 @@ function ChartMinuteVolumBar() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinuteVolumBar'; //类名 this.UpColor = g_JSChartResource.UpBarColor; this.DownColor = g_JSChartResource.DownBarColor; this.YClose; //前收盘 @@ -7072,6 +7327,7 @@ function ChartLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth; //线段宽度 this.DrawType=0; //画图方式 0=无效数平滑 1=无效数不画断开 @@ -7202,6 +7458,7 @@ function ChartPointDot() this.newMethod(); delete this.newMethod; + this.ClassName='ChartPointDot'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Radius=1; //点半径 @@ -7583,6 +7840,7 @@ function ChartLineMultiData() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLineMultiData'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -7676,6 +7934,7 @@ function ChartStickLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStickLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth=2*GetDevicePixelRatio(); //线段宽度 @@ -7826,6 +8085,7 @@ function ChartText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartText'; //类名 this.TextFont="14px 微软雅黑"; this.Draw=function() @@ -7906,6 +8166,7 @@ function ChartSingleText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartSingleText'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.TextFont="14px 微软雅黑"; //线段宽度 this.Text; @@ -8079,6 +8340,7 @@ function ChartStraightLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -8135,6 +8397,7 @@ function ChartStraightArea() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightArea'; //类名 this.Color = "rgb(255,193,37)"; //线段颜色 this.Font ='11px 微软雅黑'; @@ -8265,6 +8528,7 @@ function ChartMinutePriceLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinutePriceLine'; //类名 this.YClose; this.IsDrawArea=true; //是否画价格面积图 this.AreaColor='rgba(0,191,255,0.1)'; @@ -8441,7 +8705,7 @@ function ChartOverlayMinutePriceLine() this.MainData; //主图数据 this.MainYClose; //主图股票的前收盘价 - this.Name="ChartOverlayMinutePriceLine"; + this.ClassName="ChartOverlayMinutePriceLine"; this.Title; this.Symbol; //叠加的股票代码 this.YClose; //叠加的股票前收盘 @@ -8543,6 +8807,7 @@ function ChartMACD() this.newMethod(); delete this.newMethod; + this.ClassName="ChartMACD"; this.UpColor=g_JSChartResource.UpBarColor; this.DownColor=g_JSChartResource.DownBarColor; @@ -8626,6 +8891,7 @@ function ChartBar() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBar"; this.UpBarColor=g_JSChartResource.UpBarColor; this.DownBarColor=g_JSChartResource.DownBarColor; @@ -8721,6 +8987,7 @@ function ChartBand() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartBand"; this.FirstColor = g_JSChartResource.Index.LineColor[0]; this.SecondColor = g_JSChartResource.Index.LineColor[1]; @@ -8828,6 +9095,7 @@ function ChartChannel() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartChannel"; this.IsHScreen=false; //是否是横屏 this.PointCount=0; this.DataWidth=0; @@ -8989,6 +9257,8 @@ function ChartLock() this.newMethod=IChartPainting; //派生 this.newMethod(); delete this.newMethod; + + this.ClassName="ChartLock"; this.WidthDiv = 0.2; // 框子宽度占比 this.LockCount = 20; // 锁最新的几个数据 this.BGColor = g_JSChartResource.LockBGColor; @@ -9133,6 +9403,7 @@ function ChartBuySell() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBuySell"; this.TextFont=g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体 this.LastDataIcon=g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'}; this.BuyIcon=g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'}; @@ -12986,6 +13257,7 @@ function DynamicChartTitlePainting() this.Explain; this.ColorIndex; //五彩K线名字 {Name:'名字'} this.TradeIndex; //专家系统名字{Name:'名字'} + this.OverlayIndex=new Map(); //叠加指标 key=Identify value={ Data:数据, Title:标题, Identify:标识} this.FormatValue=function(value,item) { @@ -13136,6 +13408,83 @@ function DynamicChartTitlePainting() this.Canvas.fillText(this.TradeIndex.Name,left,bottom,textWidth); left+=textWidth; } + + this.DrawOverlayIndex(left); + } + + this.DrawOverlayIndex=function(left) //叠加指标标题 + { + var bottom=this.Frame.ChartBorder.GetTop()+this.Frame.ChartBorder.TitleHeight/2; //上下居中显示 + var right=this.Frame.ChartBorder.GetRight(); + if (left>right) return; + + var spaceWidth=5*GetDevicePixelRatio(); + var drawLeft=left; + for(item of this.OverlayIndex) + { + left+=spaceWidth; + overlayItem=item[1]; + if (overlayItem.Title) + { + this.Canvas.fillStyle=this.TitleColor; + var textWidth=this.Canvas.measureText(overlayItem.Title).width+2; + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(overlayItem.Title,drawLeft,bottom,textWidth); + } + + for(var i in overlayItem.Data) + { + var item=overlayItem.Data[i]; + if (!item || !item.Data || !item.Data.Data || !item.Name) continue; + if (item.Data.Data.length<=0) continue; + + var value=null; + var valueText=null; + if (item.DataType=="StraightLine") //直线只有1个数据 + { + value=item.Data.Data[0]; + valueText=this.FormatValue(value,item); + } + else + { + var index=Math.abs(this.CursorIndex-0.5); + index=parseInt(index.toFixed(0)); + var dataIndex=item.Data.DataOffset+index; + if (dataIndex>=item.Data.Data.length) dataIndex=item.Data.Data.length-1; + if (dataIndex<0) continue; + + value=item.Data.Data[dataIndex]; + if (value==null) continue; + + if (item.DataType=="HistoryData-Vol") + { + value=value.Vol; + valueText=this.FormatValue(value,item); + } + else if (item.DataType=="MultiReport") + { + valueText=this.FormatMultiReport(value,item); + } + else + { + valueText=this.FormatValue(value,item); + } + } + + this.Canvas.fillStyle=item.Color; + + var text=item.Name+":"+valueText; + var textWidth=this.Canvas.measureText(text).width+2; //后空2个像素 + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(text,drawLeft,bottom,textWidth); + } + + if (left>right) break; + } } this.HScreenDraw=function() @@ -16036,6 +16385,7 @@ function JSChartResource() this.FrameSplitTextColor="rgb(117,125,129)"; //刻度文字颜色 this.FrameSplitTextFont=14*GetDevicePixelRatio() +"px 微软雅黑"; //坐标刻度文字字体 this.FrameTitleBGColor="rgb(246,251,253)"; //标题栏背景色 + this.OverlayFrameBolderPen='rgb(190,190,190)' this.CorssCursorBGColor="rgb(43,54,69)"; //十字光标背景 this.CorssCursorTextColor="rgb(255,255,255)"; @@ -17567,7 +17917,6 @@ function KLineChartContainer(uielement) this.SetCustomShow(this.CustomShow,hisData); this.CustomShow=null; } - } this.UpdateMainData=function(hisData) @@ -17661,6 +18010,26 @@ function KLineChartContainer(uielement) this.WindowIndex[windowIndex].BindData(this,windowIndex,hisData); } + //叠加指标 + this.BindOverlayIndexData=function(overlayItem, windowIndex, hisData) + { + if (!overlayItem.Script) return; + + if (typeof(overlayItem.Script.RequestData)=='function') + { + overlayItem.Script.RequestData(this,windowIndex,hisData); + return; + } + + if (typeof(overlayItem.Script.ExecuteScript)=='function') + { + overlayItem.Script.ExecuteScript(this,windowIndex,hisData); + return; + } + + overlayItem.Script.BindData(this,windowIndex,hisData); + } + //执行指示(专家指示 五彩K线) this.BindInstructionIndexData=function(hisData) { @@ -17787,6 +18156,17 @@ function KLineChartContainer(uielement) this.Draw(); this.UpdatePointByCursorIndex(); //更新十字光标位子 + //叠加指标 + for(var i=0;i0) + { + var delOverlayIndexMenu={ text:'删除叠加指标', children:this.GetDeleteOverlayIndex(chart,overlayIndex) } + dataList.splice(3,0,delOverlayIndexMenu); + } + console.log('[KLineRightMenu::DoModal]',identify); rightMenu.Show({ windowIndex :identify, @@ -26560,6 +27060,36 @@ function KLineRightMenu(divElement) rightMenu.Hide(); }); } + + this.GetOverlayIndex=function(chart, windowsIndex) + { + if (windowsIndex>=chart.Frame.SubFrame.length) return []; + + var result=[]; + var item=chart.Frame.SubFrame[windowsIndex]; + for(var i in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[i]; + result.push({Name:overlayItem.Script.Name, Identify:overlayItem.Identify}); + } + + return result; + } + + this.GetDeleteOverlayIndex=function(chart,overlayIndex) + { + var data=[]; + for(var i in overlayIndex) + { + let identify=overlayIndex[i].Identify; + data.push({text:overlayIndex[i].Name, click:function() + { + chart.DeleteOverlayWindowsIndex(identify) + }}); + } + + return data; + } } //K线区间选择右键菜单 diff --git a/vuehqchart/src/jscommon/umychart.resource/font/iconfont.css b/vuehqchart/src/jscommon/umychart.resource/font/iconfont.css index d6b7f03d1d2c68e75a21902c30fc1ec2cde18fee..1cd07be6a0e0052a489aaeb6302ca2acf9bf2249 100644 --- a/vuehqchart/src/jscommon/umychart.resource/font/iconfont.css +++ b/vuehqchart/src/jscommon/umychart.resource/font/iconfont.css @@ -1,405 +1,425 @@ @font-face {font-family: "iconfont"; - src: url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.eot?t=1559700636847'); /* IE9 */ - src: url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.eot?t=1559700636847#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), - url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.woff?t=1559700636847') format('woff'), - url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.ttf?t=1559700636847') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ - url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.svg?t=1559700636847#iconfont') format('svg'); /* iOS 4.1- */ - } - - .iconfont { - font-family: "iconfont" !important; - font-size: 16px; - font-style: normal; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - - .icon-drawicon_dollar:before { - content: "\e626"; - } - - .icon-arrow_left:before { - content: "\e680"; - } - - .icon-drawicon_message:before { - content: "\e64d"; - } - - .icon-drawicon_s:before { - content: "\e64c"; - } - - .icon-drawicon_b:before { - content: "\e70f"; - } - - .icon-drawicon_good:before { - content: "\e624"; - } - - .icon-drawicon_bad:before { - content: "\e600"; - } - - .icon-menu_arraw_right:before { - content: "\e60b"; - } - - .icon-menu_arraw_left:before { - content: "\e60d"; - } - - .icon-drawicon_up:before { - content: "\e625"; - } - - .icon-drawicon_close:before { - content: "\e68c"; - } - - .icon-draw_arc:before { - content: "\e602"; - } - - .icon-index_param:before { - content: "\e604"; - } - - .icon-draw_line:before { - content: "\e605"; - } - - .icon-draw_rays:before { - content: "\e606"; - } - - .icon-rectangle:before { - content: "\e607"; - } - - .icon-draw_parallel_lines:before { - content: "\e608"; - } - - .icon-setting:before { - content: "\e609"; - } - - .icon-recycle_bin:before { - content: "\e60a"; - } - - .icon-close:before { - content: "\e60c"; - } - - .icon-draw_trendline:before { - content: "\e60e"; - } - - .icon-draw_goldensection:before { - content: "\e60f"; - } - - .icon-draw_gannfan:before { - content: "\e610"; - } - - .icon-draw_percentage:before { - content: "\e611"; - } - - .icon-draw_waveband:before { - content: "\e612"; - } - - .icon-draw_resline:before { - content: "\e613"; - } - - .icon-draw_text:before { - content: "\e614"; - } - - .icon-draw_parallelchannel:before { - content: "\e615"; - } - - .icon-draw_wavemw:before { - content: "\e616"; - } - - .icon-chip_date:before { - content: "\e617"; - } - - .icon-draw_triangle:before { - content: "\e61a"; - } - - .icon-draw_pricechannel:before { - content: "\e61b"; - } - - .icon-draw_circle:before { - content: "\e61c"; - } - - .icon-draw_symangle:before { - content: "\e61d"; - } - - .icon-draw_hline:before { - content: "\e61e"; - } - - .icon-chip_default:before { - content: "\e621"; - } - - .icon-arrow_down:before { - content: "\e681"; - } - - .icon-arrow_right:before { - content: "\e682"; - } - - .icon-arrow_up:before { - content: "\e683"; - } - - .icon-draw_quadrangle:before { - content: "\e62c"; - } - - .icon-draw_fibonacci:before { - content: "\e62d"; - } - - .icon-right:before { - content: "\e601"; - } - - .icon-left:before { - content: "\e603"; - } - - .icon-xia:before { - content: "\e618"; - } - - .icon-shang:before { - content: "\e619"; - } - - .icon-jiacu:before { - content: "\e61f"; - } - - .icon-shezhi:before { - content: "\e620"; - } - - .icon-qingxieL:before { - content: "\e622"; - } - - .icon-info_pforecast:before { - content: "\e62e"; - } - - .icon-info_trade_detail:before { - content: "\e62f"; - } - - .icon-info_block_trading:before { - content: "\e630"; - } - - .icon-info_investor:before { - content: "\e631"; - } - - .icon-info_research:before { - content: "\e632"; - } - - .icon-info_announcement:before { - content: "\e633"; - } - - .icon-info_quarter_announcement:before { - content: "\e634"; - } - - .icon-info_num_11:before { - content: "\e635"; - } - - .icon-info_num_10:before { - content: "\e636"; - } - - .icon-info_num_12:before { - content: "\e637"; - } - - .icon-info_num_13:before { - content: "\e638"; - } - - .icon-info_num_14:before { - content: "\e639"; - } - - .icon-info_num_15:before { - content: "\e63a"; - } - - .icon-info_num_1:before { - content: "\e63b"; - } - - .icon-info_num_16:before { - content: "\e63c"; - } - - .icon-info_num_3:before { - content: "\e63d"; - } - - .icon-info_num_17:before { - content: "\e63e"; - } - - .icon-info_num_4:before { - content: "\e63f"; - } - - .icon-info_num_2:before { - content: "\e640"; - } - - .icon-info_num_6:before { - content: "\e641"; - } - - .icon-info_num_18:before { - content: "\e642"; - } - - .icon-info_num_20:before { - content: "\e643"; - } - - .icon-info_num_19:before { - content: "\e644"; - } - - .icon-info_num_5:before { - content: "\e645"; - } - - .icon-info_num_9:before { - content: "\e646"; - } - - .icon-info_num_7:before { - content: "\e647"; - } - - .icon-info_num_8:before { - content: "\e648"; - } - - .icon-info_num_more:before { - content: "\e649"; - } - - .icon-bianji:before { - content: "\e623"; - } - - .icon-info_investor_hscreen:before { - content: "\e684"; - } - - .icon-info_announcement-copy:before { - content: "\e685"; - } - - .icon-info_quarter_announcement-copy:before { - content: "\e686"; - } - - .icon-info_pforecast_hscreen:before { - content: "\e687"; - } - - .icon-info_research_hscreen:before { - content: "\e688"; - } - - .icon-info_block_trading_hscreen:before { - content: "\e689"; - } - - .icon-info_trade_detail_hscreen:before { - content: "\e68a"; - } - - .icon-kline_train_buy:before { - content: "\e64a"; - } - - .icon-kline_train_sell:before { - content: "\e64b"; - } - - .icon-drawicon_down-copy:before { - content: "\e68b"; - } - - .icon-drawicon_up2:before { - content: "\e68d"; - } - - .icon-drawicon_down2:before { - content: "\e68e"; - } - - .icon-hk:before { - content: "\e627"; - } - - .icon-shhk:before { - content: "\e628"; - } - - .icon-margin:before { - content: "\e629"; - } - - .icon-sousuo:before { - content: "\e62a"; - } - - .icon-guanbi:before { - content: "\e62b"; - } - - .icon-sub:before { - content: "\e64e"; - } - - .icon-add:before { - content: "\e64f"; - } - - .icon-refresh:before { - content: "\e650"; - } - \ No newline at end of file + src: url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.eot?t=1562863167659'); /* IE9 */ + src: url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.eot?t=1562863167659#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAACcQAAsAAAAAVSQAACbAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCODgqBgljnXAE2AiQDgxwLgVAABCAFhG0HjAobDkZlxhhsHACs2TqyiIpRWfb/H5MbY0gNlp8dZSOFhV0hF9ULEWc0/BmvB1c4YTfqOkM6GAeZQ+8XdkhyjabFip8TFTT/SNCcVk8qUYumqESl/txB5WQNmRhm0vPuXezn+aQie6T1sKGUxANr/Wbv9osZLp4ISTxBapCKNjw+PCRAgG2Oi6f0kjCx4Wmb/whtolTAoI4wAaPh4BALULEKDKypzJ4r3PaNlXOlLqpcGov8LlMX7ebyxyoAEHZBTUXHezS3fd2VPiFks4SftEBi1BEbiQztpIJTFLebX7AmpdDSMJeMo/dN51eI4SiaTXH6y1VsGWE/QH+NzMryDzdVt0vczk7C1O9NJCAo9b7LX3JNd9re+GNOx/A8j0UiQeEtRoPxaP7vm+rPaO3Cnd3AOSKbm8iopGy7QDC7Y0chmVTggJPqZ/d35ldiUxvJIlNbAysMC9/v/L8I4AH+mnrBKf4A6JZF41FpukfiRxuwDMg3/zrNNT8OOQeALvHbmd/ekWf/L0Xxl6yzFZYdUpyCDi2HSGFTmTbCif3tgpWSfRw+vxtbnmADximvU4alNA99HYapy9qxkNPWg/hnFaJZ5sNjbOaBsWj0dQ0qAkahi/qoMAUajZqj2PJ5zxEvpcWtAsUdvn7Ra2+hjKgK9eNaxsdS8TIr9ZXnc8ML//vFH4uKoaKmavHwwLWtV4gBP4B7K2eimurCoAZVzEFJZRlzVSyorrdzVDVO1mVRMg2tV1HJ4aRl/g+wGyj7WIxOhc4bvd53GeL8zjlazdWmXYdOXbr1aNCrUZ9+AwYNGTZi1Jhx88w3YZLJpphqgYWmWWS/pyaFMzq9wehvtsWWWGqZ5VZYaZXV1lhrnfU2kMgUKo3OYLLYHC6Pr1C6K100W6w2u6sW/YNnuhlmOiASS6QyucrPKY0HRa3FfjOUH2F3DYEI6okFc4gVrcSGucSONuJAO3Gig7jQSdzoIh50Ey96iA8NxI9eEkAjCaKPAPSTEAYIjEGCYIigGCYYRgiOUUJgjJAYJxTmERrzCYMJwmIS4TCZ8JhCBEwlIhYQCQuJjGlEwSKiYj+ioY7oaCIGCmLiDBLGWSSCc0gU55EYLiDxvqhhAvpgmAQsJiksIWksJRksI1ksJzmsIHmsJAWsIkWsJiWsIWWsJRWsI1WsJzVsQOrYiDSwCWliM9LCFqSNrUgH25AutiM97ED62IkMsAsZYjcywh5kjL3IBPuQKY4jM5xA5qghC5RkiYvICpeQNS4jG1xBtriK7Brn+nAPqJIDWsgRFXLCdHLGDHLBTHLFAeTWl/XwDn0wfEAfDJ+AI8gLR5E3jiEfnES+aCY/nEL+OI0fYOiqnl6//BaiHj9U/7W/G5nYMMA78lISaEtItqyPK6PcKsxHtCdnNJpgh+wE711G7BYLIiaHywJBr5EDRE1NsQwHtDhPHi/EEOaoCPQ+YmGFOMO9RHNshnSx6Ck2nkVkAo/DztKNolRFd7gKHLE8uLgwtpMsEiyWihb28pxwBltwqgeltM7NBbY2BDs7R6dcQdKCjkUdrYKUea4U2xfmEBquF+KUwmOalGHtCoF54KqECqoYFWFyaMkUV2VjMBApbCVdBSTVXCjLJEKop8mOkG1a5TPuHubQKVLALzlLo2rkG5tuaJ80nEtk75EL5wq+T9jVAS92oIkHLjrGEcG5qWd0JPmGtztC4WzcdWFM9AZjMNQLMOl0Vamp86guCpPPVbgrXQ+sty1MKee8Uv2ozeQ0I+o+HTqReca9U1Hs2h+UhW5SBPiq/Qpbt4i4d+7uJ7ZrTjBM0BVrozP2B5cv+h3VsiE0GkGKKyovmY0Bsv2aCatHWXVaSFDpsDwzX1+brXR0uGh5qVlmc2A2baFDQetHtJl/67F63EjwGELiRBFJI+GVhww31WRyzw5ielz4mOrBPvZ68aipdNZs0q2vX1cZEdc6nHhz4VKL49rNjA2/rMbX2/LrXQ9MN7/aMt/LLfXyq4ncS59p7TN2/bzdMnnumSr0btUaXkLpEhEtScOb2VBjMc+E9Ux2vpfn1CJV65lk0jsJ/IRsWap1Zvyw8kOR3VJTf71D8LcNvHMN6S/nVau2MibwL2wm1svrRDjY+GRGswv7+OU9sBIThhTx+jbSz794RUjx2e1cDqHmlYy7QH0huGnFMgqO7V6adpvqdk3cIErBwY7jnrzqxngX5FKegXTeRwpZr5SZOexRiJiWb/WczwmfNHkT5JyJVt/EFR/GuznAISQAXBFjHB0Zfvzn0chj0dEy7xwu6tsiyGrSM7faUKuWumt0R1hFbOudVC3pW7xbo0W+YwSZVjaqomusJBKoDOxuJIoontZkXnS74iWPkqxgySj3y1g5HCIRjZJ4injFZ5Qj0dtGLr1EFEGOXtbWv6z3r8X+v22qGlczO8PW75TEld08+rQd5IGYG8VJgQjr83jShxPeux5GcMFCGskUNmyGCI5xVgs1yXzYRaQYcCaBK0nEEAaUzNMaUhvjvxnVDrxk6lYPntlhKD+RA2jVMYojeFFvU+CYJjy4D14BJU9k4xVN2r3D9PBFaoKzfTwr00IsFqxrZGNdJ8dK6PM3yvXDIl3DP3ISxlg3jf+oILmGzNMk4trt8zSXz368m7/u5p9eQ3lK5OxA5pqUdrEES6PxLeDtnes94SSjmxrVPtEWLEOSMBNdwQwLJrydedoZ97w+B+XENppeJ/lSHUoVA3xtVq9LjwdobqU+s8HX/LEc92ozkw1ZY34DZsr1+ILTF7G5YNRnpjpYYbkuvS42G7KrbWp+wp/Sh0/EgZpKLWNXfd8558Mr9tS0+Wui7JWSFVHyuGJFutNd5NKLPwKefNgrL91vRMCLeonsFRWj/ItRIQrnTpH8vbzysFkymF5O7X21x++f5d7TialVz6l4OhXbxROZrG8smS/p7pMxne/m8ZpjtJsND3dHhn352F60p4YAHLOhNeC24RDRgza4qT8gogMDJlHyGDwT7TrTG2060x7tOfNGvOZJJAXJGJkHFXfJd57RS6IyVeZF1g8hykgygdGqmIICJiJZRa0E8GKjlxHVPVkGHqt8dHFC1DHPyfpo3RlvtO3M2T0te3+WOadVcO3kDu/TdqaoAfs6tkYv/eb7DuHHw3CUHHGChTwgZQ5DdPn/ag8wUubR+7gv/789fIdzyfv45Wk3f+HZ2dbNn08HTx3b0l/fFm9WjTd2uFrkD41H4oGusS56nPg8EeLzNwr+kVM+SbtZpA/gw7WFTxBCSB52jSgRqZ9mBGs06zgUQmn8e5ffXhyavpzwaHDkaM3BoLf2RBHxLwSP6RO7oCbbhXf/UgO1p/xunyDDo0RSxvDIMJalCERGwCX/CP0kuuvA7mdovyeEPu4NNc8+Th7TakmNjHcOUZ8Yjo2Xln0RX3LSO5pYKk54osmp8oqbtjmPZyS+WmEjN3VoKkHmMd0TudXD+wi8IaM7/0MOkR5xDxt3gbsDWHjIzr/lAdCIsJD771mGVgDc55O8vdcGzR8biB94zh9L+en0eKlnLDSQU6bWftaSxNkZOEPwkWbAuwn7y9kmBUtdDEeLaFcnQePP9k7tB6QDZOrzRGDMjHInTJB+wKIDNvvPY9nrTC4ljfC/yAoCSlyAASl0HnLWGEy6pma6HakBmJzDRG/l/vIiR142EemEiJbs/nzbtH8agGO89lEmFLzTe21HDg7NymS8Du9GRfqyNy+3LWMsh0imvm/uIEGAZQSqguRw0KLXbEGSIz0xt2K2msirE3eldP85Boh5k+5/lglNX0QsD8lIOa5gWULZSLrudvfpSkMEQ5VD22+/dLGvIj1PdZKkuHTgH8gtwRIl0dCxEQQE5U5EwLat5QqV6isRtuilcreJucDzhaAjH5voyMXxoT6LYp0lOf1qn2zjEUSvo0h/L9e7b7mdFDSkTPvNYuBmk9CSbQCkIBPv1Mharm5jpt5Z2wwuiID19aMDWJbaeYKqgGNrblyoNpCBjS7QQvjnYfxXJWJ97i+kL24B755n+raoGjvcX6SCbVIYJIzA8GUXgtXqJfpthnqnqmIb6eNbLxWL7gQZat/TLZzVAu5uIGITiwH/260vvz6nFwP5OaTfB363HKUYMKulS6RhmkHcjphzt/PeVqAVIh7onbNy/QrXi7qKthcz3mclOTbbmN1UoI3MrgF/iI1nFojYpvpEOlezYMzzrcRtKiWq7fbCG1QxQUWzdbwRDMcJGn6Gq99MH9zltFTQQqy0Eh08N4v2kK0ummOmjA3FadVAjXHfC6qezhNRMXb4Grt5tyDM5M5jocOkpmYXsa64643taGWXQnYK41SLCMajxBn/6A8PLCs4RsK+F3RCdYvd3dsWtbtz0U+mL7qudp8DtnbP8oJkpaNSmdeerVwrTSt2FmMpUxUxn55o3QrFwEx9+YXGPr87pV5LHnJM/Up7bZhSxiLRx+Dxnx6l8LHtYMIWNSa8LvsDmw1c6JhG+vtXCNtaIWi9vXUP3ymEXYCJNCDBwCEXkSTgA3xf7n4Tn64Ebc7Uf5rusuhZmy26tx5qMjHR7fDnTDTlLQ8wHFHzgAZ8X6blw3GkE6KFXVfb7WTs7yvMl7Qn34bBBbZ2Ht9wJhe50GGNHMEyHsHmVw+kyj93FTtVKyBond0IVj5pWX4fC+OSsSmAzCir/Qj4Kya+4kj7Xa74rOUdYIgflvA2akjGBAO2y47kAhf7r5ZENaE0tPXZ0/cGFLhW8Fnw1IJ5PqmGuzxRNFQlSMBLYwGr3lH5UY1JPktqJl2aGPeN+8cJkcKo0NG0JkAiEmDqAqm/yyx1i4LlB6wRwbamH+goCboCiH8w5KAtNgBwhOrJv5/yXy2uJmwQMv98Idx1vvtGNTo6TBDBLYnl9blTPorA8gVkcS2QoyCpiAhfof8sbU8AoB0XbJRX4NeKBBmJjLKJbSKqOJT8gd3ZwcYlhwjrKfqUgwPPT13HrRv/IP28CdwOjZREMNKtpU5am+ncxahGK08QvYvFkF7y7E4+faGHLDjXiiSzZdjFi27dE911+f6nOCEevL979VFL7eTDw03ISoUtIdFdS+wUq0fn1J31D171bqp9e/fuxwVQxQ/WiNrjXxElLn12Scs05zsExpqQJKI9Y2ICkMgM1j9W15g6UCkwEx90bf+kIHmAPE/STSTbQlKNrVkS7yg0DGtJCtJfzIGmLusQeQLgmMbjXBpJ374PLfooU2+idm1hYaCzoHvns9qjwIZdGtykZqNaRoTzpRo/WdfnT/vEHoWwvrYaarZh+6c5f2Z9VfPzpzEN4K5k//rZUynw0h9MwZoWVOpSCKuAfWGni+55ObRHZelyAbsmOs5QXBcGG5YU9unYg6vLPVASL+lFt5wovzIKHsRE70iMwChiwqj4RDwyEteLvK2w0U4ni1LafWJL2Yrw0ODDtJWXeZ8Z32mWpqodSn4bITGewDhRhk9eFD5sJEWcLW0FGFeRx+TETEv6FE0UHnX81KQxtv/rf5rCKgOppqq8ppCOYs/g5rkGSRYR5t7Icq3IAwkgzlCaSSqrNOp1lGHW1DgdY0/iRumPaBcjO60QHD45X6vRaudvmA68ETjxGgw7jl+NaBexIwxf27DLukLwgR+mDYZxK7HVk8SRf+knJ1qN79h0mw0M42N1mUgk8mspycHGf21S5mxaW2zTjm+3eTIbyCbf5jDusCFBuheAKy4+XoVTgbS0AMcOXIBGExdLVjmqUlLZ/D304EB9La+UsqnGJ6WCpCFoApq2/UYPHarMjcSeR6iGsIHx3NPeHeZ/5kXT0ykwYJkPqU8NxR7PbpR6m1q9i6UkrQ++ZMMCN9SX940v0bPsI8LhNwgJcbS/h+ZGtRnTyEGN6AiCuxD7pz7jUwU+YtvCPS5HdR5zdbiMXWNEnPUDVBLrfz1qM0A83qvP2xmA5yuqbcazOlWD0qZeWa/aImgDB2PrVfXjGpR1v67bqrdZZ6f0wb7y4KtST/6SMI1TLfdptJc2vj61vHiLSmxdlmqryHFRyzSekF9caDazlF0B8xfd25JZCKSbiDyV9S8Pwn4f5zcHI6Ep3SALpL7ZvCgsJp0ftvj9oVWB42nGFTIQnHTvQ/C38qbz1xfY2k9ftnHdXc5Pp+IlHI21/CFjOzlcJgHg7lT0oNwe0HqJk9lmMEL/nwjqPHj5ItKBkfeDchp4LDvRf8LfgEFDH2QyqT9HLqP4p/lLr10rdPAP8ncounad7V/szwV/Xn2XTaGPQk2XxV2xILR0FBBM+KazqcrCJ0YYOtczBiFM6JxZZn81hYj70qHW43kEJYF7VT/CJSqJPD+E+IvIepduU1uNzVcYFxgWKDBTFi+pcRhBCHjMA5UeH0BEiAF4PYGHwvsixB9E4LAeZqkQDFqlYimECo1RIdIL3A9qkMqHxMihNoKIWQhCISMq6UXxY/XjaLJ493W2CuE0swShgMwaix5T46f6xLesL4nWTjZ2z1hRUyG9pBbrgmXPmAEl3KS5lXj9FSdM5aYJE306wUZFC9TSQmGO4yF8C8uTYOQbzLYOjHFfvt9aB1vNzunQ9BYW8yMRIrZQblHdww4JzgXDuSacExwKL1osOBgeeVh8NkSRi1J20r5F0ELBBbYb7NYBkAic5yFBXwicG4Q+wSGvi264EMXZJCMiwnMaLVw5dhsEA6zKcbTfLNgSBGen8Qmw2d64WHAmXhZ/ZvLCFPkhR5xyWCcoVg2zYKLNRtuJgrxWXytYC97NpjksizWSDbMRhExBEJYYQTBoBPG/wGrEs9g1UFdp9JcZ+NDWPb+3u/NUhuD+C4rWUi1buXTZqp63gHTnGnSthAgVtS4uhyuvWSdBEM1BAQbOgjNAFx5FL42cnYqLrXot1R/Q/mkVOPmTXov0OrsB2014Vrex+PckqVm1sjufK/f/kWWXz84ePvtg1fRnTPQHrmvCUfs9MYN6zd8by/3AcmYcuymQsEZY72OWJcjRXf8fs51RdGzVg6Nvz53LkmfnXSX5hwWk6yRn2ujwcatVVsdhetscyaGFS5mzdPTmroPd0raDFZXMTX/pGD1dhyTNPXE2d3DRUsashGpn2qXtZ7qa6UdAxtJFByVuB4vQra3oNhVdEFRbpzJDbKy19c0b/BDAOPUqydHoSGJ6BcNgcG9lcUYc6bPHGtg21aKwpNrCa/AkVxJeARpVcjwbp8CjcHDLmpGhEG7UlEdxHNwQ4Ub2fraN2KaC4D1Wju0vnh+3uFx8/sLEMr75aP/GKEl98aLNTHKe9Px5O7hwWR+5/fc03CK9uOpsb89y6nFU2Nv3em7bseXLlylBzjktpI0iYGusqZYLIQpd0uy0jCixu2dQgVxZvUrKmZqk4JQCLAaGLJAskJvUG0jRVwa1dH8y3kA1vbaUQC8shSx8C8hWo+g4exI6eQ4irsNwgiMxythwpzXOoTxPfAg37on3Pmf3/FgJusmJiaACZXQYtMc5hBvqJ+SFSdjAR0cKHEh2jTZ2BH8cA3mzhhi9Dx9teYVlUKQka9s2WxJQe1VWPaqqtIiT6InxX2zGMdIXCp/0jBJkdrAcqANtMpKHHyOF9tRuGRS7RNjw1ffsZ9HZxSLzj9iAbX6PaItp4q78TPxRc94HGm7inwh0QiQdzqoiF955L+coZ5V4ToE7dKeJAxxmyloiVwib8JlXlTiFtaLcz0bNbryZTp4qljBXUJtsskoUNkqMQo6JIja9Tf887TJPX1bOXCWG7NKhq4CqGMy1/Mx3XcwjQw+nKByEBhsnnYJOcTzR6F5HA7YHIQMPMSI8A6Q0lu/rUaKWYUhKWuPUqVunTRV8mTx5K5oe+ABjgNKg5xl5yYay/W2hmIjkKFGAIZAGhRlAeD1mUbu7e7t7pNKenmU93Uf+wuG24nGlQYsW9XozgLKNTOrdzOwdtdbWdchbziscH08F2/Itk84LVOWw7O8W2PIdvJgyMNA7MAj6M2h/vyfLBaMiOAPwtxfVKBdEVOS7nHZooREyuvJSoBSwo7IJamom1ebNsoasE7dBJdTz1hLYCpn/qEhZueqIx8Zc5VlGrIxWfrdIfuKkYMVp8+l43k2S8vTET0HgTQvUErgGPYM/Y6rFAlnEBLwDx8G0sGDt7K21D2krJD+uLg0Ypr2fiN4rdvIeAXHNn7FzpeL9taUPoeEA/d/rO8UK6OGWWvDJqtSl7O9faU7DDivsH1OjABdSUx8tWLFmmJb29+8ylzJw5DCGqBwI9OsMIe5J9MaKHcOrpV6egXZsdI9oVK8PC/PJ0sIgWh4M1PnxOa94+491Ht13XY11X3ruaK4Db7k5aPmUkJE3/iwifmB0gOCxZ/xX8MiWSBuiDx9M/4MSo8A9IAZrAv2f9XC03euCVBIRu154V5hq4haWCeaEVd5YF/ZZCUfyYk+5saDnuaKabLHIK1VFyIyIDXmhDk8I3fO2wId/2SRqTcqr6zLidLOE0cLFRN0cV8+vp796pjGMxF5SczaPye1mMjReU2q0N4oqo6AqF5Vd01bv7VyZNJKn8x49n6EOzZgTU1mTwvH3VvuXaWM62uZW/tGEkpIdx+I2bLg4MHEmtk7x0PmvKDIuQRvxYkwXGrPI2/P/bgTWzi8YJHLnoQmEL9veDwDr55W+yG7EV209TTSNsutjokyj9NfFSxouGgU5EnlqZ3+/CTshyzonFYgDhNEU3+CoQpQ6k9O9JfEpZa3SbVq6qPlA1FPMVhkvS4c6sCd06pZxH5fJzbt1fjpthk6smw0n6Yid4NihJVzWbrmobPQ2XFf8Nf981CD3/das9OcfdfFz6IXDcDjHQks7xXBzX/lzpTEwCUoK9gxOgBICDdC7XXsWtTOEbe2GOIPsITOvx1Iqm3ddu7bZ9NQQoK8ISd9hzzxh22CX9NLSm6LU6rpp0c2J5Q2YJdYok4N2dfCS7vSPEasmqHmuGGqPN0/VCDVmH7NKqKpm2LsChNYnMxuIZgqJ7rZS63JTKfd0w6oT2ePzXvC9OGTb5xtpQqYJVofF0emxnIhstXDBC4RnG6ZwLuNCPhTecnJy8xwgXjfnI6qotbUYVYRqbXXHFbe2wm2YxR+4jy+1feMMH2pxfuOqucfarDiP/HWK/3mNFfhrLB7ObP2Qp1TT4iGqPMlNUOPEuLl48XN60W1VHZHmtwz8D/Zxx/CCb3duOQofSh4xpcL/9L/YpKvYhP/IGXMl/HLIuMbLvUBzIUk+uNg/k1k5B7lQe0RHhJD+DNFQo+RHhvx1gMnXe0IOCDyJY3+qmOF8yVU1mWXpczvMZ/FVnEJLxvRE3c0cVobdp9GhSDKTtHvyV0bXfE4NPr7Flc9NqFjnJ8h6/xS0ZRP/afpTtKnZ0jP6OeugJqvaH9OI53/42J+UUrkYEaOyieFVHZd8c40Pe2PHcvLIHoLTl4hPfihlwrwNNaen0qfS7Z5GxvO3tzUEKjjLcS4EwhQoeXe76j7rOX9/jCZ7cg67bg/Mv75exGW75PllrDTKWX2KmsJqaeQjEMUpyoy92k8Cfb17y0H0EDyy5wqU8pMDMP5mmhoInY00PaaRDjv4eO1TNpFeyOzKOwiOTX6+wIezcfYy8vha69IYFaNKGNvWaekamseFuIse1Ij0LRsZkDhFzGeesVYQ3g4Q6X/uSAkO5bQeUTu/V9ijrk0a7/6bS+zDuLCCZ+duvhNeEg8zpMGvE9+zSE++6O6RM7aUS7Xn2WZJBUN20kiLfsr+uwRejJ+Lk9yg5/Jna+ZtcnAdhTjtn14nmzX+NC46lcd3fdRQ4QyPwhtmr3b/7Etzd0WJRyeO+RuUoR06jkTYNRnD7JrHnojXGFM5iRVr/bVPltm1I2P91H/1C1SfJGlcAfNhY0X1qGJxxyr3Lz58d6ZJtGIfZu4IyB9dz+BxetL+TV8lDqVEa2SVj8SBSx5UTXT3QSZPkiKBXA/YwIQH/SRr88C+nLrF3OvvVilPiZW7nJptBfEhsrsaBoflTzLS38JjTg6zouvg7YFVavbdjVRi9kuLK+fORnjNZ+c6Py0rNzePtXLNLnNwkHNQsEtwsLM3A571VVeb1hC1YztJQ46LI8dSt+8AIRiAxagr4LqvF/151ARGSU6q/N8fD0wTsBtzrIEqDphRJ/ENTglSozK7OYlbfCWKtdPd0ptFUQd8xbKtWTwdMd5haujdb+7uZp0YsFqrVclDdk9eqWWezGet1tTsG2Co0KeHXFyz1/aEXQOtyrY3Sqvs1iU1R5cnYhqslxBNWof/lgSnd/8+NWGVpMvXGo713aFS1q5JoSER2FijbCRkF9dVLlrlTfm6a2qsxhHu5qWyLdGamGp4PT2uixN76qBQbZfHQyyKsDJn45bzyMuTKZsPp+Tq1b6CS46NfEwKZUqVqsv45xfdjvQ0ZioXh7uPOygS9+JTRFZIbF64OjTBYZdPQcGYqKSUltdVZ9ThjNE6YqtZ1EPoC2qOVWRKnxACVNbBaQnf5qZwB7W19Czd73jddNuk4oh9W/lT9za1va1V1Rqif28kxEVo8x6H6hbFeD0pNVACheY13xFlzbr8AxjeBtbqqaKpuyi/ZYlKDaJpzegvYTnq5jH5TDsNY4qXtiZSHVVZBalcmuwe64A0XhlInZERuqUqJqWGI9WO0EtuzeppOn87PO7DhriLG344h8DRQCJNoVDX83X9s6fP6IK14leZkxhuj5fHFXBdZ17+otCC2UuSkNwgvz3KRn60ZG+Y39pKjfc+chmN4uIQAszrnz17uo5CI9P69ibYlByABGYnAkZ90xsmbIbFHpCC6avRKJwTMXlMtey8+9GfDcx5X/jcCVGugRq9Giwiffg4WirTF9lPYhZf78amTx0EYtp4+3gqaraicxfUD979vZK70reh+WPCVconBOLxk4CE/Nsd9Se5E/6g+yf/wT9/Kzl/+Xzp89JTl0+VAPHn3yxXOTzuPg7DkU8jk+a3OwbVFec+B9FyDft2hOhb/yjH5qFyNhEDYVSsWKgsDKXFtETPxLkbt0WD7EXXWAymQ0pefJ4+PyGpUSl6nqFIHtPz9TMJ8fqzvlTcVH0KPyU5xy0LJOjf7uPyLFBqQP6shGFzflhUWGYmoz9gRRe6fFHIr3GmjC8wm8WYNZt/KWWCMUXjejZeIZeVCoOn/ej5sT+7klVZX5BVFl+W5ZZVOfrp4SpGhSNiCUg32DUR7ZKU/rUsXlhoGauL1bGgy6MLyIDrtm2O0k5dDrLeYlmP9HkuDM+cXW6F5ZucndApvbJ12y/BI4Ek8epiYsZUpcW/g1NuA04wMcGfRgvr6oq9tYwD3XRcDVd4bBCLQmEZN4hCpYN1+cmqXkItJZmoDSdPc3sbqCaSiVZycogRAoR2bZQSVSwV0UO7mXV1VqtvgcHLSTGd8mSwDnP3LqZN6y4jNSrB7gpJZt/Vm4/1qk1k4G0+fwqLOxpecK5uMjiB+fkT2489AeEEthBs1UYikxhxIj8P6qbrkzvoHHpPcfF2923Fpm4623Y26PyJvX62LZveZjJtc99uKm5ncOgdoD+VlY3eg80dN41UQlK7yZQBO18CFleAoxK3E6l+MZYgsSeyY/YSqHLk3Gy7YXJ6SqbZcpxy3GJ+renkr5OpyZJGS+vLmcD0P4vU32ns0fkHEw1AyUVfReQBHRgFALvLLYzQuHKn75hGf96gA5jYeX32YeAjDc0IRp5l+v8bHHToyyh+EIpwQyotg2jSAEbGB0YxgFTI12zH+IG930neK/1vBYYteiNlO/q8ypKyDTM+QiPQLy1QlhC2VIbQ/boYVDRO4esG8HFVDA+3CuyDqP+xGI5eDEve0qAf7XNL/z25LIkYJ17Oq+noKl7pNDom2T/KmvdoyfnOoFthczWr0Q3X839mYFBwvCv/YSZf+t8wjSIq6ATRV+tU9BEA9rcWDIAl3SiYsr44gYox8xZdTahFLxGz0bNgyU8z0b9xYotuxrxOHzHVS9r9i2niLRhAbdI9L9cdgJd8m+sYexz/sEKZgt76r9r3p1z4+pWFb+Dhrx4IAAB+vLZncPw/qZoFRvY/HzP8Y5bmdKMps8h6p/FfTyQEIIB3KJcgZwDcsgjgH4pK3/XJ17mRh80ebRsyWt8gGLMUkrgzSN7NoBjPBmdr+0N7lbsgwdICwMZjw4ByrwyZ6Nsg5N4ASvxmkBr+GZS8EAbnFasBeItiIq8oCjL4opoU7KLUUWwlqPwLTQ6kc8af+w+a+MTi9urmcPkXCFSFRho2d2Z1UWvsis/GmiGEWPQaB3B21Zr1b9fXNasbVy52UyuKggy+qCbejtlFqS/cVo5e/F9ociCNaHGy43/QxDe/uL264QBfOOFqsSg107C5MyTXRW2LsVvzn7GIsFwSi54dagBnV62A3L9dI281L3eVPd9dTjidr9UF4TrsRSrtpcdhrN+g/dNvx/V8GEExnCApmmE5XhAlWVE13TDDkWgsnkim0plsLl8olsqVaq3eaLbaJDKFSqMzmCw2h8vjC4QisUQqkyuUKrVGq9MbjCazxWqzO5xh6DavNOpBgy99DIF0hVTjqAyobT0OoYEmJYvHeCtWkw4pUYOVA7e0GVOtX6mJ0a9RCeS3OkguSQ9vvFRuWtvEKDXLKmdR7jcm9+hCTFhzLUmDfMQvQZFMt7qbV/ZEZrdMKQ0sWNdUmqRlhTNkD9g9RrEcISDYhLSYYMbSrJp1Jy6grFjmM6JSLi5NAeLidqbKJgYPScpKOcraYXkSqUk2JYeAOohRg/VZvRENUZH4eOdTpGJd1TC2vcKgsp0kCKtC99aNll3LfenJVNlNuRwJ21dUdhAQHWsJaL4JadLpVtgWzGuyKqCmHEzDS30cyeqGag3z0jgr95URPzL5SAVdGyFqrqKQczzPyc7py2V2zDSfWmYjzQ+YXF5ILf63vPTB0owZPzdY6lj2dVQ4Sra9azJCeJQeRhx25kuqEN07C4pw64dOLEMkg96rp0ggdW3i0CQSszh0EDs2YDGvqAZl6lZvVHJX3t5ud36z87ud3+/8YW+PoJ7t7KmZkNszuD2M3O5G7k8x3V6Qx12e3F7H6ozVDHUGY17WX3AXFQsVkwx4v/lue9kmp4AcNNytduliP7kYUWFeDvTHSPLcbxWG4eNElwzd+3HLMyOXzffAAnRTLGWVJ1v7V04IYecSlTmSArmvXSnOeLcR5Xw3077PpbY38kJH2rAspJhTjgtNJql4NuVqlrxfVNSK1C60MVvmxY9aqyVzGLNNAQ==') format('woff2'), + url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.woff?t=1562863167659') format('woff'), + url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.ttf?t=1562863167659') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.svg?t=1562863167659#iconfont') format('svg'); /* iOS 4.1- */ +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-drawicon_dollar:before { + content: "\e626"; +} + +.icon-arrow_left:before { + content: "\e680"; +} + +.icon-overlay_index:before { + content: "\e655"; +} + +.icon-drawicon_message:before { + content: "\e64d"; +} + +.icon-drawicon_s:before { + content: "\e64c"; +} + +.icon-drawicon_b:before { + content: "\e70f"; +} + +.icon-drawicon_good:before { + content: "\e624"; +} + +.icon-drawicon_bad:before { + content: "\e600"; +} + +.icon-menu_arraw_right:before { + content: "\e60b"; +} + +.icon-menu_arraw_left:before { + content: "\e60d"; +} + +.icon-drawicon_up:before { + content: "\e625"; +} + +.icon-drawicon_close:before { + content: "\e68c"; +} + +.icon-change_index:before { + content: "\e656"; +} + +.icon-draw_arc:before { + content: "\e602"; +} + +.icon-index_param:before { + content: "\e604"; +} + +.icon-draw_line:before { + content: "\e605"; +} + +.icon-draw_rays:before { + content: "\e606"; +} + +.icon-rectangle:before { + content: "\e607"; +} + +.icon-draw_parallel_lines:before { + content: "\e608"; +} + +.icon-setting:before { + content: "\e609"; +} + +.icon-recycle_bin:before { + content: "\e60a"; +} + +.icon-close:before { + content: "\e60c"; +} + +.icon-draw_trendline:before { + content: "\e60e"; +} + +.icon-draw_goldensection:before { + content: "\e60f"; +} + +.icon-draw_gannfan:before { + content: "\e610"; +} + +.icon-draw_percentage:before { + content: "\e611"; +} + +.icon-draw_waveband:before { + content: "\e612"; +} + +.icon-draw_resline:before { + content: "\e613"; +} + +.icon-draw_text:before { + content: "\e614"; +} + +.icon-draw_parallelchannel:before { + content: "\e615"; +} + +.icon-draw_wavemw:before { + content: "\e616"; +} + +.icon-chip_date:before { + content: "\e617"; +} + +.icon-draw_triangle:before { + content: "\e61a"; +} + +.icon-draw_pricechannel:before { + content: "\e61b"; +} + +.icon-draw_circle:before { + content: "\e61c"; +} + +.icon-draw_symangle:before { + content: "\e61d"; +} + +.icon-draw_hline:before { + content: "\e61e"; +} + +.icon-chip_default:before { + content: "\e621"; +} + +.icon-arrow_down:before { + content: "\e681"; +} + +.icon-arrow_right:before { + content: "\e682"; +} + +.icon-arrow_up:before { + content: "\e683"; +} + +.icon-draw_quadrangle:before { + content: "\e62c"; +} + +.icon-draw_fibonacci:before { + content: "\e62d"; +} + +.icon-right:before { + content: "\e601"; +} + +.icon-left:before { + content: "\e603"; +} + +.icon-xia:before { + content: "\e618"; +} + +.icon-shang:before { + content: "\e619"; +} + +.icon-jiacu:before { + content: "\e61f"; +} + +.icon-shezhi:before { + content: "\e620"; +} + +.icon-qingxieL:before { + content: "\e622"; +} + +.icon-info_pforecast:before { + content: "\e62e"; +} + +.icon-info_trade_detail:before { + content: "\e62f"; +} + +.icon-info_block_trading:before { + content: "\e630"; +} + +.icon-info_investor:before { + content: "\e631"; +} + +.icon-info_research:before { + content: "\e632"; +} + +.icon-info_announcement:before { + content: "\e633"; +} + +.icon-info_quarter_announcement:before { + content: "\e634"; +} + +.icon-info_num_11:before { + content: "\e635"; +} + +.icon-info_num_10:before { + content: "\e636"; +} + +.icon-info_num_12:before { + content: "\e637"; +} + +.icon-info_num_13:before { + content: "\e638"; +} + +.icon-info_num_14:before { + content: "\e639"; +} + +.icon-info_num_15:before { + content: "\e63a"; +} + +.icon-info_num_1:before { + content: "\e63b"; +} + +.icon-info_num_16:before { + content: "\e63c"; +} + +.icon-info_num_3:before { + content: "\e63d"; +} + +.icon-info_num_17:before { + content: "\e63e"; +} + +.icon-info_num_4:before { + content: "\e63f"; +} + +.icon-info_num_2:before { + content: "\e640"; +} + +.icon-info_num_6:before { + content: "\e641"; +} + +.icon-info_num_18:before { + content: "\e642"; +} + +.icon-info_num_20:before { + content: "\e643"; +} + +.icon-info_num_19:before { + content: "\e644"; +} + +.icon-info_num_5:before { + content: "\e645"; +} + +.icon-info_num_9:before { + content: "\e646"; +} + +.icon-info_num_7:before { + content: "\e647"; +} + +.icon-info_num_8:before { + content: "\e648"; +} + +.icon-info_num_more:before { + content: "\e649"; +} + +.icon-bianji:before { + content: "\e623"; +} + +.icon-info_investor_hscreen:before { + content: "\e684"; +} + +.icon-info_announcement-copy:before { + content: "\e685"; +} + +.icon-info_quarter_announcement-copy:before { + content: "\e686"; +} + +.icon-info_pforecast_hscreen:before { + content: "\e687"; +} + +.icon-info_research_hscreen:before { + content: "\e688"; +} + +.icon-info_block_trading_hscreen:before { + content: "\e689"; +} + +.icon-info_trade_detail_hscreen:before { + content: "\e68a"; +} + +.icon-kline_train_buy:before { + content: "\e64a"; +} + +.icon-kline_train_sell:before { + content: "\e64b"; +} + +.icon-drawicon_down-copy:before { + content: "\e68b"; +} + +.icon-drawicon_up2:before { + content: "\e68d"; +} + +.icon-drawicon_down2:before { + content: "\e68e"; +} + +.icon-hk:before { + content: "\e627"; +} + +.icon-shhk:before { + content: "\e628"; +} + +.icon-margin:before { + content: "\e629"; +} + +.icon-sousuo:before { + content: "\e62a"; +} + +.icon-guanbi:before { + content: "\e62b"; +} + +.icon-sub:before { + content: "\e64e"; +} + +.icon-add:before { + content: "\e64f"; +} + +.icon-refresh:before { + content: "\e650"; +} + +.icon-houtui:before { + content: "\e651"; +} + +.icon-qianjin:before { + content: "\e652"; +} + +.icon-exit:before { + content: "\e653"; +} + diff --git a/vuehqchart/src/jscommon/umychart.vue/umychart.vue.js b/vuehqchart/src/jscommon/umychart.vue/umychart.vue.js index 6d485725aaf363e4c4bb684f063e1db63cf9f4b1..a70c97d16f4495aa9334c785831b76c259bd4232 100644 --- a/vuehqchart/src/jscommon/umychart.vue/umychart.vue.js +++ b/vuehqchart/src/jscommon/umychart.vue/umychart.vue.js @@ -43,7 +43,7 @@ function JSIndexScript() ['DMI', this.DMI],['CR', this.CR],['PSY', this.PSY], ['CCI', this.CCI],['DMA', this.DMA],['TRIX', this.TRIX], ['VR', this.VR],['EMV', this.EMV],['ROC', this.ROC], - ['MTM', this.MIM],['FSL', this.FSL],['CYR', this.CYR], + ['MTM', this.MTM],['FSL', this.FSL],['CYR', this.CYR], ['MASS', this.MASS],['WAD', this.WAD],['CHO', this.CHO], ['ADTM', this.ADTM],['HSL', this.HSL],['BIAS36', this.BIAS36], ['BIAS_QL', this.BIAS_QL],['DPO', this.DPO],['OSC', this.OSC], @@ -3471,9 +3471,19 @@ function JSChart(divElement) if (item.Modify!=null) chart.Frame.SubFrame[i].Frame.ModifyIndex=item.Modify; if (item.Change!=null) chart.Frame.SubFrame[i].Frame.ChangeIndex=item.Change; if (item.Close!=null) chart.Frame.SubFrame[i].Frame.CloseIndex=item.Close; + if (item.Overlay!=null) chart.Frame.SubFrame[i].Frame.OverlayIndex=item.Overlay; if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight=item.TitleHeight; } + + //叠加指标 + for (var i in option.OverlayIndex) + { + var item=option.OverlayIndex[i]; + if (item.Windows>=chart.Frame.SubFrame.length) continue; + chart.CreateOverlayWindowsIndex(item.Windows,item.Index); + } + this.AdjustTitleHeight(chart); return chart; @@ -4238,6 +4248,7 @@ var JSCHART_EVENT_ID= RECV_TRAIN_MOVE_STEP:4, //接收K线训练,移动一次K线 CHART_STATUS:5, //每次Draw() 以后会调用 BARRAGE_PLAY_END:6, //单个弹幕播放完成 + RECV_OVERLAY_INDEX_DATA:7,//接收叠加指标数据 } var JSCHART_OPERATOR_ID= @@ -4326,13 +4337,22 @@ function JSChartContainer(uielement) this.mapEvent.delete(eventid); } + this.GetEventCallback=function(id) //获取事件回调 + { + if (!this.mapEvent.has(id)) return null; + var item=this.mapEvent.get(id); + return item; + } + //接收指标数据 this.GetIndexEvent=function() { - if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_INDEX_DATA)) return null; + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_INDEX_DATA); + } - var item=this.mapEvent.get(JSCHART_EVENT_ID.RECV_INDEX_DATA); - return item; + this.GetOverlayIndexEvent=function() + { + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_OVERLAY_INDEX_DATA); } uielement.onmousemove=function(e) @@ -4829,6 +4849,8 @@ function JSChartContainer(uielement) item.Draw(); } + this.Frame.DrawOveraly(); //画叠加指标 + //固定扩展图形 for(var i in this.ExtendChartPaint) { @@ -5415,6 +5437,17 @@ function JSChartContainer(uielement) } item.Frame.XYSplit=true; } + + //更新子坐标 + for(var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + overlayItem.UpdateFrameMaxMin(); + } + } } this.DataMoveLeft=function() @@ -5469,6 +5502,23 @@ function JSChartContainer(uielement) if (!item.Data) continue; item.Data.DataOffset=data.DataOffset; } + + //叠加指标当前显示的数据偏移 + for (var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + for(var k in overlayItem.ChartPaint) + { + var item=overlayItem.ChartPaint[k]; + if (!item.Data) continue; + item.Data.DataOffset=data.DataOffset; + } + } + } + } this.DataMove=function(step,isLeft) @@ -5610,7 +5660,7 @@ function JSChartContainer(uielement) if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存 console.log('[JSChartContainer::SaveToImage]', this.UIElement); - clrBG='rgb(255,255,255)'; + var clrBG='rgb(255,255,255)'; if (colorGB) clrBG=colorGB; this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height); this.Canvas.fillStyle=clrBG; @@ -6642,6 +6692,7 @@ function KLineFrame() this.ModifyIndex=true; //是否显示'改参数'菜单 this.ChangeIndex=true; //是否显示'换指标'菜单 this.CloseIndex=true; //是否显示'关闭指标窗口'菜单 + this.OverlayIndex=false; //是否显示叠加指标 this.ModifyIndexEvent; //改参数 点击事件 this.ChangeIndexEvent; //换指标 点击事件 @@ -6659,7 +6710,7 @@ function KLineFrame() this.ChartBorder.UIElement.parentNode.appendChild(divToolbar); } - if (!this.ModifyIndex && !this.ChangeIndex) + if (!this.ModifyIndex && !this.ChangeIndex && !this.OverlayIndex) { divToolbar.style.display='none'; return; @@ -6676,7 +6727,8 @@ function KLineFrame() var left=chartWidth-(this.ChartBorder.Right/pixelTatio)-toolbarWidth; var top=this.ChartBorder.GetTop()/pixelTatio; var spanIcon = "  " + - ""; + "  " + + ""; if (this.Identify!==0 && this.CloseIndex) //第1个窗口不能关闭 { @@ -6705,13 +6757,32 @@ function KLineFrame() },this.ModifyIndexEvent); if (!this.ChangeIndex) //隐藏'换指标' + { $("#"+divToolbar.id+" .index_change").hide(); + } else if (typeof(this.ChangeIndexEvent)=='function') + { $("#"+divToolbar.id+" .index_change").click( { Chart:this.ChartBorder.UIElement.JSChartContainer, - Identify:this.Identify + Identify:this.Identify, + IsOverlay:false },this.ChangeIndexEvent); + } + + if (!this.OverlayIndex) + { + $("#"+divToolbar.id+" .index_overlay").hide(); + } + else + { + $("#"+divToolbar.id+" .index_overlay").click( + { + Chart:this.ChartBorder.UIElement.JSChartContainer, + Identify:this.Identify, + IsOverlay:true + },this.ChangeIndexEvent); + } $("#"+divToolbar.id+" .index_close").click( { @@ -6950,6 +7021,93 @@ function KLineFrame() } } +function OverlayKLineFrame() +{ + this.newMethod=KLineFrame; //派生 + this.newMethod(); + delete this.newMethod; + + this.MainFrame=null; //主框架 + this.RightOffset=50; + this.PenBorder=g_JSChartResource.OverlayFrameBolderPen; //'rgb(0,0,0)' + + this.Draw=function() + { + this.SplitXYCoordinate(); + + this.DrawVertical(); + this.DrawHorizontal(); + + this.SizeChange=false; + this.XYSplit=false; + } + + //分割x,y轴坐标信息 + this.SplitXYCoordinate=function() + { + if (this.XYSplit==false) return; + if (this.YSplitOperator!=null) this.YSplitOperator.Operator(); + // if (this.XSplitOperator!=null) this.XSplitOperator.Operator(); 子坐标和主坐标X轴一致 所以不用计算 + } + + //画Y轴 + this.DrawHorizontal=function() + { + var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom = this.ChartBorder.GetBottom(); + var top = this.ChartBorder.GetTopTitle(); + var borderRight=this.ChartBorder.Right; + right+=this.RightOffset; + + var yPrev=null; //上一个坐标y的值 + for(var i=this.HorizontalInfo.length-1; i>=0; --i) //从上往下画分割线 + { + var item=this.HorizontalInfo[i]; + var y=this.GetYFromData(item.Value); + if (y!=null && Math.abs(y-yPrev)= bottom - 2) this.Canvas.textBaseline = 'bottom'; + else if (y <= top + 2) this.Canvas.textBaseline = 'top'; + else this.Canvas.textBaseline = "middle"; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(right-5,ToFixedPoint(y)); + this.Canvas.lineTo(right,ToFixedPoint(y)); + this.Canvas.stroke(); + + //坐标信息 右边 间距小于10 不画坐标 + if (item.Message[1]!=null && borderRight>10) + { + if (item.Font!=null) this.Canvas.font=item.Font; + + this.Canvas.fillStyle=item.TextColor; + this.Canvas.textAlign="left"; + this.Canvas.fillText(item.Message[1],right+2,y); + } + + yPrev=y; + } + } + + //画X轴 + this.DrawVertical=function() + { + var top=this.ChartBorder.GetTopEx(); + //var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom=this.ChartBorder.GetBottomEx(); + right+=this.RightOffset; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(ToFixedPoint(right),ToFixedPoint(top)); + this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(bottom)); + this.Canvas.stroke(); + } +} + //K线横屏框架 function KLineHScreenFrame() { @@ -7231,6 +7389,36 @@ function SubFrameItem() { this.Frame; this.Height; + this.OverlayIndex=[]; //叠加指标 + this.Interval=50; //子坐标间间距 +} + +function OverlayIndexItem() +{ + this.Frame; + this.ChartPaint=[]; + this.Identify=Guid(); + this.Scprit; //脚本 + + this.UpdateFrameMaxMin=function() //调整坐标最大 最小值 + { + var value={Max:null, Min:null} + for(var i in this.ChartPaint) + { + var paint=this.ChartPaint[i]; + var range=paint.GetMaxMin(); + + if (value.Max==null || value.Maxrange.Min) value.Min=range.Min + } + + if (value.Max!=null && value.Min!=null) + { + this.Frame.HorizontalMax=value.Max; + this.Frame.HorizontalMin=value.Min; + this.Frame.XYSplit=true; + } + } } //行情框架 @@ -7279,10 +7467,41 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.Draw(); + + var rightOffset=item.Interval; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + //把主坐标部分设置给子坐标下来 + overlayItem.Frame.DataWidth=item.Frame.DataWidth; + overlayItem.Frame.DistanceWidth=item.Frame.DistanceWidth; + overlayItem.Frame.XPointCount=item.Frame.XPointCount; + if (overlayItem.ChartPaint.length>0) + overlayItem.Frame.RightOffset=rightOffset; + overlayItem.Frame.Draw(); + rightOffset+=item.Interval; + } } this.SizeChange=false; } + + this.DrawOveraly=function() + { + for(var i in this.SubFrame) + { + var item=this.SubFrame[i]; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + for(k in overlayItem.ChartPaint) + { + overlayItem.ChartPaint[k].Draw(); + } + } + } + } + this.DrawLock=function() { for (var i in this.SubFrame) @@ -7309,6 +7528,12 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.SizeChange=sizeChange; + + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + if (overlayItem.Frame) overlayItem.Frame.SizeChange=sizeChange; + } } //画布的位置 @@ -7389,12 +7614,26 @@ function HQTradeFrame() this.ZoomUp=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomUp(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -7403,12 +7642,26 @@ function HQTradeFrame() this.ZoomDown=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomDown(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -8700,6 +8953,7 @@ function ChartKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartKLine'; //类名 this.Symbol; //股票代码 this.DrawType=0; // 0=实心K线柱子 1=收盘价线 2=美国线 3=空心K线柱子 this.CloseLineColor=g_JSChartResource.CloseLineColor; @@ -9748,10 +10002,10 @@ function ChartOverlayKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartOverlayKLine'; //类名 this.Color="rgb(65,105,225)"; this.MainData; //主图K线数据 this.SourceData; //叠加的原始数据 - this.Name="ChartOverlayKLine"; this.Title; this.DrawType=0; @@ -10219,6 +10473,7 @@ function ChartMinuteVolumBar() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinuteVolumBar'; //类名 this.UpColor = g_JSChartResource.UpBarColor; this.DownColor = g_JSChartResource.DownBarColor; this.YClose; //前收盘 @@ -10298,6 +10553,7 @@ function ChartLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth; //线段宽度 this.DrawType=0; //画图方式 0=无效数平滑 1=无效数不画断开 @@ -10428,6 +10684,7 @@ function ChartPointDot() this.newMethod(); delete this.newMethod; + this.ClassName='ChartPointDot'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Radius=1; //点半径 @@ -10809,6 +11066,7 @@ function ChartLineMultiData() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLineMultiData'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -10902,6 +11160,7 @@ function ChartStickLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStickLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth=2*GetDevicePixelRatio(); //线段宽度 @@ -11052,6 +11311,7 @@ function ChartText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartText'; //类名 this.TextFont="14px 微软雅黑"; this.Draw=function() @@ -11132,6 +11392,7 @@ function ChartSingleText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartSingleText'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.TextFont="14px 微软雅黑"; //线段宽度 this.Text; @@ -11305,6 +11566,7 @@ function ChartStraightLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -11361,6 +11623,7 @@ function ChartStraightArea() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightArea'; //类名 this.Color = "rgb(255,193,37)"; //线段颜色 this.Font ='11px 微软雅黑'; @@ -11491,6 +11754,7 @@ function ChartMinutePriceLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinutePriceLine'; //类名 this.YClose; this.IsDrawArea=true; //是否画价格面积图 this.AreaColor='rgba(0,191,255,0.1)'; @@ -11667,7 +11931,7 @@ function ChartOverlayMinutePriceLine() this.MainData; //主图数据 this.MainYClose; //主图股票的前收盘价 - this.Name="ChartOverlayMinutePriceLine"; + this.ClassName="ChartOverlayMinutePriceLine"; this.Title; this.Symbol; //叠加的股票代码 this.YClose; //叠加的股票前收盘 @@ -11769,6 +12033,7 @@ function ChartMACD() this.newMethod(); delete this.newMethod; + this.ClassName="ChartMACD"; this.UpColor=g_JSChartResource.UpBarColor; this.DownColor=g_JSChartResource.DownBarColor; @@ -11852,6 +12117,7 @@ function ChartBar() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBar"; this.UpBarColor=g_JSChartResource.UpBarColor; this.DownBarColor=g_JSChartResource.DownBarColor; @@ -11947,6 +12213,7 @@ function ChartBand() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartBand"; this.FirstColor = g_JSChartResource.Index.LineColor[0]; this.SecondColor = g_JSChartResource.Index.LineColor[1]; @@ -12054,6 +12321,7 @@ function ChartChannel() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartChannel"; this.IsHScreen=false; //是否是横屏 this.PointCount=0; this.DataWidth=0; @@ -12215,6 +12483,8 @@ function ChartLock() this.newMethod=IChartPainting; //派生 this.newMethod(); delete this.newMethod; + + this.ClassName="ChartLock"; this.WidthDiv = 0.2; // 框子宽度占比 this.LockCount = 20; // 锁最新的几个数据 this.BGColor = g_JSChartResource.LockBGColor; @@ -12359,6 +12629,7 @@ function ChartBuySell() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBuySell"; this.TextFont=g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体 this.LastDataIcon=g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'}; this.BuyIcon=g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'}; @@ -16212,6 +16483,7 @@ function DynamicChartTitlePainting() this.Explain; this.ColorIndex; //五彩K线名字 {Name:'名字'} this.TradeIndex; //专家系统名字{Name:'名字'} + this.OverlayIndex=new Map(); //叠加指标 key=Identify value={ Data:数据, Title:标题, Identify:标识} this.FormatValue=function(value,item) { @@ -16362,6 +16634,83 @@ function DynamicChartTitlePainting() this.Canvas.fillText(this.TradeIndex.Name,left,bottom,textWidth); left+=textWidth; } + + this.DrawOverlayIndex(left); + } + + this.DrawOverlayIndex=function(left) //叠加指标标题 + { + var bottom=this.Frame.ChartBorder.GetTop()+this.Frame.ChartBorder.TitleHeight/2; //上下居中显示 + var right=this.Frame.ChartBorder.GetRight(); + if (left>right) return; + + var spaceWidth=5*GetDevicePixelRatio(); + var drawLeft=left; + for(item of this.OverlayIndex) + { + left+=spaceWidth; + overlayItem=item[1]; + if (overlayItem.Title) + { + this.Canvas.fillStyle=this.TitleColor; + var textWidth=this.Canvas.measureText(overlayItem.Title).width+2; + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(overlayItem.Title,drawLeft,bottom,textWidth); + } + + for(var i in overlayItem.Data) + { + var item=overlayItem.Data[i]; + if (!item || !item.Data || !item.Data.Data || !item.Name) continue; + if (item.Data.Data.length<=0) continue; + + var value=null; + var valueText=null; + if (item.DataType=="StraightLine") //直线只有1个数据 + { + value=item.Data.Data[0]; + valueText=this.FormatValue(value,item); + } + else + { + var index=Math.abs(this.CursorIndex-0.5); + index=parseInt(index.toFixed(0)); + var dataIndex=item.Data.DataOffset+index; + if (dataIndex>=item.Data.Data.length) dataIndex=item.Data.Data.length-1; + if (dataIndex<0) continue; + + value=item.Data.Data[dataIndex]; + if (value==null) continue; + + if (item.DataType=="HistoryData-Vol") + { + value=value.Vol; + valueText=this.FormatValue(value,item); + } + else if (item.DataType=="MultiReport") + { + valueText=this.FormatMultiReport(value,item); + } + else + { + valueText=this.FormatValue(value,item); + } + } + + this.Canvas.fillStyle=item.Color; + + var text=item.Name+":"+valueText; + var textWidth=this.Canvas.measureText(text).width+2; //后空2个像素 + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(text,drawLeft,bottom,textWidth); + } + + if (left>right) break; + } } this.HScreenDraw=function() @@ -19262,6 +19611,7 @@ function JSChartResource() this.FrameSplitTextColor="rgb(117,125,129)"; //刻度文字颜色 this.FrameSplitTextFont=14*GetDevicePixelRatio() +"px 微软雅黑"; //坐标刻度文字字体 this.FrameTitleBGColor="rgb(246,251,253)"; //标题栏背景色 + this.OverlayFrameBolderPen='rgb(190,190,190)' this.CorssCursorBGColor="rgb(43,54,69)"; //十字光标背景 this.CorssCursorTextColor="rgb(255,255,255)"; @@ -20793,7 +21143,6 @@ function KLineChartContainer(uielement) this.SetCustomShow(this.CustomShow,hisData); this.CustomShow=null; } - } this.UpdateMainData=function(hisData) @@ -20887,6 +21236,26 @@ function KLineChartContainer(uielement) this.WindowIndex[windowIndex].BindData(this,windowIndex,hisData); } + //叠加指标 + this.BindOverlayIndexData=function(overlayItem, windowIndex, hisData) + { + if (!overlayItem.Script) return; + + if (typeof(overlayItem.Script.RequestData)=='function') + { + overlayItem.Script.RequestData(this,windowIndex,hisData); + return; + } + + if (typeof(overlayItem.Script.ExecuteScript)=='function') + { + overlayItem.Script.ExecuteScript(this,windowIndex,hisData); + return; + } + + overlayItem.Script.BindData(this,windowIndex,hisData); + } + //执行指示(专家指示 五彩K线) this.BindInstructionIndexData=function(hisData) { @@ -21013,6 +21382,17 @@ function KLineChartContainer(uielement) this.Draw(); this.UpdatePointByCursorIndex(); //更新十字光标位子 + //叠加指标 + for(var i=0;i0) + { + var delOverlayIndexMenu={ text:'删除叠加指标', children:this.GetDeleteOverlayIndex(chart,overlayIndex) } + dataList.splice(3,0,delOverlayIndexMenu); + } + console.log('[KLineRightMenu::DoModal]',identify); rightMenu.Show({ windowIndex :identify, @@ -29786,6 +30286,36 @@ function KLineRightMenu(divElement) rightMenu.Hide(); }); } + + this.GetOverlayIndex=function(chart, windowsIndex) + { + if (windowsIndex>=chart.Frame.SubFrame.length) return []; + + var result=[]; + var item=chart.Frame.SubFrame[windowsIndex]; + for(var i in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[i]; + result.push({Name:overlayItem.Script.Name, Identify:overlayItem.Identify}); + } + + return result; + } + + this.GetDeleteOverlayIndex=function(chart,overlayIndex) + { + var data=[]; + for(var i in overlayIndex) + { + let identify=overlayIndex[i].Identify; + data.push({text:overlayIndex[i].Name, click:function() + { + chart.DeleteOverlayWindowsIndex(identify) + }}); + } + + return data; + } } //K线区间选择右键菜单 @@ -40292,7 +40822,7 @@ function ScriptIndex(name,script,args,option) return; } - //清空指标图形 + //清空主指标图形 hqChart.DeleteIndexPaint(windowIndex); if (windowIndex==0) hqChart.ShowKLine(true); @@ -40451,6 +40981,595 @@ function ScriptIndex(name,script,args,option) } } +function OverlayScriptIndex(name,script,args,option) +{ + this.newMethod=ScriptIndex; //派生 + this.newMethod(name,script,args,option); + delete this.newMethod; + + //叠加指标 + this.OverlayIndex=null; // { IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame } + + this.BindData=function(hqChart,windowIndex,hisData) + { + if (!this.OverlayIndex || this.OverlayIndex.IsOverlay!=true) return; + + this.OverlayIndex.Frame.ChartPaint=[]; + if (this.OutVar==null || this.OutVar.length<0) return; + + /*叠加一个K线背景 + if (this.KLineType!=null) + { + if (this.KLineType===0 || this.KLineType===1 || this.KLineType===2) this.CreateSelfKLine(hqChart,windowIndex,hisData); + else if (this.KLineType===-1 && windowIndex==0) hqChart.ShowKLine(false); + } + + if (windowIndex>=1 && hqChart.Frame) + { + hqChart.Frame.SubFrame[windowIndex].Frame.YSplitOperator.FloatPrecision=this.FloatPrecision; + if (this.YSpecificMaxMin) hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin=this.YSpecificMaxMin; //最大最小值 + if (this.YSplitScale) hqChart.Frame.SubFrame[windowIndex].Frame.YSplitScale=this.YSplitScale; //固定刻度 + } + */ + + //指标名字 + var titleInfo={ Data:[], Title:this.Name }; + let indexParam=''; + for(var i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + if (indexParam.length>0) titleInfo.Title=this.Name+'('+indexParam+')'; + + var titleIndex=windowIndex+1; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.set(this.OverlayIndex.Identify,titleInfo); + + for(var i in this.OutVar) + { + let item=this.OutVar[i]; + if (item.IsExData===true) continue; //扩展数据不显示图形 + + if (item.Type==0) + { + this.CreateLine(hqChart,windowIndex,item,i); + } + else if (item.Type==1) + { + switch(item.Draw.DrawType) + { + case 'STICKLINE': + this.CreateBar(hqChart,windowIndex,item,i); + break; + case 'DRAWTEXT': + case 'SUPERDRAWTEXT': + this.CreateText(hqChart,windowIndex,item,i); + break; + case 'DRAWLINE': + this.CreateStraightLine(hqChart,windowIndex,item,i); + break; + case 'DRAWBAND': + this.CreateBand(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE_IF': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'POLYLINE': + this.CreatePolyLine(hqChart,windowIndex,item,i); + break; + case 'DRAWNUMBER': + this.CreateNumberText(hqChart,windowIndex,item,i); + break; + case 'DRAWICON': + this.CreateIcon(hqChart,windowIndex,item,i); + break; + case 'DRAWCHANNEL': + this.CreateChannel(hqChart,windowIndex,item,i); + break; + } + } + else if (item.Type==2) + { + this.CreateMACD(hqChart,windowIndex,item,i); + } + else if (item.Type==3) + { + this.CreatePointDot(hqChart,windowIndex,item,i); + } + else if (item.Type==4) + { + this.CreateLineStick(hqChart,windowIndex,item,i); + } + else if (item.Type==5) + { + this.CreateStick(hqChart,windowIndex,item,i); + } + else if (item.Type==6) + { + this.CreateVolStick(hqChart,windowIndex,item,i,hisData); + } + } + + + /* + hqChart.TitlePaint[titleIndex].Title=this.Name; + + let indexParam=''; + for(let i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + + if (indexParam.length>0) hqChart.TitlePaint[titleIndex].Title=this.Name+'('+indexParam+')'; + */ + + return true; + } + + //指标执行完成 + this.RecvResultData=function(outVar,param) + { + let hqChart=param.HQChart; + let windowIndex=param.WindowIndex; + let hisData=param.HistoryData; + param.Self.OutVar=outVar; + param.Self.BindData(hqChart,windowIndex,hisData); + + param.HQChart.UpdataDataoffset(); //更新数据偏移 + param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值 + param.HQChart.Draw(); + + var event=hqChart.GetOverlayIndexEvent(); //指标计算完成回调 + if (event) + { + var self=param.Self; + var data={ OutVar:self.OutVar, WindowIndex: windowIndex, Name: self.Name, Arguments: self.Arguments, HistoryData: hisData, + Identify:self.OverlayIndex.Identify, + Stock: {Symbol:hqChart.Symbol,Name:hqChart.Name} }; + event.Callback(event,data,self); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + // 图形创建 + ///////////////////////////////////////////////////////////////////////////////////// + + this.CreateLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.DrawType=1; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) line.LineWidth=width; + } + + if (varItem.IsShow==false) line.IsShow=false; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + //创建柱子 + this.CreateBar=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStickLine(); + chart.Canvas=hqChart.Canvas; + if (varItem.Draw.Width>0) chart.LineWidth=varItem.Draw.Width; + else chart.LineWidth=1; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建文本 + this.CreateText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + chart.Text=varItem.Draw.Text; + if (varItem.Draw.Direction>0) chart.Direction=varItem.Draw.Direction; + if (varItem.Draw.YOffset>0) chart.YOffset=varItem.Draw.YOffset; + if (varItem.Draw.TextAlign) chart.TextAlign=varItem.Draw.TextAlign; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //COLORSTICK + this.CreateMACD=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartMACD(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,this.GetDefaultColor(id)); + + frame.ChartPaint.push(chart); + } + + this.CreatePointDot=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartPointDot(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.Radius) chart.Radius=varItem.Radius; + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.Radius=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateLineStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLineStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStraightLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.DrawType=1; + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(line.Data,varItem.Name,line.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateVolStick=function(hqChart,windowIndex,varItem,id,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartVolStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + chart.KLineDrawType=hqChart.KLineDrawType; //设置K线显示类型 + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + chart.HistoryData=hisData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateBand=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartBand(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.FirstColor = varItem.Draw.Color[0]; + chart.SecondColor = varItem.Draw.Color[1]; + chart.Data.Data=varItem.Draw.DrawData; + + frame.ChartPaint.push(chart); + } + + //创建K线图 + this.CreateKLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data.Data=varItem.Draw.DrawData; + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + + if (varItem.Color) //如果设置了颜色,使用外面设置的颜色 + chart.UnchagneColor=chart.DownColor=chart.UpColor=this.GetColor(varItem.Color); + + frame.ChartPaint.push(chart); + } + + this.CreatePolyLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(line.Data,' ',line.Color); //给一个空的标题 + + frame.ChartPaint.push(chart); + } + + this.CreateNumberText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData.Value; + chart.Text=varItem.Draw.DrawData.Text; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建图标 + this.CreateIcon=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + chart.TextAlign='center'; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var icon=varItem.Draw.Icon; + if (icon.IconFont==true) + { + chart.IconFont={ Family:icon.Family, Text:icon.Symbol, Color:icon.Color }; + } + else + { + chart.Text=icon.Symbol; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else if (icon.Color) chart.Color=icon.Color; + else chart.Color='rgb(0,0,0)'; + } + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建通道 + this.CreateChannel=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartChannel(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + if(varItem.Draw.AreaColor) chart.AreaColor=varItem.Draw.AreaColor; + else if (varItem.Color) chart.AreaColor=this.GetColor(varItem.Color); + else chart.AreaColor=this.GetDefaultColor(id); + + if (varItem.Draw.Border.Color) chart.LineColor=varItem.Draw.Border.Color; + else chart.LineColor=null; + + if (varItem.Draw.Border.Dotted) chart.LineDotted=varItem.Draw.Border.Dotted; + if (varItem.Draw.Border.Width>0) chart.LineWidth=varItem.Draw.Border.Width; + + //let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + frame.ChartPaint.push(chart); + } + + //创建K线 + this.CreateSelfKLine=function(hqChart,windowIndex,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name="Self Kline" + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data=hisData + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + chart.DrawType=this.KLineType; + + frame.ChartPaint.push(chart); + } + + //给一个默认的颜色 + this.GetDefaultColor=function(id) + { + let COLOR_ARRAY= + [ + "rgb(24,71,178)", + "rgb(42,230,215)", + "rgb(252,96,154)", + "rgb(0,128,255)", + "rgb(229,0,79)", + "rgb(68,114,196)", + "rgb(255,174,0)", + "rgb(25,199,255)", + "rgb(175,95,162)", + "rgb(236,105,65)", + ]; + + let number=parseInt(id); + return COLOR_ARRAY[number%(COLOR_ARRAY.length-1)]; + } +} + //后台执行指标 function APIScriptIndex(name,script,args,option) { diff --git a/webhqchart.demo/demo/phone22.html b/webhqchart.demo/demo/phone22.html new file mode 100644 index 0000000000000000000000000000000000000000..2bd5e7632ca6c17529a66a82c23355e2afad3a10 --- /dev/null +++ b/webhqchart.demo/demo/phone22.html @@ -0,0 +1,228 @@ + + + + + +页面行情(K线图) + + + + + + + +
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webhqchart.demo/jscommon/umychart.complier.js b/webhqchart.demo/jscommon/umychart.complier.js index b66ff4c557971521dfd25c61d39e8c99e8b8c6aa..f1c62d5f4462de228ac459039a91db3611b9d054 100644 --- a/webhqchart.demo/jscommon/umychart.complier.js +++ b/webhqchart.demo/jscommon/umychart.complier.js @@ -9073,7 +9073,7 @@ function ScriptIndex(name,script,args,option) return; } - //清空指标图形 + //清空主指标图形 hqChart.DeleteIndexPaint(windowIndex); if (windowIndex==0) hqChart.ShowKLine(true); @@ -9232,6 +9232,595 @@ function ScriptIndex(name,script,args,option) } } +function OverlayScriptIndex(name,script,args,option) +{ + this.newMethod=ScriptIndex; //派生 + this.newMethod(name,script,args,option); + delete this.newMethod; + + //叠加指标 + this.OverlayIndex=null; // { IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame } + + this.BindData=function(hqChart,windowIndex,hisData) + { + if (!this.OverlayIndex || this.OverlayIndex.IsOverlay!=true) return; + + this.OverlayIndex.Frame.ChartPaint=[]; + if (this.OutVar==null || this.OutVar.length<0) return; + + /*叠加一个K线背景 + if (this.KLineType!=null) + { + if (this.KLineType===0 || this.KLineType===1 || this.KLineType===2) this.CreateSelfKLine(hqChart,windowIndex,hisData); + else if (this.KLineType===-1 && windowIndex==0) hqChart.ShowKLine(false); + } + + if (windowIndex>=1 && hqChart.Frame) + { + hqChart.Frame.SubFrame[windowIndex].Frame.YSplitOperator.FloatPrecision=this.FloatPrecision; + if (this.YSpecificMaxMin) hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin=this.YSpecificMaxMin; //最大最小值 + if (this.YSplitScale) hqChart.Frame.SubFrame[windowIndex].Frame.YSplitScale=this.YSplitScale; //固定刻度 + } + */ + + //指标名字 + var titleInfo={ Data:[], Title:this.Name }; + let indexParam=''; + for(var i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + if (indexParam.length>0) titleInfo.Title=this.Name+'('+indexParam+')'; + + var titleIndex=windowIndex+1; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.set(this.OverlayIndex.Identify,titleInfo); + + for(var i in this.OutVar) + { + let item=this.OutVar[i]; + if (item.IsExData===true) continue; //扩展数据不显示图形 + + if (item.Type==0) + { + this.CreateLine(hqChart,windowIndex,item,i); + } + else if (item.Type==1) + { + switch(item.Draw.DrawType) + { + case 'STICKLINE': + this.CreateBar(hqChart,windowIndex,item,i); + break; + case 'DRAWTEXT': + case 'SUPERDRAWTEXT': + this.CreateText(hqChart,windowIndex,item,i); + break; + case 'DRAWLINE': + this.CreateStraightLine(hqChart,windowIndex,item,i); + break; + case 'DRAWBAND': + this.CreateBand(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE_IF': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'POLYLINE': + this.CreatePolyLine(hqChart,windowIndex,item,i); + break; + case 'DRAWNUMBER': + this.CreateNumberText(hqChart,windowIndex,item,i); + break; + case 'DRAWICON': + this.CreateIcon(hqChart,windowIndex,item,i); + break; + case 'DRAWCHANNEL': + this.CreateChannel(hqChart,windowIndex,item,i); + break; + } + } + else if (item.Type==2) + { + this.CreateMACD(hqChart,windowIndex,item,i); + } + else if (item.Type==3) + { + this.CreatePointDot(hqChart,windowIndex,item,i); + } + else if (item.Type==4) + { + this.CreateLineStick(hqChart,windowIndex,item,i); + } + else if (item.Type==5) + { + this.CreateStick(hqChart,windowIndex,item,i); + } + else if (item.Type==6) + { + this.CreateVolStick(hqChart,windowIndex,item,i,hisData); + } + } + + + /* + hqChart.TitlePaint[titleIndex].Title=this.Name; + + let indexParam=''; + for(let i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + + if (indexParam.length>0) hqChart.TitlePaint[titleIndex].Title=this.Name+'('+indexParam+')'; + */ + + return true; + } + + //指标执行完成 + this.RecvResultData=function(outVar,param) + { + let hqChart=param.HQChart; + let windowIndex=param.WindowIndex; + let hisData=param.HistoryData; + param.Self.OutVar=outVar; + param.Self.BindData(hqChart,windowIndex,hisData); + + param.HQChart.UpdataDataoffset(); //更新数据偏移 + param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值 + param.HQChart.Draw(); + + var event=hqChart.GetOverlayIndexEvent(); //指标计算完成回调 + if (event) + { + var self=param.Self; + var data={ OutVar:self.OutVar, WindowIndex: windowIndex, Name: self.Name, Arguments: self.Arguments, HistoryData: hisData, + Identify:self.OverlayIndex.Identify, + Stock: {Symbol:hqChart.Symbol,Name:hqChart.Name} }; + event.Callback(event,data,self); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + // 图形创建 + ///////////////////////////////////////////////////////////////////////////////////// + + this.CreateLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.DrawType=1; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) line.LineWidth=width; + } + + if (varItem.IsShow==false) line.IsShow=false; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + //创建柱子 + this.CreateBar=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStickLine(); + chart.Canvas=hqChart.Canvas; + if (varItem.Draw.Width>0) chart.LineWidth=varItem.Draw.Width; + else chart.LineWidth=1; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建文本 + this.CreateText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + chart.Text=varItem.Draw.Text; + if (varItem.Draw.Direction>0) chart.Direction=varItem.Draw.Direction; + if (varItem.Draw.YOffset>0) chart.YOffset=varItem.Draw.YOffset; + if (varItem.Draw.TextAlign) chart.TextAlign=varItem.Draw.TextAlign; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //COLORSTICK + this.CreateMACD=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartMACD(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,this.GetDefaultColor(id)); + + frame.ChartPaint.push(chart); + } + + this.CreatePointDot=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartPointDot(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.Radius) chart.Radius=varItem.Radius; + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.Radius=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateLineStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLineStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStraightLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.DrawType=1; + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(line.Data,varItem.Name,line.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateVolStick=function(hqChart,windowIndex,varItem,id,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartVolStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + chart.KLineDrawType=hqChart.KLineDrawType; //设置K线显示类型 + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + chart.HistoryData=hisData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateBand=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartBand(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.FirstColor = varItem.Draw.Color[0]; + chart.SecondColor = varItem.Draw.Color[1]; + chart.Data.Data=varItem.Draw.DrawData; + + frame.ChartPaint.push(chart); + } + + //创建K线图 + this.CreateKLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data.Data=varItem.Draw.DrawData; + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + + if (varItem.Color) //如果设置了颜色,使用外面设置的颜色 + chart.UnchagneColor=chart.DownColor=chart.UpColor=this.GetColor(varItem.Color); + + frame.ChartPaint.push(chart); + } + + this.CreatePolyLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(line.Data,' ',line.Color); //给一个空的标题 + + frame.ChartPaint.push(chart); + } + + this.CreateNumberText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData.Value; + chart.Text=varItem.Draw.DrawData.Text; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建图标 + this.CreateIcon=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + chart.TextAlign='center'; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var icon=varItem.Draw.Icon; + if (icon.IconFont==true) + { + chart.IconFont={ Family:icon.Family, Text:icon.Symbol, Color:icon.Color }; + } + else + { + chart.Text=icon.Symbol; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else if (icon.Color) chart.Color=icon.Color; + else chart.Color='rgb(0,0,0)'; + } + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建通道 + this.CreateChannel=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartChannel(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + if(varItem.Draw.AreaColor) chart.AreaColor=varItem.Draw.AreaColor; + else if (varItem.Color) chart.AreaColor=this.GetColor(varItem.Color); + else chart.AreaColor=this.GetDefaultColor(id); + + if (varItem.Draw.Border.Color) chart.LineColor=varItem.Draw.Border.Color; + else chart.LineColor=null; + + if (varItem.Draw.Border.Dotted) chart.LineDotted=varItem.Draw.Border.Dotted; + if (varItem.Draw.Border.Width>0) chart.LineWidth=varItem.Draw.Border.Width; + + //let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + frame.ChartPaint.push(chart); + } + + //创建K线 + this.CreateSelfKLine=function(hqChart,windowIndex,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name="Self Kline" + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data=hisData + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + chart.DrawType=this.KLineType; + + frame.ChartPaint.push(chart); + } + + //给一个默认的颜色 + this.GetDefaultColor=function(id) + { + let COLOR_ARRAY= + [ + "rgb(24,71,178)", + "rgb(42,230,215)", + "rgb(252,96,154)", + "rgb(0,128,255)", + "rgb(229,0,79)", + "rgb(68,114,196)", + "rgb(255,174,0)", + "rgb(25,199,255)", + "rgb(175,95,162)", + "rgb(236,105,65)", + ]; + + let number=parseInt(id); + return COLOR_ARRAY[number%(COLOR_ARRAY.length-1)]; + } +} + //后台执行指标 function APIScriptIndex(name,script,args,option) { diff --git a/webhqchart.demo/jscommon/umychart.index.data.js b/webhqchart.demo/jscommon/umychart.index.data.js index b763756175595584c7b3b013b622b8d64f821e1b..367a0f82cc96074a2dfb1eb4afd8f4ae4dac3c7f 100644 --- a/webhqchart.demo/jscommon/umychart.index.data.js +++ b/webhqchart.demo/jscommon/umychart.index.data.js @@ -43,7 +43,7 @@ function JSIndexScript() ['DMI', this.DMI],['CR', this.CR],['PSY', this.PSY], ['CCI', this.CCI],['DMA', this.DMA],['TRIX', this.TRIX], ['VR', this.VR],['EMV', this.EMV],['ROC', this.ROC], - ['MTM', this.MIM],['FSL', this.FSL],['CYR', this.CYR], + ['MTM', this.MTM],['FSL', this.FSL],['CYR', this.CYR], ['MASS', this.MASS],['WAD', this.WAD],['CHO', this.CHO], ['ADTM', this.ADTM],['HSL', this.HSL],['BIAS36', this.BIAS36], ['BIAS_QL', this.BIAS_QL],['DPO', this.DPO],['OSC', this.OSC], diff --git a/webhqchart.demo/jscommon/umychart.js b/webhqchart.demo/jscommon/umychart.js index 75ac9bad18c6e130911e13ef36b424ae0dbebe94..f0da77903fd26961a1627a224636bca511f824d8 100644 --- a/webhqchart.demo/jscommon/umychart.js +++ b/webhqchart.demo/jscommon/umychart.js @@ -245,9 +245,19 @@ function JSChart(divElement) if (item.Modify!=null) chart.Frame.SubFrame[i].Frame.ModifyIndex=item.Modify; if (item.Change!=null) chart.Frame.SubFrame[i].Frame.ChangeIndex=item.Change; if (item.Close!=null) chart.Frame.SubFrame[i].Frame.CloseIndex=item.Close; + if (item.Overlay!=null) chart.Frame.SubFrame[i].Frame.OverlayIndex=item.Overlay; if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight=item.TitleHeight; } + + //叠加指标 + for (var i in option.OverlayIndex) + { + var item=option.OverlayIndex[i]; + if (item.Windows>=chart.Frame.SubFrame.length) continue; + chart.CreateOverlayWindowsIndex(item.Windows,item.Index); + } + this.AdjustTitleHeight(chart); return chart; @@ -1012,6 +1022,7 @@ var JSCHART_EVENT_ID= RECV_TRAIN_MOVE_STEP:4, //接收K线训练,移动一次K线 CHART_STATUS:5, //每次Draw() 以后会调用 BARRAGE_PLAY_END:6, //单个弹幕播放完成 + RECV_OVERLAY_INDEX_DATA:7,//接收叠加指标数据 } var JSCHART_OPERATOR_ID= @@ -1100,13 +1111,22 @@ function JSChartContainer(uielement) this.mapEvent.delete(eventid); } + this.GetEventCallback=function(id) //获取事件回调 + { + if (!this.mapEvent.has(id)) return null; + var item=this.mapEvent.get(id); + return item; + } + //接收指标数据 this.GetIndexEvent=function() { - if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_INDEX_DATA)) return null; + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_INDEX_DATA); + } - var item=this.mapEvent.get(JSCHART_EVENT_ID.RECV_INDEX_DATA); - return item; + this.GetOverlayIndexEvent=function() + { + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_OVERLAY_INDEX_DATA); } uielement.onmousemove=function(e) @@ -1603,6 +1623,8 @@ function JSChartContainer(uielement) item.Draw(); } + this.Frame.DrawOveraly(); //画叠加指标 + //固定扩展图形 for(var i in this.ExtendChartPaint) { @@ -2189,6 +2211,17 @@ function JSChartContainer(uielement) } item.Frame.XYSplit=true; } + + //更新子坐标 + for(var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + overlayItem.UpdateFrameMaxMin(); + } + } } this.DataMoveLeft=function() @@ -2243,6 +2276,23 @@ function JSChartContainer(uielement) if (!item.Data) continue; item.Data.DataOffset=data.DataOffset; } + + //叠加指标当前显示的数据偏移 + for (var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + for(var k in overlayItem.ChartPaint) + { + var item=overlayItem.ChartPaint[k]; + if (!item.Data) continue; + item.Data.DataOffset=data.DataOffset; + } + } + } + } this.DataMove=function(step,isLeft) @@ -2384,7 +2434,7 @@ function JSChartContainer(uielement) if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存 console.log('[JSChartContainer::SaveToImage]', this.UIElement); - clrBG='rgb(255,255,255)'; + var clrBG='rgb(255,255,255)'; if (colorGB) clrBG=colorGB; this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height); this.Canvas.fillStyle=clrBG; @@ -3416,6 +3466,7 @@ function KLineFrame() this.ModifyIndex=true; //是否显示'改参数'菜单 this.ChangeIndex=true; //是否显示'换指标'菜单 this.CloseIndex=true; //是否显示'关闭指标窗口'菜单 + this.OverlayIndex=false; //是否显示叠加指标 this.ModifyIndexEvent; //改参数 点击事件 this.ChangeIndexEvent; //换指标 点击事件 @@ -3433,7 +3484,7 @@ function KLineFrame() this.ChartBorder.UIElement.parentNode.appendChild(divToolbar); } - if (!this.ModifyIndex && !this.ChangeIndex) + if (!this.ModifyIndex && !this.ChangeIndex && !this.OverlayIndex) { divToolbar.style.display='none'; return; @@ -3450,7 +3501,8 @@ function KLineFrame() var left=chartWidth-(this.ChartBorder.Right/pixelTatio)-toolbarWidth; var top=this.ChartBorder.GetTop()/pixelTatio; var spanIcon = "  " + - ""; + "  " + + ""; if (this.Identify!==0 && this.CloseIndex) //第1个窗口不能关闭 { @@ -3479,13 +3531,32 @@ function KLineFrame() },this.ModifyIndexEvent); if (!this.ChangeIndex) //隐藏'换指标' + { $("#"+divToolbar.id+" .index_change").hide(); + } else if (typeof(this.ChangeIndexEvent)=='function') + { $("#"+divToolbar.id+" .index_change").click( { Chart:this.ChartBorder.UIElement.JSChartContainer, - Identify:this.Identify + Identify:this.Identify, + IsOverlay:false + },this.ChangeIndexEvent); + } + + if (!this.OverlayIndex) + { + $("#"+divToolbar.id+" .index_overlay").hide(); + } + else + { + $("#"+divToolbar.id+" .index_overlay").click( + { + Chart:this.ChartBorder.UIElement.JSChartContainer, + Identify:this.Identify, + IsOverlay:true },this.ChangeIndexEvent); + } $("#"+divToolbar.id+" .index_close").click( { @@ -3724,6 +3795,93 @@ function KLineFrame() } } +function OverlayKLineFrame() +{ + this.newMethod=KLineFrame; //派生 + this.newMethod(); + delete this.newMethod; + + this.MainFrame=null; //主框架 + this.RightOffset=50; + this.PenBorder=g_JSChartResource.OverlayFrameBolderPen; //'rgb(0,0,0)' + + this.Draw=function() + { + this.SplitXYCoordinate(); + + this.DrawVertical(); + this.DrawHorizontal(); + + this.SizeChange=false; + this.XYSplit=false; + } + + //分割x,y轴坐标信息 + this.SplitXYCoordinate=function() + { + if (this.XYSplit==false) return; + if (this.YSplitOperator!=null) this.YSplitOperator.Operator(); + // if (this.XSplitOperator!=null) this.XSplitOperator.Operator(); 子坐标和主坐标X轴一致 所以不用计算 + } + + //画Y轴 + this.DrawHorizontal=function() + { + var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom = this.ChartBorder.GetBottom(); + var top = this.ChartBorder.GetTopTitle(); + var borderRight=this.ChartBorder.Right; + right+=this.RightOffset; + + var yPrev=null; //上一个坐标y的值 + for(var i=this.HorizontalInfo.length-1; i>=0; --i) //从上往下画分割线 + { + var item=this.HorizontalInfo[i]; + var y=this.GetYFromData(item.Value); + if (y!=null && Math.abs(y-yPrev)= bottom - 2) this.Canvas.textBaseline = 'bottom'; + else if (y <= top + 2) this.Canvas.textBaseline = 'top'; + else this.Canvas.textBaseline = "middle"; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(right-5,ToFixedPoint(y)); + this.Canvas.lineTo(right,ToFixedPoint(y)); + this.Canvas.stroke(); + + //坐标信息 右边 间距小于10 不画坐标 + if (item.Message[1]!=null && borderRight>10) + { + if (item.Font!=null) this.Canvas.font=item.Font; + + this.Canvas.fillStyle=item.TextColor; + this.Canvas.textAlign="left"; + this.Canvas.fillText(item.Message[1],right+2,y); + } + + yPrev=y; + } + } + + //画X轴 + this.DrawVertical=function() + { + var top=this.ChartBorder.GetTopEx(); + //var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom=this.ChartBorder.GetBottomEx(); + right+=this.RightOffset; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(ToFixedPoint(right),ToFixedPoint(top)); + this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(bottom)); + this.Canvas.stroke(); + } +} + //K线横屏框架 function KLineHScreenFrame() { @@ -4005,6 +4163,36 @@ function SubFrameItem() { this.Frame; this.Height; + this.OverlayIndex=[]; //叠加指标 + this.Interval=50; //子坐标间间距 +} + +function OverlayIndexItem() +{ + this.Frame; + this.ChartPaint=[]; + this.Identify=Guid(); + this.Scprit; //脚本 + + this.UpdateFrameMaxMin=function() //调整坐标最大 最小值 + { + var value={Max:null, Min:null} + for(var i in this.ChartPaint) + { + var paint=this.ChartPaint[i]; + var range=paint.GetMaxMin(); + + if (value.Max==null || value.Maxrange.Min) value.Min=range.Min + } + + if (value.Max!=null && value.Min!=null) + { + this.Frame.HorizontalMax=value.Max; + this.Frame.HorizontalMin=value.Min; + this.Frame.XYSplit=true; + } + } } //行情框架 @@ -4053,10 +4241,41 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.Draw(); + + var rightOffset=item.Interval; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + //把主坐标部分设置给子坐标下来 + overlayItem.Frame.DataWidth=item.Frame.DataWidth; + overlayItem.Frame.DistanceWidth=item.Frame.DistanceWidth; + overlayItem.Frame.XPointCount=item.Frame.XPointCount; + if (overlayItem.ChartPaint.length>0) + overlayItem.Frame.RightOffset=rightOffset; + overlayItem.Frame.Draw(); + rightOffset+=item.Interval; + } } this.SizeChange=false; } + + this.DrawOveraly=function() + { + for(var i in this.SubFrame) + { + var item=this.SubFrame[i]; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + for(k in overlayItem.ChartPaint) + { + overlayItem.ChartPaint[k].Draw(); + } + } + } + } + this.DrawLock=function() { for (var i in this.SubFrame) @@ -4083,6 +4302,12 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.SizeChange=sizeChange; + + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + if (overlayItem.Frame) overlayItem.Frame.SizeChange=sizeChange; + } } //画布的位置 @@ -4163,12 +4388,26 @@ function HQTradeFrame() this.ZoomUp=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomUp(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -4177,12 +4416,26 @@ function HQTradeFrame() this.ZoomDown=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomDown(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -5474,6 +5727,7 @@ function ChartKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartKLine'; //类名 this.Symbol; //股票代码 this.DrawType=0; // 0=实心K线柱子 1=收盘价线 2=美国线 3=空心K线柱子 this.CloseLineColor=g_JSChartResource.CloseLineColor; @@ -6522,10 +6776,10 @@ function ChartOverlayKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartOverlayKLine'; //类名 this.Color="rgb(65,105,225)"; this.MainData; //主图K线数据 this.SourceData; //叠加的原始数据 - this.Name="ChartOverlayKLine"; this.Title; this.DrawType=0; @@ -6993,6 +7247,7 @@ function ChartMinuteVolumBar() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinuteVolumBar'; //类名 this.UpColor = g_JSChartResource.UpBarColor; this.DownColor = g_JSChartResource.DownBarColor; this.YClose; //前收盘 @@ -7072,6 +7327,7 @@ function ChartLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth; //线段宽度 this.DrawType=0; //画图方式 0=无效数平滑 1=无效数不画断开 @@ -7202,6 +7458,7 @@ function ChartPointDot() this.newMethod(); delete this.newMethod; + this.ClassName='ChartPointDot'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Radius=1; //点半径 @@ -7583,6 +7840,7 @@ function ChartLineMultiData() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLineMultiData'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -7676,6 +7934,7 @@ function ChartStickLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStickLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth=2*GetDevicePixelRatio(); //线段宽度 @@ -7826,6 +8085,7 @@ function ChartText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartText'; //类名 this.TextFont="14px 微软雅黑"; this.Draw=function() @@ -7906,6 +8166,7 @@ function ChartSingleText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartSingleText'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.TextFont="14px 微软雅黑"; //线段宽度 this.Text; @@ -8079,6 +8340,7 @@ function ChartStraightLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -8135,6 +8397,7 @@ function ChartStraightArea() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightArea'; //类名 this.Color = "rgb(255,193,37)"; //线段颜色 this.Font ='11px 微软雅黑'; @@ -8265,6 +8528,7 @@ function ChartMinutePriceLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinutePriceLine'; //类名 this.YClose; this.IsDrawArea=true; //是否画价格面积图 this.AreaColor='rgba(0,191,255,0.1)'; @@ -8441,7 +8705,7 @@ function ChartOverlayMinutePriceLine() this.MainData; //主图数据 this.MainYClose; //主图股票的前收盘价 - this.Name="ChartOverlayMinutePriceLine"; + this.ClassName="ChartOverlayMinutePriceLine"; this.Title; this.Symbol; //叠加的股票代码 this.YClose; //叠加的股票前收盘 @@ -8543,6 +8807,7 @@ function ChartMACD() this.newMethod(); delete this.newMethod; + this.ClassName="ChartMACD"; this.UpColor=g_JSChartResource.UpBarColor; this.DownColor=g_JSChartResource.DownBarColor; @@ -8626,6 +8891,7 @@ function ChartBar() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBar"; this.UpBarColor=g_JSChartResource.UpBarColor; this.DownBarColor=g_JSChartResource.DownBarColor; @@ -8721,6 +8987,7 @@ function ChartBand() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartBand"; this.FirstColor = g_JSChartResource.Index.LineColor[0]; this.SecondColor = g_JSChartResource.Index.LineColor[1]; @@ -8828,6 +9095,7 @@ function ChartChannel() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartChannel"; this.IsHScreen=false; //是否是横屏 this.PointCount=0; this.DataWidth=0; @@ -8989,6 +9257,8 @@ function ChartLock() this.newMethod=IChartPainting; //派生 this.newMethod(); delete this.newMethod; + + this.ClassName="ChartLock"; this.WidthDiv = 0.2; // 框子宽度占比 this.LockCount = 20; // 锁最新的几个数据 this.BGColor = g_JSChartResource.LockBGColor; @@ -9133,6 +9403,7 @@ function ChartBuySell() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBuySell"; this.TextFont=g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体 this.LastDataIcon=g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'}; this.BuyIcon=g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'}; @@ -12986,6 +13257,7 @@ function DynamicChartTitlePainting() this.Explain; this.ColorIndex; //五彩K线名字 {Name:'名字'} this.TradeIndex; //专家系统名字{Name:'名字'} + this.OverlayIndex=new Map(); //叠加指标 key=Identify value={ Data:数据, Title:标题, Identify:标识} this.FormatValue=function(value,item) { @@ -13136,6 +13408,83 @@ function DynamicChartTitlePainting() this.Canvas.fillText(this.TradeIndex.Name,left,bottom,textWidth); left+=textWidth; } + + this.DrawOverlayIndex(left); + } + + this.DrawOverlayIndex=function(left) //叠加指标标题 + { + var bottom=this.Frame.ChartBorder.GetTop()+this.Frame.ChartBorder.TitleHeight/2; //上下居中显示 + var right=this.Frame.ChartBorder.GetRight(); + if (left>right) return; + + var spaceWidth=5*GetDevicePixelRatio(); + var drawLeft=left; + for(item of this.OverlayIndex) + { + left+=spaceWidth; + overlayItem=item[1]; + if (overlayItem.Title) + { + this.Canvas.fillStyle=this.TitleColor; + var textWidth=this.Canvas.measureText(overlayItem.Title).width+2; + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(overlayItem.Title,drawLeft,bottom,textWidth); + } + + for(var i in overlayItem.Data) + { + var item=overlayItem.Data[i]; + if (!item || !item.Data || !item.Data.Data || !item.Name) continue; + if (item.Data.Data.length<=0) continue; + + var value=null; + var valueText=null; + if (item.DataType=="StraightLine") //直线只有1个数据 + { + value=item.Data.Data[0]; + valueText=this.FormatValue(value,item); + } + else + { + var index=Math.abs(this.CursorIndex-0.5); + index=parseInt(index.toFixed(0)); + var dataIndex=item.Data.DataOffset+index; + if (dataIndex>=item.Data.Data.length) dataIndex=item.Data.Data.length-1; + if (dataIndex<0) continue; + + value=item.Data.Data[dataIndex]; + if (value==null) continue; + + if (item.DataType=="HistoryData-Vol") + { + value=value.Vol; + valueText=this.FormatValue(value,item); + } + else if (item.DataType=="MultiReport") + { + valueText=this.FormatMultiReport(value,item); + } + else + { + valueText=this.FormatValue(value,item); + } + } + + this.Canvas.fillStyle=item.Color; + + var text=item.Name+":"+valueText; + var textWidth=this.Canvas.measureText(text).width+2; //后空2个像素 + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(text,drawLeft,bottom,textWidth); + } + + if (left>right) break; + } } this.HScreenDraw=function() @@ -16036,6 +16385,7 @@ function JSChartResource() this.FrameSplitTextColor="rgb(117,125,129)"; //刻度文字颜色 this.FrameSplitTextFont=14*GetDevicePixelRatio() +"px 微软雅黑"; //坐标刻度文字字体 this.FrameTitleBGColor="rgb(246,251,253)"; //标题栏背景色 + this.OverlayFrameBolderPen='rgb(190,190,190)' this.CorssCursorBGColor="rgb(43,54,69)"; //十字光标背景 this.CorssCursorTextColor="rgb(255,255,255)"; @@ -17567,7 +17917,6 @@ function KLineChartContainer(uielement) this.SetCustomShow(this.CustomShow,hisData); this.CustomShow=null; } - } this.UpdateMainData=function(hisData) @@ -17661,6 +18010,26 @@ function KLineChartContainer(uielement) this.WindowIndex[windowIndex].BindData(this,windowIndex,hisData); } + //叠加指标 + this.BindOverlayIndexData=function(overlayItem, windowIndex, hisData) + { + if (!overlayItem.Script) return; + + if (typeof(overlayItem.Script.RequestData)=='function') + { + overlayItem.Script.RequestData(this,windowIndex,hisData); + return; + } + + if (typeof(overlayItem.Script.ExecuteScript)=='function') + { + overlayItem.Script.ExecuteScript(this,windowIndex,hisData); + return; + } + + overlayItem.Script.BindData(this,windowIndex,hisData); + } + //执行指示(专家指示 五彩K线) this.BindInstructionIndexData=function(hisData) { @@ -17787,6 +18156,17 @@ function KLineChartContainer(uielement) this.Draw(); this.UpdatePointByCursorIndex(); //更新十字光标位子 + //叠加指标 + for(var i=0;i0) + { + var delOverlayIndexMenu={ text:'删除叠加指标', children:this.GetDeleteOverlayIndex(chart,overlayIndex) } + dataList.splice(3,0,delOverlayIndexMenu); + } + console.log('[KLineRightMenu::DoModal]',identify); rightMenu.Show({ windowIndex :identify, @@ -26560,6 +27060,36 @@ function KLineRightMenu(divElement) rightMenu.Hide(); }); } + + this.GetOverlayIndex=function(chart, windowsIndex) + { + if (windowsIndex>=chart.Frame.SubFrame.length) return []; + + var result=[]; + var item=chart.Frame.SubFrame[windowsIndex]; + for(var i in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[i]; + result.push({Name:overlayItem.Script.Name, Identify:overlayItem.Identify}); + } + + return result; + } + + this.GetDeleteOverlayIndex=function(chart,overlayIndex) + { + var data=[]; + for(var i in overlayIndex) + { + let identify=overlayIndex[i].Identify; + data.push({text:overlayIndex[i].Name, click:function() + { + chart.DeleteOverlayWindowsIndex(identify) + }}); + } + + return data; + } } //K线区间选择右键菜单 diff --git a/webhqchart.demo/jscommon/umychart.resource/font/iconfont.css b/webhqchart.demo/jscommon/umychart.resource/font/iconfont.css index d6b7f03d1d2c68e75a21902c30fc1ec2cde18fee..1cd07be6a0e0052a489aaeb6302ca2acf9bf2249 100644 --- a/webhqchart.demo/jscommon/umychart.resource/font/iconfont.css +++ b/webhqchart.demo/jscommon/umychart.resource/font/iconfont.css @@ -1,405 +1,425 @@ @font-face {font-family: "iconfont"; - src: url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.eot?t=1559700636847'); /* IE9 */ - src: url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.eot?t=1559700636847#iefix') format('embedded-opentype'), /* IE6-IE8 */ - url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), - url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.woff?t=1559700636847') format('woff'), - url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.ttf?t=1559700636847') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ - url('//at.alicdn.com/t/font_1040563_2a9nsb2skfw.svg?t=1559700636847#iconfont') format('svg'); /* iOS 4.1- */ - } - - .iconfont { - font-family: "iconfont" !important; - font-size: 16px; - font-style: normal; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - } - - .icon-drawicon_dollar:before { - content: "\e626"; - } - - .icon-arrow_left:before { - content: "\e680"; - } - - .icon-drawicon_message:before { - content: "\e64d"; - } - - .icon-drawicon_s:before { - content: "\e64c"; - } - - .icon-drawicon_b:before { - content: "\e70f"; - } - - .icon-drawicon_good:before { - content: "\e624"; - } - - .icon-drawicon_bad:before { - content: "\e600"; - } - - .icon-menu_arraw_right:before { - content: "\e60b"; - } - - .icon-menu_arraw_left:before { - content: "\e60d"; - } - - .icon-drawicon_up:before { - content: "\e625"; - } - - .icon-drawicon_close:before { - content: "\e68c"; - } - - .icon-draw_arc:before { - content: "\e602"; - } - - .icon-index_param:before { - content: "\e604"; - } - - .icon-draw_line:before { - content: "\e605"; - } - - .icon-draw_rays:before { - content: "\e606"; - } - - .icon-rectangle:before { - content: "\e607"; - } - - .icon-draw_parallel_lines:before { - content: "\e608"; - } - - .icon-setting:before { - content: "\e609"; - } - - .icon-recycle_bin:before { - content: "\e60a"; - } - - .icon-close:before { - content: "\e60c"; - } - - .icon-draw_trendline:before { - content: "\e60e"; - } - - .icon-draw_goldensection:before { - content: "\e60f"; - } - - .icon-draw_gannfan:before { - content: "\e610"; - } - - .icon-draw_percentage:before { - content: "\e611"; - } - - .icon-draw_waveband:before { - content: "\e612"; - } - - .icon-draw_resline:before { - content: "\e613"; - } - - .icon-draw_text:before { - content: "\e614"; - } - - .icon-draw_parallelchannel:before { - content: "\e615"; - } - - .icon-draw_wavemw:before { - content: "\e616"; - } - - .icon-chip_date:before { - content: "\e617"; - } - - .icon-draw_triangle:before { - content: "\e61a"; - } - - .icon-draw_pricechannel:before { - content: "\e61b"; - } - - .icon-draw_circle:before { - content: "\e61c"; - } - - .icon-draw_symangle:before { - content: "\e61d"; - } - - .icon-draw_hline:before { - content: "\e61e"; - } - - .icon-chip_default:before { - content: "\e621"; - } - - .icon-arrow_down:before { - content: "\e681"; - } - - .icon-arrow_right:before { - content: "\e682"; - } - - .icon-arrow_up:before { - content: "\e683"; - } - - .icon-draw_quadrangle:before { - content: "\e62c"; - } - - .icon-draw_fibonacci:before { - content: "\e62d"; - } - - .icon-right:before { - content: "\e601"; - } - - .icon-left:before { - content: "\e603"; - } - - .icon-xia:before { - content: "\e618"; - } - - .icon-shang:before { - content: "\e619"; - } - - .icon-jiacu:before { - content: "\e61f"; - } - - .icon-shezhi:before { - content: "\e620"; - } - - .icon-qingxieL:before { - content: "\e622"; - } - - .icon-info_pforecast:before { - content: "\e62e"; - } - - .icon-info_trade_detail:before { - content: "\e62f"; - } - - .icon-info_block_trading:before { - content: "\e630"; - } - - .icon-info_investor:before { - content: "\e631"; - } - - .icon-info_research:before { - content: "\e632"; - } - - .icon-info_announcement:before { - content: "\e633"; - } - - .icon-info_quarter_announcement:before { - content: "\e634"; - } - - .icon-info_num_11:before { - content: "\e635"; - } - - .icon-info_num_10:before { - content: "\e636"; - } - - .icon-info_num_12:before { - content: "\e637"; - } - - .icon-info_num_13:before { - content: "\e638"; - } - - .icon-info_num_14:before { - content: "\e639"; - } - - .icon-info_num_15:before { - content: "\e63a"; - } - - .icon-info_num_1:before { - content: "\e63b"; - } - - .icon-info_num_16:before { - content: "\e63c"; - } - - .icon-info_num_3:before { - content: "\e63d"; - } - - .icon-info_num_17:before { - content: "\e63e"; - } - - .icon-info_num_4:before { - content: "\e63f"; - } - - .icon-info_num_2:before { - content: "\e640"; - } - - .icon-info_num_6:before { - content: "\e641"; - } - - .icon-info_num_18:before { - content: "\e642"; - } - - .icon-info_num_20:before { - content: "\e643"; - } - - .icon-info_num_19:before { - content: "\e644"; - } - - .icon-info_num_5:before { - content: "\e645"; - } - - .icon-info_num_9:before { - content: "\e646"; - } - - .icon-info_num_7:before { - content: "\e647"; - } - - .icon-info_num_8:before { - content: "\e648"; - } - - .icon-info_num_more:before { - content: "\e649"; - } - - .icon-bianji:before { - content: "\e623"; - } - - .icon-info_investor_hscreen:before { - content: "\e684"; - } - - .icon-info_announcement-copy:before { - content: "\e685"; - } - - .icon-info_quarter_announcement-copy:before { - content: "\e686"; - } - - .icon-info_pforecast_hscreen:before { - content: "\e687"; - } - - .icon-info_research_hscreen:before { - content: "\e688"; - } - - .icon-info_block_trading_hscreen:before { - content: "\e689"; - } - - .icon-info_trade_detail_hscreen:before { - content: "\e68a"; - } - - .icon-kline_train_buy:before { - content: "\e64a"; - } - - .icon-kline_train_sell:before { - content: "\e64b"; - } - - .icon-drawicon_down-copy:before { - content: "\e68b"; - } - - .icon-drawicon_up2:before { - content: "\e68d"; - } - - .icon-drawicon_down2:before { - content: "\e68e"; - } - - .icon-hk:before { - content: "\e627"; - } - - .icon-shhk:before { - content: "\e628"; - } - - .icon-margin:before { - content: "\e629"; - } - - .icon-sousuo:before { - content: "\e62a"; - } - - .icon-guanbi:before { - content: "\e62b"; - } - - .icon-sub:before { - content: "\e64e"; - } - - .icon-add:before { - content: "\e64f"; - } - - .icon-refresh:before { - content: "\e650"; - } - \ No newline at end of file + src: url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.eot?t=1562863167659'); /* IE9 */ + src: url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.eot?t=1562863167659#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), + url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.woff?t=1562863167659') format('woff'), + url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.ttf?t=1562863167659') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ + url('//at.alicdn.com/t/font_1040563_ske42qg6e0n.svg?t=1562863167659#iconfont') format('svg'); /* iOS 4.1- */ +} + +.iconfont { + font-family: "iconfont" !important; + font-size: 16px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.icon-drawicon_dollar:before { + content: "\e626"; +} + +.icon-arrow_left:before { + content: "\e680"; +} + +.icon-overlay_index:before { + content: "\e655"; +} + +.icon-drawicon_message:before { + content: "\e64d"; +} + +.icon-drawicon_s:before { + content: "\e64c"; +} + +.icon-drawicon_b:before { + content: "\e70f"; +} + +.icon-drawicon_good:before { + content: "\e624"; +} + +.icon-drawicon_bad:before { + content: "\e600"; +} + +.icon-menu_arraw_right:before { + content: "\e60b"; +} + +.icon-menu_arraw_left:before { + content: "\e60d"; +} + +.icon-drawicon_up:before { + content: "\e625"; +} + +.icon-drawicon_close:before { + content: "\e68c"; +} + +.icon-change_index:before { + content: "\e656"; +} + +.icon-draw_arc:before { + content: "\e602"; +} + +.icon-index_param:before { + content: "\e604"; +} + +.icon-draw_line:before { + content: "\e605"; +} + +.icon-draw_rays:before { + content: "\e606"; +} + +.icon-rectangle:before { + content: "\e607"; +} + +.icon-draw_parallel_lines:before { + content: "\e608"; +} + +.icon-setting:before { + content: "\e609"; +} + +.icon-recycle_bin:before { + content: "\e60a"; +} + +.icon-close:before { + content: "\e60c"; +} + +.icon-draw_trendline:before { + content: "\e60e"; +} + +.icon-draw_goldensection:before { + content: "\e60f"; +} + +.icon-draw_gannfan:before { + content: "\e610"; +} + +.icon-draw_percentage:before { + content: "\e611"; +} + +.icon-draw_waveband:before { + content: "\e612"; +} + +.icon-draw_resline:before { + content: "\e613"; +} + +.icon-draw_text:before { + content: "\e614"; +} + +.icon-draw_parallelchannel:before { + content: "\e615"; +} + +.icon-draw_wavemw:before { + content: "\e616"; +} + +.icon-chip_date:before { + content: "\e617"; +} + +.icon-draw_triangle:before { + content: "\e61a"; +} + +.icon-draw_pricechannel:before { + content: "\e61b"; +} + +.icon-draw_circle:before { + content: "\e61c"; +} + +.icon-draw_symangle:before { + content: "\e61d"; +} + +.icon-draw_hline:before { + content: "\e61e"; +} + +.icon-chip_default:before { + content: "\e621"; +} + +.icon-arrow_down:before { + content: "\e681"; +} + +.icon-arrow_right:before { + content: "\e682"; +} + +.icon-arrow_up:before { + content: "\e683"; +} + +.icon-draw_quadrangle:before { + content: "\e62c"; +} + +.icon-draw_fibonacci:before { + content: "\e62d"; +} + +.icon-right:before { + content: "\e601"; +} + +.icon-left:before { + content: "\e603"; +} + +.icon-xia:before { + content: "\e618"; +} + +.icon-shang:before { + content: "\e619"; +} + +.icon-jiacu:before { + content: "\e61f"; +} + +.icon-shezhi:before { + content: "\e620"; +} + +.icon-qingxieL:before { + content: "\e622"; +} + +.icon-info_pforecast:before { + content: "\e62e"; +} + +.icon-info_trade_detail:before { + content: "\e62f"; +} + +.icon-info_block_trading:before { + content: "\e630"; +} + +.icon-info_investor:before { + content: "\e631"; +} + +.icon-info_research:before { + content: "\e632"; +} + +.icon-info_announcement:before { + content: "\e633"; +} + +.icon-info_quarter_announcement:before { + content: "\e634"; +} + +.icon-info_num_11:before { + content: "\e635"; +} + +.icon-info_num_10:before { + content: "\e636"; +} + +.icon-info_num_12:before { + content: "\e637"; +} + +.icon-info_num_13:before { + content: "\e638"; +} + +.icon-info_num_14:before { + content: "\e639"; +} + +.icon-info_num_15:before { + content: "\e63a"; +} + +.icon-info_num_1:before { + content: "\e63b"; +} + +.icon-info_num_16:before { + content: "\e63c"; +} + +.icon-info_num_3:before { + content: "\e63d"; +} + +.icon-info_num_17:before { + content: "\e63e"; +} + +.icon-info_num_4:before { + content: "\e63f"; +} + +.icon-info_num_2:before { + content: "\e640"; +} + +.icon-info_num_6:before { + content: "\e641"; +} + +.icon-info_num_18:before { + content: "\e642"; +} + +.icon-info_num_20:before { + content: "\e643"; +} + +.icon-info_num_19:before { + content: "\e644"; +} + +.icon-info_num_5:before { + content: "\e645"; +} + +.icon-info_num_9:before { + content: "\e646"; +} + +.icon-info_num_7:before { + content: "\e647"; +} + +.icon-info_num_8:before { + content: "\e648"; +} + +.icon-info_num_more:before { + content: "\e649"; +} + +.icon-bianji:before { + content: "\e623"; +} + +.icon-info_investor_hscreen:before { + content: "\e684"; +} + +.icon-info_announcement-copy:before { + content: "\e685"; +} + +.icon-info_quarter_announcement-copy:before { + content: "\e686"; +} + +.icon-info_pforecast_hscreen:before { + content: "\e687"; +} + +.icon-info_research_hscreen:before { + content: "\e688"; +} + +.icon-info_block_trading_hscreen:before { + content: "\e689"; +} + +.icon-info_trade_detail_hscreen:before { + content: "\e68a"; +} + +.icon-kline_train_buy:before { + content: "\e64a"; +} + +.icon-kline_train_sell:before { + content: "\e64b"; +} + +.icon-drawicon_down-copy:before { + content: "\e68b"; +} + +.icon-drawicon_up2:before { + content: "\e68d"; +} + +.icon-drawicon_down2:before { + content: "\e68e"; +} + +.icon-hk:before { + content: "\e627"; +} + +.icon-shhk:before { + content: "\e628"; +} + +.icon-margin:before { + content: "\e629"; +} + +.icon-sousuo:before { + content: "\e62a"; +} + +.icon-guanbi:before { + content: "\e62b"; +} + +.icon-sub:before { + content: "\e64e"; +} + +.icon-add:before { + content: "\e64f"; +} + +.icon-refresh:before { + content: "\e650"; +} + +.icon-houtui:before { + content: "\e651"; +} + +.icon-qianjin:before { + content: "\e652"; +} + +.icon-exit:before { + content: "\e653"; +} + diff --git a/webhqchart/umychart.complier.js b/webhqchart/umychart.complier.js index b66ff4c557971521dfd25c61d39e8c99e8b8c6aa..f1c62d5f4462de228ac459039a91db3611b9d054 100644 --- a/webhqchart/umychart.complier.js +++ b/webhqchart/umychart.complier.js @@ -9073,7 +9073,7 @@ function ScriptIndex(name,script,args,option) return; } - //清空指标图形 + //清空主指标图形 hqChart.DeleteIndexPaint(windowIndex); if (windowIndex==0) hqChart.ShowKLine(true); @@ -9232,6 +9232,595 @@ function ScriptIndex(name,script,args,option) } } +function OverlayScriptIndex(name,script,args,option) +{ + this.newMethod=ScriptIndex; //派生 + this.newMethod(name,script,args,option); + delete this.newMethod; + + //叠加指标 + this.OverlayIndex=null; // { IsOverlay:true, Identify:overlayFrame.Identify, WindowIndex:windowIndex, Frame:overlayFrame } + + this.BindData=function(hqChart,windowIndex,hisData) + { + if (!this.OverlayIndex || this.OverlayIndex.IsOverlay!=true) return; + + this.OverlayIndex.Frame.ChartPaint=[]; + if (this.OutVar==null || this.OutVar.length<0) return; + + /*叠加一个K线背景 + if (this.KLineType!=null) + { + if (this.KLineType===0 || this.KLineType===1 || this.KLineType===2) this.CreateSelfKLine(hqChart,windowIndex,hisData); + else if (this.KLineType===-1 && windowIndex==0) hqChart.ShowKLine(false); + } + + if (windowIndex>=1 && hqChart.Frame) + { + hqChart.Frame.SubFrame[windowIndex].Frame.YSplitOperator.FloatPrecision=this.FloatPrecision; + if (this.YSpecificMaxMin) hqChart.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin=this.YSpecificMaxMin; //最大最小值 + if (this.YSplitScale) hqChart.Frame.SubFrame[windowIndex].Frame.YSplitScale=this.YSplitScale; //固定刻度 + } + */ + + //指标名字 + var titleInfo={ Data:[], Title:this.Name }; + let indexParam=''; + for(var i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + if (indexParam.length>0) titleInfo.Title=this.Name+'('+indexParam+')'; + + var titleIndex=windowIndex+1; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.set(this.OverlayIndex.Identify,titleInfo); + + for(var i in this.OutVar) + { + let item=this.OutVar[i]; + if (item.IsExData===true) continue; //扩展数据不显示图形 + + if (item.Type==0) + { + this.CreateLine(hqChart,windowIndex,item,i); + } + else if (item.Type==1) + { + switch(item.Draw.DrawType) + { + case 'STICKLINE': + this.CreateBar(hqChart,windowIndex,item,i); + break; + case 'DRAWTEXT': + case 'SUPERDRAWTEXT': + this.CreateText(hqChart,windowIndex,item,i); + break; + case 'DRAWLINE': + this.CreateStraightLine(hqChart,windowIndex,item,i); + break; + case 'DRAWBAND': + this.CreateBand(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'DRAWKLINE_IF': + this.CreateKLine(hqChart,windowIndex,item,i); + break; + case 'POLYLINE': + this.CreatePolyLine(hqChart,windowIndex,item,i); + break; + case 'DRAWNUMBER': + this.CreateNumberText(hqChart,windowIndex,item,i); + break; + case 'DRAWICON': + this.CreateIcon(hqChart,windowIndex,item,i); + break; + case 'DRAWCHANNEL': + this.CreateChannel(hqChart,windowIndex,item,i); + break; + } + } + else if (item.Type==2) + { + this.CreateMACD(hqChart,windowIndex,item,i); + } + else if (item.Type==3) + { + this.CreatePointDot(hqChart,windowIndex,item,i); + } + else if (item.Type==4) + { + this.CreateLineStick(hqChart,windowIndex,item,i); + } + else if (item.Type==5) + { + this.CreateStick(hqChart,windowIndex,item,i); + } + else if (item.Type==6) + { + this.CreateVolStick(hqChart,windowIndex,item,i,hisData); + } + } + + + /* + hqChart.TitlePaint[titleIndex].Title=this.Name; + + let indexParam=''; + for(let i in this.Arguments) + { + let item=this.Arguments[i]; + if (indexParam.length>0) indexParam+=','; + indexParam+=item.Value.toString(); + } + + if (indexParam.length>0) hqChart.TitlePaint[titleIndex].Title=this.Name+'('+indexParam+')'; + */ + + return true; + } + + //指标执行完成 + this.RecvResultData=function(outVar,param) + { + let hqChart=param.HQChart; + let windowIndex=param.WindowIndex; + let hisData=param.HistoryData; + param.Self.OutVar=outVar; + param.Self.BindData(hqChart,windowIndex,hisData); + + param.HQChart.UpdataDataoffset(); //更新数据偏移 + param.HQChart.UpdateFrameMaxMin(); //调整坐标最大 最小值 + param.HQChart.Draw(); + + var event=hqChart.GetOverlayIndexEvent(); //指标计算完成回调 + if (event) + { + var self=param.Self; + var data={ OutVar:self.OutVar, WindowIndex: windowIndex, Name: self.Name, Arguments: self.Arguments, HistoryData: hisData, + Identify:self.OverlayIndex.Identify, + Stock: {Symbol:hqChart.Symbol,Name:hqChart.Name} }; + event.Callback(event,data,self); + } + } + + ////////////////////////////////////////////////////////////////////////////////////// + // 图形创建 + ///////////////////////////////////////////////////////////////////////////////////// + + this.CreateLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.DrawType=1; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) line.LineWidth=width; + } + + if (varItem.IsShow==false) line.IsShow=false; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + //创建柱子 + this.CreateBar=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStickLine(); + chart.Canvas=hqChart.Canvas; + if (varItem.Draw.Width>0) chart.LineWidth=varItem.Draw.Width; + else chart.LineWidth=1; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建文本 + this.CreateText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + chart.Text=varItem.Draw.Text; + if (varItem.Draw.Direction>0) chart.Direction=varItem.Draw.Direction; + if (varItem.Draw.YOffset>0) chart.YOffset=varItem.Draw.YOffset; + if (varItem.Draw.TextAlign) chart.TextAlign=varItem.Draw.TextAlign; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //COLORSTICK + this.CreateMACD=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartMACD(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,this.GetDefaultColor(id)); + + frame.ChartPaint.push(chart); + } + + this.CreatePointDot=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartPointDot(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.Radius) chart.Radius=varItem.Radius; + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.Radius=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateLineStick=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLineStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateStraightLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.DrawType=1; + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(line.Data,varItem.Name,line.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateVolStick=function(hqChart,windowIndex,varItem,id,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartVolStick(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + chart.KLineDrawType=hqChart.KLineDrawType; //设置K线显示类型 + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Data; + chart.HistoryData=hisData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(chart.Data,varItem.Name,chart.Color); + + frame.ChartPaint.push(chart); + } + + this.CreateBand=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartBand(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.FirstColor = varItem.Draw.Color[0]; + chart.SecondColor = varItem.Draw.Color[1]; + chart.Data.Data=varItem.Draw.DrawData; + + frame.ChartPaint.push(chart); + } + + //创建K线图 + this.CreateKLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data.Data=varItem.Draw.DrawData; + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + + if (varItem.Color) //如果设置了颜色,使用外面设置的颜色 + chart.UnchagneColor=chart.DownColor=chart.UpColor=this.GetColor(varItem.Color); + + frame.ChartPaint.push(chart); + } + + this.CreatePolyLine=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartLine(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + if (varItem.LineWidth) + { + let width=parseInt(varItem.LineWidth.replace("LINETHICK","")); + if (!isNaN(width) && width>0) chart.LineWidth=width; + } + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var titlePaint=hqChart.TitlePaint[titleIndex]; + titlePaint.OverlayIndex.get(overlayIndex.Identify).Data[id]=new DynamicTitleData(line.Data,' ',line.Color); //给一个空的标题 + + frame.ChartPaint.push(chart); + } + + this.CreateNumberText=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else chart.Color=this.GetDefaultColor(id); + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData.Value; + chart.Text=varItem.Draw.DrawData.Text; + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建图标 + this.CreateIcon=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartSingleText(); + chart.Canvas=hqChart.Canvas; + chart.TextAlign='center'; + + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + var icon=varItem.Draw.Icon; + if (icon.IconFont==true) + { + chart.IconFont={ Family:icon.Family, Text:icon.Symbol, Color:icon.Color }; + } + else + { + chart.Text=icon.Symbol; + if (varItem.Color) chart.Color=this.GetColor(varItem.Color); + else if (icon.Color) chart.Color=icon.Color; + else chart.Color='rgb(0,0,0)'; + } + + //hqChart.TitlePaint[titleIndex].Data[id]=new DynamicTitleData(bar.Data,varItem.Name,bar.Color); + + frame.ChartPaint.push(chart); + } + + //创建通道 + this.CreateChannel=function(hqChart,windowIndex,varItem,id) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartChannel(); + chart.Canvas=hqChart.Canvas; + chart.Name=varItem.Name; + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + if(varItem.Draw.AreaColor) chart.AreaColor=varItem.Draw.AreaColor; + else if (varItem.Color) chart.AreaColor=this.GetColor(varItem.Color); + else chart.AreaColor=this.GetDefaultColor(id); + + if (varItem.Draw.Border.Color) chart.LineColor=varItem.Draw.Border.Color; + else chart.LineColor=null; + + if (varItem.Draw.Border.Dotted) chart.LineDotted=varItem.Draw.Border.Dotted; + if (varItem.Draw.Border.Width>0) chart.LineWidth=varItem.Draw.Border.Width; + + //let titleIndex=windowIndex+1; + chart.Data.Data=varItem.Draw.DrawData; + frame.ChartPaint.push(chart); + } + + //创建K线 + this.CreateSelfKLine=function(hqChart,windowIndex,hisData) + { + var overlayIndex=this.OverlayIndex; + var frame=overlayIndex.Frame; + let chart=new ChartKLine(); + chart.Canvas=hqChart.Canvas; + chart.Name="Self Kline" + chart.ChartBorder=frame.Frame.ChartBorder; + chart.ChartFrame=frame.Frame; + chart.Identify=overlayIndex.Identify; + + chart.Data=hisData + chart.IsShowMaxMinPrice=false; + chart.IsShowKTooltip=false; + chart.DrawType=this.KLineType; + + frame.ChartPaint.push(chart); + } + + //给一个默认的颜色 + this.GetDefaultColor=function(id) + { + let COLOR_ARRAY= + [ + "rgb(24,71,178)", + "rgb(42,230,215)", + "rgb(252,96,154)", + "rgb(0,128,255)", + "rgb(229,0,79)", + "rgb(68,114,196)", + "rgb(255,174,0)", + "rgb(25,199,255)", + "rgb(175,95,162)", + "rgb(236,105,65)", + ]; + + let number=parseInt(id); + return COLOR_ARRAY[number%(COLOR_ARRAY.length-1)]; + } +} + //后台执行指标 function APIScriptIndex(name,script,args,option) { diff --git a/webhqchart/umychart.index.data.js b/webhqchart/umychart.index.data.js index b763756175595584c7b3b013b622b8d64f821e1b..367a0f82cc96074a2dfb1eb4afd8f4ae4dac3c7f 100644 --- a/webhqchart/umychart.index.data.js +++ b/webhqchart/umychart.index.data.js @@ -43,7 +43,7 @@ function JSIndexScript() ['DMI', this.DMI],['CR', this.CR],['PSY', this.PSY], ['CCI', this.CCI],['DMA', this.DMA],['TRIX', this.TRIX], ['VR', this.VR],['EMV', this.EMV],['ROC', this.ROC], - ['MTM', this.MIM],['FSL', this.FSL],['CYR', this.CYR], + ['MTM', this.MTM],['FSL', this.FSL],['CYR', this.CYR], ['MASS', this.MASS],['WAD', this.WAD],['CHO', this.CHO], ['ADTM', this.ADTM],['HSL', this.HSL],['BIAS36', this.BIAS36], ['BIAS_QL', this.BIAS_QL],['DPO', this.DPO],['OSC', this.OSC], diff --git a/webhqchart/umychart.js b/webhqchart/umychart.js index 75ac9bad18c6e130911e13ef36b424ae0dbebe94..f0da77903fd26961a1627a224636bca511f824d8 100644 --- a/webhqchart/umychart.js +++ b/webhqchart/umychart.js @@ -245,9 +245,19 @@ function JSChart(divElement) if (item.Modify!=null) chart.Frame.SubFrame[i].Frame.ModifyIndex=item.Modify; if (item.Change!=null) chart.Frame.SubFrame[i].Frame.ChangeIndex=item.Change; if (item.Close!=null) chart.Frame.SubFrame[i].Frame.CloseIndex=item.Close; + if (item.Overlay!=null) chart.Frame.SubFrame[i].Frame.OverlayIndex=item.Overlay; if (!isNaN(item.TitleHeight)) chart.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight=item.TitleHeight; } + + //叠加指标 + for (var i in option.OverlayIndex) + { + var item=option.OverlayIndex[i]; + if (item.Windows>=chart.Frame.SubFrame.length) continue; + chart.CreateOverlayWindowsIndex(item.Windows,item.Index); + } + this.AdjustTitleHeight(chart); return chart; @@ -1012,6 +1022,7 @@ var JSCHART_EVENT_ID= RECV_TRAIN_MOVE_STEP:4, //接收K线训练,移动一次K线 CHART_STATUS:5, //每次Draw() 以后会调用 BARRAGE_PLAY_END:6, //单个弹幕播放完成 + RECV_OVERLAY_INDEX_DATA:7,//接收叠加指标数据 } var JSCHART_OPERATOR_ID= @@ -1100,13 +1111,22 @@ function JSChartContainer(uielement) this.mapEvent.delete(eventid); } + this.GetEventCallback=function(id) //获取事件回调 + { + if (!this.mapEvent.has(id)) return null; + var item=this.mapEvent.get(id); + return item; + } + //接收指标数据 this.GetIndexEvent=function() { - if (!this.mapEvent.has(JSCHART_EVENT_ID.RECV_INDEX_DATA)) return null; + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_INDEX_DATA); + } - var item=this.mapEvent.get(JSCHART_EVENT_ID.RECV_INDEX_DATA); - return item; + this.GetOverlayIndexEvent=function() + { + return this.GetEventCallback(JSCHART_EVENT_ID.RECV_OVERLAY_INDEX_DATA); } uielement.onmousemove=function(e) @@ -1603,6 +1623,8 @@ function JSChartContainer(uielement) item.Draw(); } + this.Frame.DrawOveraly(); //画叠加指标 + //固定扩展图形 for(var i in this.ExtendChartPaint) { @@ -2189,6 +2211,17 @@ function JSChartContainer(uielement) } item.Frame.XYSplit=true; } + + //更新子坐标 + for(var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + overlayItem.UpdateFrameMaxMin(); + } + } } this.DataMoveLeft=function() @@ -2243,6 +2276,23 @@ function JSChartContainer(uielement) if (!item.Data) continue; item.Data.DataOffset=data.DataOffset; } + + //叠加指标当前显示的数据偏移 + for (var i in this.Frame.SubFrame) + { + var subFrame=this.Frame.SubFrame[i]; + for(var j in subFrame.OverlayIndex) + { + var overlayItem=subFrame.OverlayIndex[j]; + for(var k in overlayItem.ChartPaint) + { + var item=overlayItem.ChartPaint[k]; + if (!item.Data) continue; + item.Data.DataOffset=data.DataOffset; + } + } + } + } this.DataMove=function(step,isLeft) @@ -2384,7 +2434,7 @@ function JSChartContainer(uielement) if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash) return null; // 数据加载中不能保存 console.log('[JSChartContainer::SaveToImage]', this.UIElement); - clrBG='rgb(255,255,255)'; + var clrBG='rgb(255,255,255)'; if (colorGB) clrBG=colorGB; this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height); this.Canvas.fillStyle=clrBG; @@ -3416,6 +3466,7 @@ function KLineFrame() this.ModifyIndex=true; //是否显示'改参数'菜单 this.ChangeIndex=true; //是否显示'换指标'菜单 this.CloseIndex=true; //是否显示'关闭指标窗口'菜单 + this.OverlayIndex=false; //是否显示叠加指标 this.ModifyIndexEvent; //改参数 点击事件 this.ChangeIndexEvent; //换指标 点击事件 @@ -3433,7 +3484,7 @@ function KLineFrame() this.ChartBorder.UIElement.parentNode.appendChild(divToolbar); } - if (!this.ModifyIndex && !this.ChangeIndex) + if (!this.ModifyIndex && !this.ChangeIndex && !this.OverlayIndex) { divToolbar.style.display='none'; return; @@ -3450,7 +3501,8 @@ function KLineFrame() var left=chartWidth-(this.ChartBorder.Right/pixelTatio)-toolbarWidth; var top=this.ChartBorder.GetTop()/pixelTatio; var spanIcon = "  " + - ""; + "  " + + ""; if (this.Identify!==0 && this.CloseIndex) //第1个窗口不能关闭 { @@ -3479,13 +3531,32 @@ function KLineFrame() },this.ModifyIndexEvent); if (!this.ChangeIndex) //隐藏'换指标' + { $("#"+divToolbar.id+" .index_change").hide(); + } else if (typeof(this.ChangeIndexEvent)=='function') + { $("#"+divToolbar.id+" .index_change").click( { Chart:this.ChartBorder.UIElement.JSChartContainer, - Identify:this.Identify + Identify:this.Identify, + IsOverlay:false + },this.ChangeIndexEvent); + } + + if (!this.OverlayIndex) + { + $("#"+divToolbar.id+" .index_overlay").hide(); + } + else + { + $("#"+divToolbar.id+" .index_overlay").click( + { + Chart:this.ChartBorder.UIElement.JSChartContainer, + Identify:this.Identify, + IsOverlay:true },this.ChangeIndexEvent); + } $("#"+divToolbar.id+" .index_close").click( { @@ -3724,6 +3795,93 @@ function KLineFrame() } } +function OverlayKLineFrame() +{ + this.newMethod=KLineFrame; //派生 + this.newMethod(); + delete this.newMethod; + + this.MainFrame=null; //主框架 + this.RightOffset=50; + this.PenBorder=g_JSChartResource.OverlayFrameBolderPen; //'rgb(0,0,0)' + + this.Draw=function() + { + this.SplitXYCoordinate(); + + this.DrawVertical(); + this.DrawHorizontal(); + + this.SizeChange=false; + this.XYSplit=false; + } + + //分割x,y轴坐标信息 + this.SplitXYCoordinate=function() + { + if (this.XYSplit==false) return; + if (this.YSplitOperator!=null) this.YSplitOperator.Operator(); + // if (this.XSplitOperator!=null) this.XSplitOperator.Operator(); 子坐标和主坐标X轴一致 所以不用计算 + } + + //画Y轴 + this.DrawHorizontal=function() + { + var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom = this.ChartBorder.GetBottom(); + var top = this.ChartBorder.GetTopTitle(); + var borderRight=this.ChartBorder.Right; + right+=this.RightOffset; + + var yPrev=null; //上一个坐标y的值 + for(var i=this.HorizontalInfo.length-1; i>=0; --i) //从上往下画分割线 + { + var item=this.HorizontalInfo[i]; + var y=this.GetYFromData(item.Value); + if (y!=null && Math.abs(y-yPrev)= bottom - 2) this.Canvas.textBaseline = 'bottom'; + else if (y <= top + 2) this.Canvas.textBaseline = 'top'; + else this.Canvas.textBaseline = "middle"; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(right-5,ToFixedPoint(y)); + this.Canvas.lineTo(right,ToFixedPoint(y)); + this.Canvas.stroke(); + + //坐标信息 右边 间距小于10 不画坐标 + if (item.Message[1]!=null && borderRight>10) + { + if (item.Font!=null) this.Canvas.font=item.Font; + + this.Canvas.fillStyle=item.TextColor; + this.Canvas.textAlign="left"; + this.Canvas.fillText(item.Message[1],right+2,y); + } + + yPrev=y; + } + } + + //画X轴 + this.DrawVertical=function() + { + var top=this.ChartBorder.GetTopEx(); + //var left=this.ChartBorder.GetLeft(); + var right=this.ChartBorder.GetRight(); + var bottom=this.ChartBorder.GetBottomEx(); + right+=this.RightOffset; + + this.Canvas.strokeStyle=this.PenBorder; + this.Canvas.beginPath(); + this.Canvas.moveTo(ToFixedPoint(right),ToFixedPoint(top)); + this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(bottom)); + this.Canvas.stroke(); + } +} + //K线横屏框架 function KLineHScreenFrame() { @@ -4005,6 +4163,36 @@ function SubFrameItem() { this.Frame; this.Height; + this.OverlayIndex=[]; //叠加指标 + this.Interval=50; //子坐标间间距 +} + +function OverlayIndexItem() +{ + this.Frame; + this.ChartPaint=[]; + this.Identify=Guid(); + this.Scprit; //脚本 + + this.UpdateFrameMaxMin=function() //调整坐标最大 最小值 + { + var value={Max:null, Min:null} + for(var i in this.ChartPaint) + { + var paint=this.ChartPaint[i]; + var range=paint.GetMaxMin(); + + if (value.Max==null || value.Maxrange.Min) value.Min=range.Min + } + + if (value.Max!=null && value.Min!=null) + { + this.Frame.HorizontalMax=value.Max; + this.Frame.HorizontalMin=value.Min; + this.Frame.XYSplit=true; + } + } } //行情框架 @@ -4053,10 +4241,41 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.Draw(); + + var rightOffset=item.Interval; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + //把主坐标部分设置给子坐标下来 + overlayItem.Frame.DataWidth=item.Frame.DataWidth; + overlayItem.Frame.DistanceWidth=item.Frame.DistanceWidth; + overlayItem.Frame.XPointCount=item.Frame.XPointCount; + if (overlayItem.ChartPaint.length>0) + overlayItem.Frame.RightOffset=rightOffset; + overlayItem.Frame.Draw(); + rightOffset+=item.Interval; + } } this.SizeChange=false; } + + this.DrawOveraly=function() + { + for(var i in this.SubFrame) + { + var item=this.SubFrame[i]; + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + for(k in overlayItem.ChartPaint) + { + overlayItem.ChartPaint[k].Draw(); + } + } + } + } + this.DrawLock=function() { for (var i in this.SubFrame) @@ -4083,6 +4302,12 @@ function HQTradeFrame() { var item=this.SubFrame[i]; item.Frame.SizeChange=sizeChange; + + for(j in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[j]; + if (overlayItem.Frame) overlayItem.Frame.SizeChange=sizeChange; + } } //画布的位置 @@ -4163,12 +4388,26 @@ function HQTradeFrame() this.ZoomUp=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomUp(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -4177,12 +4416,26 @@ function HQTradeFrame() this.ZoomDown=function(cursorIndex) { var result=this.SubFrame[0].Frame.ZoomDown(cursorIndex); - for(var i=1;i0) //第1个窗口主坐标已经算好了 + { + item.Frame.XPointCount= mainFrame.XPointCount; + item.Frame.ZoomIndex= mainFrame.ZoomIndex; + item.Frame.DataWidth= mainFrame.DataWidth; + item.Frame.DistanceWidth= mainFrame.DistanceWidth; + } + + for(var j in item.OverlayIndex) + { + var overlayItem=this.SubFrame[i].OverlayIndex[j]; + overlayItem.Frame.XPointCount= mainFrame.XPointCount; + overlayItem.Frame.ZoomIndex= mainFrame.ZoomIndex; + overlayItem.Frame.DataWidth= mainFrame.DataWidth; + overlayItem.Frame.DistanceWidth= mainFrame.DistanceWidth; + } } return result; @@ -5474,6 +5727,7 @@ function ChartKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartKLine'; //类名 this.Symbol; //股票代码 this.DrawType=0; // 0=实心K线柱子 1=收盘价线 2=美国线 3=空心K线柱子 this.CloseLineColor=g_JSChartResource.CloseLineColor; @@ -6522,10 +6776,10 @@ function ChartOverlayKLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartOverlayKLine'; //类名 this.Color="rgb(65,105,225)"; this.MainData; //主图K线数据 this.SourceData; //叠加的原始数据 - this.Name="ChartOverlayKLine"; this.Title; this.DrawType=0; @@ -6993,6 +7247,7 @@ function ChartMinuteVolumBar() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinuteVolumBar'; //类名 this.UpColor = g_JSChartResource.UpBarColor; this.DownColor = g_JSChartResource.DownBarColor; this.YClose; //前收盘 @@ -7072,6 +7327,7 @@ function ChartLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth; //线段宽度 this.DrawType=0; //画图方式 0=无效数平滑 1=无效数不画断开 @@ -7202,6 +7458,7 @@ function ChartPointDot() this.newMethod(); delete this.newMethod; + this.ClassName='ChartPointDot'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Radius=1; //点半径 @@ -7583,6 +7840,7 @@ function ChartLineMultiData() this.newMethod(); delete this.newMethod; + this.ClassName='ChartLineMultiData'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -7676,6 +7934,7 @@ function ChartStickLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStickLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.LineWidth=2*GetDevicePixelRatio(); //线段宽度 @@ -7826,6 +8085,7 @@ function ChartText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartText'; //类名 this.TextFont="14px 微软雅黑"; this.Draw=function() @@ -7906,6 +8166,7 @@ function ChartSingleText() this.newMethod(); delete this.newMethod; + this.ClassName='ChartSingleText'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.TextFont="14px 微软雅黑"; //线段宽度 this.Text; @@ -8079,6 +8340,7 @@ function ChartStraightLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightLine'; //类名 this.Color="rgb(255,193,37)"; //线段颜色 this.Draw=function() @@ -8135,6 +8397,7 @@ function ChartStraightArea() this.newMethod(); delete this.newMethod; + this.ClassName='ChartStraightArea'; //类名 this.Color = "rgb(255,193,37)"; //线段颜色 this.Font ='11px 微软雅黑'; @@ -8265,6 +8528,7 @@ function ChartMinutePriceLine() this.newMethod(); delete this.newMethod; + this.ClassName='ChartMinutePriceLine'; //类名 this.YClose; this.IsDrawArea=true; //是否画价格面积图 this.AreaColor='rgba(0,191,255,0.1)'; @@ -8441,7 +8705,7 @@ function ChartOverlayMinutePriceLine() this.MainData; //主图数据 this.MainYClose; //主图股票的前收盘价 - this.Name="ChartOverlayMinutePriceLine"; + this.ClassName="ChartOverlayMinutePriceLine"; this.Title; this.Symbol; //叠加的股票代码 this.YClose; //叠加的股票前收盘 @@ -8543,6 +8807,7 @@ function ChartMACD() this.newMethod(); delete this.newMethod; + this.ClassName="ChartMACD"; this.UpColor=g_JSChartResource.UpBarColor; this.DownColor=g_JSChartResource.DownBarColor; @@ -8626,6 +8891,7 @@ function ChartBar() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBar"; this.UpBarColor=g_JSChartResource.UpBarColor; this.DownBarColor=g_JSChartResource.DownBarColor; @@ -8721,6 +8987,7 @@ function ChartBand() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartBand"; this.FirstColor = g_JSChartResource.Index.LineColor[0]; this.SecondColor = g_JSChartResource.Index.LineColor[1]; @@ -8828,6 +9095,7 @@ function ChartChannel() delete this.newMethod; this.IsDrawFirst = true; + this.ClassName="ChartChannel"; this.IsHScreen=false; //是否是横屏 this.PointCount=0; this.DataWidth=0; @@ -8989,6 +9257,8 @@ function ChartLock() this.newMethod=IChartPainting; //派生 this.newMethod(); delete this.newMethod; + + this.ClassName="ChartLock"; this.WidthDiv = 0.2; // 框子宽度占比 this.LockCount = 20; // 锁最新的几个数据 this.BGColor = g_JSChartResource.LockBGColor; @@ -9133,6 +9403,7 @@ function ChartBuySell() this.newMethod(); delete this.newMethod; + this.ClassName="ChartBuySell"; this.TextFont=g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体 this.LastDataIcon=g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'}; this.BuyIcon=g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'}; @@ -12986,6 +13257,7 @@ function DynamicChartTitlePainting() this.Explain; this.ColorIndex; //五彩K线名字 {Name:'名字'} this.TradeIndex; //专家系统名字{Name:'名字'} + this.OverlayIndex=new Map(); //叠加指标 key=Identify value={ Data:数据, Title:标题, Identify:标识} this.FormatValue=function(value,item) { @@ -13136,6 +13408,83 @@ function DynamicChartTitlePainting() this.Canvas.fillText(this.TradeIndex.Name,left,bottom,textWidth); left+=textWidth; } + + this.DrawOverlayIndex(left); + } + + this.DrawOverlayIndex=function(left) //叠加指标标题 + { + var bottom=this.Frame.ChartBorder.GetTop()+this.Frame.ChartBorder.TitleHeight/2; //上下居中显示 + var right=this.Frame.ChartBorder.GetRight(); + if (left>right) return; + + var spaceWidth=5*GetDevicePixelRatio(); + var drawLeft=left; + for(item of this.OverlayIndex) + { + left+=spaceWidth; + overlayItem=item[1]; + if (overlayItem.Title) + { + this.Canvas.fillStyle=this.TitleColor; + var textWidth=this.Canvas.measureText(overlayItem.Title).width+2; + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(overlayItem.Title,drawLeft,bottom,textWidth); + } + + for(var i in overlayItem.Data) + { + var item=overlayItem.Data[i]; + if (!item || !item.Data || !item.Data.Data || !item.Name) continue; + if (item.Data.Data.length<=0) continue; + + var value=null; + var valueText=null; + if (item.DataType=="StraightLine") //直线只有1个数据 + { + value=item.Data.Data[0]; + valueText=this.FormatValue(value,item); + } + else + { + var index=Math.abs(this.CursorIndex-0.5); + index=parseInt(index.toFixed(0)); + var dataIndex=item.Data.DataOffset+index; + if (dataIndex>=item.Data.Data.length) dataIndex=item.Data.Data.length-1; + if (dataIndex<0) continue; + + value=item.Data.Data[dataIndex]; + if (value==null) continue; + + if (item.DataType=="HistoryData-Vol") + { + value=value.Vol; + valueText=this.FormatValue(value,item); + } + else if (item.DataType=="MultiReport") + { + valueText=this.FormatMultiReport(value,item); + } + else + { + valueText=this.FormatValue(value,item); + } + } + + this.Canvas.fillStyle=item.Color; + + var text=item.Name+":"+valueText; + var textWidth=this.Canvas.measureText(text).width+2; //后空2个像素 + drawLeft=left; + left+=textWidth; + if (left>right) break; + this.Canvas.fillText(text,drawLeft,bottom,textWidth); + } + + if (left>right) break; + } } this.HScreenDraw=function() @@ -16036,6 +16385,7 @@ function JSChartResource() this.FrameSplitTextColor="rgb(117,125,129)"; //刻度文字颜色 this.FrameSplitTextFont=14*GetDevicePixelRatio() +"px 微软雅黑"; //坐标刻度文字字体 this.FrameTitleBGColor="rgb(246,251,253)"; //标题栏背景色 + this.OverlayFrameBolderPen='rgb(190,190,190)' this.CorssCursorBGColor="rgb(43,54,69)"; //十字光标背景 this.CorssCursorTextColor="rgb(255,255,255)"; @@ -17567,7 +17917,6 @@ function KLineChartContainer(uielement) this.SetCustomShow(this.CustomShow,hisData); this.CustomShow=null; } - } this.UpdateMainData=function(hisData) @@ -17661,6 +18010,26 @@ function KLineChartContainer(uielement) this.WindowIndex[windowIndex].BindData(this,windowIndex,hisData); } + //叠加指标 + this.BindOverlayIndexData=function(overlayItem, windowIndex, hisData) + { + if (!overlayItem.Script) return; + + if (typeof(overlayItem.Script.RequestData)=='function') + { + overlayItem.Script.RequestData(this,windowIndex,hisData); + return; + } + + if (typeof(overlayItem.Script.ExecuteScript)=='function') + { + overlayItem.Script.ExecuteScript(this,windowIndex,hisData); + return; + } + + overlayItem.Script.BindData(this,windowIndex,hisData); + } + //执行指示(专家指示 五彩K线) this.BindInstructionIndexData=function(hisData) { @@ -17787,6 +18156,17 @@ function KLineChartContainer(uielement) this.Draw(); this.UpdatePointByCursorIndex(); //更新十字光标位子 + //叠加指标 + for(var i=0;i0) + { + var delOverlayIndexMenu={ text:'删除叠加指标', children:this.GetDeleteOverlayIndex(chart,overlayIndex) } + dataList.splice(3,0,delOverlayIndexMenu); + } + console.log('[KLineRightMenu::DoModal]',identify); rightMenu.Show({ windowIndex :identify, @@ -26560,6 +27060,36 @@ function KLineRightMenu(divElement) rightMenu.Hide(); }); } + + this.GetOverlayIndex=function(chart, windowsIndex) + { + if (windowsIndex>=chart.Frame.SubFrame.length) return []; + + var result=[]; + var item=chart.Frame.SubFrame[windowsIndex]; + for(var i in item.OverlayIndex) + { + var overlayItem=item.OverlayIndex[i]; + result.push({Name:overlayItem.Script.Name, Identify:overlayItem.Identify}); + } + + return result; + } + + this.GetDeleteOverlayIndex=function(chart,overlayIndex) + { + var data=[]; + for(var i in overlayIndex) + { + let identify=overlayIndex[i].Identify; + data.push({text:overlayIndex[i].Name, click:function() + { + chart.DeleteOverlayWindowsIndex(identify) + }}); + } + + return data; + } } //K线区间选择右键菜单