You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3179 lines
111 KiB

  1. /*
  2. copyright (c) 2018 jones
  3. http://www.apache.org/licenses/LICENSE-2.0
  4. 开源项目 https://github.com/jones2000/HQChart
  5. jones_2000@163.com
  6. 指标窗口
  7. */
  8. //日志
  9. import { JSConsole } from "./umychart.console.wechat.js"
  10. import
  11. {
  12. g_JSChartResource,
  13. JSCHART_LANGUAGE_ID,
  14. g_JSChartLocalization,
  15. } from './umychart.resource.wechat.js'
  16. import
  17. {
  18. Guid,
  19. JSCHART_EVENT_ID,
  20. ToFixedPoint,
  21. ToFixedRect,
  22. CloneData,
  23. } from "./umychart.data.wechat.js";
  24. import
  25. {
  26. CoordinateInfo,
  27. IFrameSplitOperator,
  28. FrameSplitKLinePriceY,
  29. FrameSplitY,
  30. FrameSplitKLineX,
  31. FrameSplitMinutePriceY,
  32. FrameSplitMinuteX,
  33. FrameSplitXData,
  34. SplitData,
  35. PriceSplitData,
  36. FrameSplitXDepth,
  37. IChangeStringFormat,
  38. HQPriceStringFormat,
  39. HQDateStringFormat,
  40. HQMinuteTimeStringFormat,
  41. g_DivTooltipDataForamt,
  42. } from './umychart.framesplit.wechat.js'
  43. import
  44. {
  45. g_MinuteTimeStringData
  46. } from "./umychart.coordinatedata.wechat.js";
  47. function IChartFramePainting()
  48. {
  49. this.HorizontalInfo = new Array(); //Y轴
  50. this.VerticalInfo = new Array(); //X轴
  51. this.ClassName='IChartFramePainting';
  52. this.Canvas; //画布
  53. this.Identify; //窗口标识
  54. this.Guid=Guid(); //内部窗口唯一标识
  55. this.ChartBorder;
  56. this.PenBorder = g_JSChartResource.FrameBorderPen; //边框颜色
  57. this.TitleBGColor = g_JSChartResource.FrameTitleBGColor; //标题背景色
  58. this.IsShow = true; //是否显示
  59. this.SizeChange = true; //大小是否改变
  60. this.XYSplit = true; //XY轴坐标信息改变
  61. this.XSplit=true; //X轴坐标信息改变
  62. this.YCustomSplit=true; //Y轴自定刻度
  63. this.HorizontalMax; //Y轴最大值
  64. this.HorizontalMin; //Y轴最小值
  65. this.XPointCount = 10; //X轴数据个数
  66. this.YMaxMin={ Max:null, Min:null }; //Y轴原始的最大值 最小值
  67. this.YSplitOperator; //Y轴分割
  68. this.XSplitOperator; //X轴分割
  69. this.Data; //主数据
  70. this.YSpecificMaxMin = null; //指定Y轴最大最小值
  71. this.YSplitScale=null; //固定分割刻度数组 [2,5,8]
  72. this.IsShowBorder = true; //是否显示边框
  73. this.IsShowIndexName = true; //是否显示指标名字
  74. this.IndexParamSpace = 2; //指标参数数值显示间距
  75. this.IndexTitleSpace=0; //指标标题到参数之间的间距
  76. this.IsShowTitleArrow=g_JSChartResource.IndexTitle.EnableIndexArrow; //是否显示指标信息上涨下跌箭头
  77. this.TitleArrowType=g_JSChartResource.IndexTitle.ArrowType; //指标信息上涨下跌箭头类型 0=独立颜色 1=跟指标名字颜色一致
  78. //上锁信息
  79. this.IsLocked = false; //是否上锁
  80. this.LockPaint = null;
  81. this.BorderLine=null; //1=上 2=下 4=左 8=右
  82. this.IsMinSize=false; //窗口是否最小化
  83. this.LogoTextColor=g_JSChartResource.FrameLogo.TextColor;
  84. this.LogoTextFont=g_JSChartResource.FrameLogo.Font;
  85. this.Draw = function ()
  86. {
  87. this.DrawFrame();
  88. this.DrawBorder();
  89. this.SizeChange = false;
  90. this.XYSplit = false;
  91. this.XSplit=false;
  92. this.YCustomSplit=false;
  93. }
  94. this.DrawFrame = function () { }
  95. this.GetBorder=function()
  96. {
  97. if (this.IsHScreen) return this.ChartBorder.GetHScreenBorder();
  98. else return this.ChartBorder.GetBorder();
  99. }
  100. this.ClearCoordinateText=function(option)
  101. {
  102. if (IFrameSplitOperator.IsNonEmptyArray(this.HorizontalInfo))
  103. {
  104. for(var i=0;i<this.HorizontalInfo.length;++i)
  105. {
  106. var item=this.HorizontalInfo[i];
  107. item.Message[0]=item.Message[1]=null;
  108. }
  109. }
  110. if (IFrameSplitOperator.IsNonEmptyArray(this.VerticalInfo))
  111. {
  112. for(var i=0;i<this.VerticalInfo.length;++i)
  113. {
  114. var item=this.VerticalInfo[i];
  115. item.Message[0]=item.Message[1]=null;
  116. }
  117. }
  118. }
  119. //画边框
  120. this.DrawBorder = function ()
  121. {
  122. if (!this.IsShowBorder) return;
  123. if (this.IsMinSize) return;
  124. var left = ToFixedPoint(this.ChartBorder.GetLeft());
  125. var top = ToFixedPoint(this.ChartBorder.GetTop());
  126. var right = ToFixedPoint(this.ChartBorder.GetRight());
  127. var bottom = ToFixedPoint(this.ChartBorder.GetBottom());
  128. var width = right - left;
  129. var height = bottom - top;
  130. if (this.BorderLine==null)
  131. {
  132. this.Canvas.strokeStyle = this.PenBorder;
  133. this.Canvas.strokeRect(left, top, width, height);
  134. }
  135. else if (IFrameSplitOperator.IsNumber(this.BorderLine))
  136. {
  137. this.Canvas.strokeStyle=this.PenBorder;
  138. this.Canvas.beginPath();
  139. if ((this.BorderLine&1)>0) //上
  140. {
  141. this.Canvas.moveTo(left,top);
  142. this.Canvas.lineTo(right,top);
  143. }
  144. if ((this.BorderLine&2)>0) //下
  145. {
  146. this.Canvas.moveTo(left,bottom);
  147. this.Canvas.lineTo(right,bottom);
  148. }
  149. if ((this.BorderLine&4)>0) //左
  150. {
  151. this.Canvas.moveTo(left,top);
  152. this.Canvas.lineTo(left,bottom);
  153. }
  154. if ((this.BorderLine&8)>0) //右
  155. {
  156. this.Canvas.moveTo(right,top);
  157. this.Canvas.lineTo(right,bottom);
  158. }
  159. this.Canvas.stroke();
  160. }
  161. }
  162. //左右刻度文字宽度
  163. this.GetScaleTextWidth=function() { }
  164. //画标题背景色
  165. this.DrawTitleBG = function ()
  166. {
  167. /* ,
  168. if (this.ChartBorder.TitleHeight<=0) return;
  169. var left=ToFixedPoint(this.ChartBorder.GetLeft());
  170. var top=ToFixedPoint(this.ChartBorder.GetTop());
  171. var right=ToFixedPoint(this.ChartBorder.GetRight());
  172. var bottom=ToFixedPoint(this.ChartBorder.GetTopEx());
  173. var width=right-left;
  174. var height=bottom-top;
  175. this.Canvas.fillStyle=this.TitleBGColor;
  176. this.Canvas.fillRect(left,top,width,height);
  177. */
  178. }
  179. this.DrawLock = function ()
  180. {
  181. if (this.IsLocked)
  182. {
  183. if (this.LockPaint == null) this.LockPaint = new ChartLock();
  184. this.LockPaint.Canvas = this.Canvas;
  185. this.LockPaint.ChartBorder = this.ChartBorder;
  186. this.LockPaint.ChartFrame = this;
  187. this.LockPaint.Draw();
  188. }
  189. }
  190. this.DrawLogo=function()
  191. {
  192. var border=this.GetBorder();
  193. var text=g_JSChartResource.FrameLogo.Text;
  194. if (!text) return;
  195. this.Canvas.fillStyle=this.LogoTextColor;
  196. this.Canvas.font=this.LogoTextFont;
  197. this.Canvas.textAlign = 'left';
  198. this.Canvas.textBaseline = 'bottom';
  199. if (this.IsHScreen)
  200. {
  201. var x=border.Left+5;
  202. var y=border.Top+5;
  203. this.Canvas.save();
  204. this.Canvas.translate(x,y);
  205. this.Canvas.rotate(90 * Math.PI / 180);
  206. this.Canvas.fillText(text,0,0);
  207. this.Canvas.restore();
  208. }
  209. else
  210. {
  211. var x=border.Left+5;
  212. var y=border.Bottom-5;
  213. this.Canvas.fillText(text,x,y);
  214. }
  215. }
  216. //设施上锁
  217. this.SetLock = function (lockData)
  218. {
  219. if (!lockData) //空数据不上锁
  220. {
  221. this.IsLocked = false;
  222. return;
  223. }
  224. this.IsLocked = true;
  225. if (!this.LockPaint) this.LockPaint = new ChartLock(); //创建锁
  226. if (lockData.Callback) this.LockPaint.Callback = lockData.Callback; //回调
  227. if (lockData.IndexName) this.LockPaint.IndexName = lockData.IndexName; //指标名字
  228. if (lockData.ID) this.LockPaint.LockID = lockData.ID; //锁ID
  229. if (lockData.BG) this.LockPaint.BGColor = lockData.BG; //背景色
  230. if (lockData.Text) this.LockPaint.Title = lockData.Text;
  231. if (lockData.TextColor) this.LockPaint.TextColor = lockData.TextColor;
  232. if (lockData.Font) this.LockPaint.Font = lockData.Font;
  233. if (lockData.Count) this.LockPaint.LockCount = lockData.Count;
  234. }
  235. this.GetLockRect=function()
  236. {
  237. if (!this.IsLocked) return null;
  238. if (!this.LockPaint) return null;
  239. return this.LockPaint.LockRect;
  240. }
  241. this.GetFontHeight=function(font)
  242. {
  243. if (font) this.Canvas.font=font;
  244. return this.Canvas.measureText("擎").width;
  245. }
  246. }
  247. //空框架只画边框
  248. function NoneFrame()
  249. {
  250. this.newMethod = IChartFramePainting; //派生
  251. this.newMethod();
  252. delete this.newMethod;
  253. this.ClassName='NoneFrame';
  254. this.Snapshot = function () { }
  255. this.DrawInsideHorizontal = function () { }
  256. this.SetSizeChage = function (sizeChange)
  257. {
  258. this.SizeChange = sizeChange;
  259. //画布的位置
  260. this.Position =
  261. {
  262. X: this.ChartBorder.UIElement.offsetLeft,
  263. Y: this.ChartBorder.UIElement.offsetTop,
  264. W: this.ChartBorder.UIElement.clientWidth,
  265. H: this.ChartBorder.UIElement.clientHeight
  266. };
  267. }
  268. }
  269. function AverageWidthFrame()
  270. {
  271. this.newMethod = IChartFramePainting; //派生
  272. this.newMethod();
  273. delete this.newMethod;
  274. this.ClassName='AverageWidthFrame';
  275. this.DataWidth = 50;
  276. this.DistanceWidth = 10;
  277. this.MinXDistance = 30; //X轴刻度最小间距
  278. this.MinYDistance=10;
  279. this.XMessageAlign = 'top'; //X轴刻度文字上下对齐方式
  280. this.IsShowTitle = true; //是否显示动态标题
  281. this.IsShowYText = [true, true]; //是否显示Y轴坐标坐标 [0=左侧] [1=右侧]
  282. this.XBottomOffset = g_JSChartResource.Frame.XBottomOffset; //X轴文字显示向下偏移
  283. this.YTextTopOffset=g_JSChartResource.Frame.YTopOffset; //Y轴顶部文字向下偏移
  284. this.YTextPosition=[0,0], //是坐标否强制画在内部 [0=左侧] [1=右侧] 1=OUT" , 2=INSIDE
  285. this.YTextPadding=[g_JSChartResource.Frame.YTextPadding[0], g_JSChartResource.Frame.YTextPadding[1]], //Y轴文字和边框间距 [0=左侧] [1=右侧]
  286. this.IsShowXLine=true; //是否显示X轴刻度线
  287. this.IsShowYLine=true;
  288. this.YTextBaseline=0; //0=居中 1=上部 (目前就支持内部刻度)
  289. this.ShortYLineLength=5;
  290. this.ShortXLineLength=5;
  291. this.DrawOtherChart; //其他画法调用
  292. this.GetEventCallback; //事件回调
  293. this.FrameData={ SubFrameItem:null }; //窗口框架信息
  294. this.DrawFrame = function ()
  295. {
  296. if (this.XPointCount > 0)
  297. {
  298. this.DistanceWidth = this.ChartBorder.GetWidth() / (4 * this.XPointCount);
  299. this.DataWidth = 2 * this.DistanceWidth;
  300. }
  301. this.DrawHorizontal();
  302. this.DrawVertical();
  303. }
  304. this.GetYFromData = function (value)
  305. {
  306. if (value <= this.HorizontalMin) return this.ChartBorder.GetBottomEx();
  307. if (value >= this.HorizontalMax) return this.ChartBorder.GetTopEx();
  308. var height = this.ChartBorder.GetHeightEx() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  309. return this.ChartBorder.GetBottomEx() - height;
  310. }
  311. //Y刻度画在内部
  312. this.DrawInsideHorizontal = function ()
  313. {
  314. if (this.IsHScreen === true) return; //横屏不画
  315. if (this.IsMinSize) return;
  316. if (this.IsShowYText[0] === false && this.IsShowYText[1] === false) return;
  317. var left = this.ChartBorder.GetLeft();
  318. var right = this.ChartBorder.GetRight();
  319. var bottom = this.ChartBorder.GetBottom();
  320. var top = this.ChartBorder.GetTopTitle();
  321. var borderRight = this.ChartBorder.Right;
  322. var borderLeft = this.ChartBorder.Left;
  323. var titleHeight = this.ChartBorder.TitleHeight;
  324. if (borderLeft >= 10 && borderRight>=10) return;
  325. if ((borderLeft < 10 && this.IsShowYText[0] === true) || (borderRight < 10 && this.IsShowYText[1] === true))
  326. {
  327. var yPrev = null; //上一个坐标y的值
  328. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  329. {
  330. var item = this.HorizontalInfo[i];
  331. if (!item) continue;
  332. var y = this.GetYFromData(item.Value);
  333. if (y != null && yPrev !=null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  334. //坐标信息 左边 间距小于10 画在内部
  335. if (item.Message[0] != null && borderLeft < 10 && this.IsShowYText[0] === true)
  336. {
  337. if (item.Font != null) this.Canvas.font = item.Font;
  338. this.Canvas.fillStyle = item.TextColor;
  339. this.Canvas.textAlign = "left";
  340. var textHeight=this.Canvas.measureText('擎').width;
  341. var yText=y;
  342. if (y >= bottom - 2)
  343. {
  344. this.Canvas.textBaseline = 'bottom';
  345. }
  346. else if (y-textHeight/2 <= top)
  347. {
  348. this.Canvas.textBaseline = 'top';
  349. yText+=this.YTextTopOffset;
  350. }
  351. else
  352. {
  353. if (this.YTextBaseline==1) this.Canvas.textBaseline = "bottom";
  354. else this.Canvas.textBaseline = "middle";
  355. }
  356. var textObj = { X: left, Y: yText, Text: { BaseLine: this.Canvas.textBaseline, Font: this.Canvas.font, Value: item.Message[0] } };
  357. if (!this.IsOverlayMaxMin || !this.IsOverlayMaxMin(textObj)) this.Canvas.fillText(item.Message[0], left + 1, yText);
  358. }
  359. if (item.Message[1] != null && borderRight < 10 && this.IsShowYText[1] === true)
  360. {
  361. if (item.Font != null) this.Canvas.font = item.Font;
  362. this.Canvas.fillStyle = item.TextColor;
  363. this.Canvas.textAlign = "right";
  364. var textHeight=this.Canvas.measureText('擎').width;
  365. var yText=y;
  366. if (y >= bottom - 2)
  367. {
  368. this.Canvas.textBaseline = 'bottom';
  369. }
  370. else if (y-textHeight/2 <= top)
  371. {
  372. this.Canvas.textBaseline = 'top';
  373. yText+=this.YTextTopOffset;
  374. }
  375. else
  376. {
  377. if (this.YTextBaseline==1) this.Canvas.textBaseline = "bottom";
  378. else this.Canvas.textBaseline = "middle";
  379. }
  380. var textWidth = this.Canvas.measureText(item.Message[1]).width;
  381. var textObj = { X: right - textWidth, Y: yText, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[1] } };
  382. if (!this.IsOverlayMaxMin || !this.IsOverlayMaxMin(textObj))
  383. this.Canvas.fillText(item.Message[1], right - 1, yText);
  384. }
  385. yPrev = y;
  386. }
  387. }
  388. }
  389. //画Y轴
  390. this.DrawHorizontal = function ()
  391. {
  392. var left = this.ChartBorder.GetLeft();
  393. var right = this.ChartBorder.GetRight();
  394. var bottom = this.ChartBorder.GetBottom();
  395. var top = this.ChartBorder.GetTopTitle();
  396. var borderRight = this.ChartBorder.Right;
  397. var borderLeft = this.ChartBorder.Left;
  398. var titleHeight = this.ChartBorder.TitleHeight;
  399. this.Canvas.save();
  400. var yPrev = null; //上一个坐标y的值
  401. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  402. {
  403. var item = this.HorizontalInfo[i];
  404. var y = this.GetYFromData(item.Value);
  405. if (y != null && yPrev != null && Math.abs(y - yPrev) <this.MinYDistance) continue; //两个坐标在近了 就不画了
  406. var yFixed=ToFixedPoint(y);
  407. if (bottom!=y && this.IsShowYLine) //和底部线段重叠了就不绘制
  408. {
  409. if (item.LineType==2)
  410. {
  411. this.Canvas.strokeStyle = item.LineColor;
  412. if (item.LineDash) this.Canvas.setLineDash(item.LineDash);
  413. else this.Canvas.setLineDash([5,5]);
  414. this.Canvas.beginPath();
  415. this.Canvas.moveTo(left, yFixed);
  416. this.Canvas.lineTo(right,yFixed);
  417. this.Canvas.stroke();
  418. this.Canvas.setLineDash([]);
  419. }
  420. else if (item.LineType==3) //只在刻度边上画一个短横线
  421. {
  422. }
  423. else if (item.LineType>0)
  424. {
  425. this.Canvas.strokeStyle = item.LineColor;
  426. if(g_JSChartResource.FrameYLineDash)
  427. {
  428. this.Canvas.setLineDash(g_JSChartResource.FrameYLineDash); //虚线
  429. this.Canvas.beginPath();
  430. this.Canvas.moveTo(left, yFixed);
  431. this.Canvas.lineTo(right, yFixed);
  432. this.Canvas.stroke();
  433. this.Canvas.setLineDash([]);
  434. }
  435. else
  436. {
  437. this.Canvas.beginPath();
  438. this.Canvas.moveTo(left, yFixed);
  439. this.Canvas.lineTo(right, yFixed);
  440. this.Canvas.stroke();
  441. }
  442. }
  443. }
  444. var yText=y;
  445. if (y >= bottom - 2)
  446. {
  447. this.Canvas.textBaseline = 'bottom';
  448. }
  449. else if (y <= top + 2)
  450. {
  451. this.Canvas.textBaseline = 'top';
  452. yText+=this.YTextTopOffset;
  453. }
  454. else
  455. {
  456. this.Canvas.textBaseline = "middle";
  457. }
  458. //坐标信息 左边 间距小于10 不画坐标
  459. this.Canvas.fillStyle = item.TextColor;
  460. this.Canvas.strokeStyle = item.TextColor;
  461. if (item.Message[0] != null && borderLeft > 10 && this.IsShowYText[0] === true)
  462. {
  463. if (item.Font != null) this.Canvas.font = item.Font;
  464. this.Canvas.textAlign = "right";
  465. this.Canvas.fillText(item.Message[0], left - this.YTextPadding[0], yText);
  466. }
  467. //坐标信息 右边 间距小于10 不画坐标
  468. if (item.Message[1] != null && borderRight > 10 && this.IsShowYText[1] === true)
  469. {
  470. if (item.Font != null) this.Canvas.font = item.Font;
  471. var xText=right;
  472. if (item.LineType==3)
  473. {
  474. var lineLength=this.ShortYLineLength;
  475. this.Canvas.beginPath();
  476. this.Canvas.moveTo(xText,yFixed);
  477. this.Canvas.lineTo(xText+lineLength,yFixed);
  478. this.Canvas.stroke();
  479. xText+=lineLength;
  480. }
  481. this.Canvas.textAlign = "left";
  482. this.Canvas.fillText(item.Message[1], xText + this.YTextPadding[1], yText);
  483. }
  484. yPrev = y;
  485. }
  486. this.Canvas.restore();
  487. }
  488. this.GetXFromIndex = function (index)
  489. {
  490. var count = this.XPointCount;
  491. if (count == 1)
  492. {
  493. if (index == 0) return this.ChartBorder.GetLeft();
  494. else return this.ChartBorder.GetRight();
  495. }
  496. else if (count <= 0)
  497. {
  498. return this.ChartBorder.GetLeft();
  499. }
  500. else if (index >= count)
  501. {
  502. return this.ChartBorder.GetRight();
  503. }
  504. else
  505. {
  506. var offset = this.ChartBorder.GetLeft() + this.ChartBorder.GetWidth() * index / count;
  507. return offset;
  508. }
  509. }
  510. //画X轴
  511. this.DrawVertical = function ()
  512. {
  513. var top = this.ChartBorder.GetTopTitle();
  514. var bottom = this.ChartBorder.GetBottom();
  515. var right = this.ChartBorder.GetRight();
  516. var yText = bottom;
  517. if (this.XMessageAlign == 'bottom') yText = this.ChartBorder.GetChartHeight();
  518. else this.XMessageAlign = 'top';
  519. var xPrev = null; //上一个坐标x的值
  520. let xPrevTextRight = null;
  521. for (var i in this.VerticalInfo)
  522. {
  523. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  524. if (x > right) break;
  525. if (xPrev != null && Math.abs(x - xPrev) < this.MinXDistance) continue;
  526. var item=this.VerticalInfo[i];
  527. var xFixed=ToFixedPoint(x);
  528. if (this.IsShowXLine && item.LineType > 0)
  529. {
  530. if (item.LineType==2)
  531. {
  532. this.Canvas.strokeStyle = item.LineColor;
  533. if (item.LineDash) this.Canvas.setLineDash(item.LineDash);
  534. else this.Canvas.setLineDash([5,5]);
  535. this.Canvas.beginPath();
  536. this.Canvas.moveTo(xFixed, top);
  537. this.Canvas.lineTo(xFixed, bottom);
  538. this.Canvas.stroke();
  539. this.Canvas.setLineDash([]);
  540. }
  541. else if (item.LineType==3)
  542. {
  543. }
  544. else if (item.LineType>0)
  545. {
  546. if(g_JSChartResource.FrameXLineDash)
  547. {
  548. this.Canvas.strokeStyle = item.LineColor;
  549. this.Canvas.beginPath();
  550. this.Canvas.setLineDash(g_JSChartResource.FrameXLineDash);
  551. this.Canvas.moveTo(xFixed, top);
  552. this.Canvas.lineTo(xFixed, bottom);
  553. this.Canvas.stroke();
  554. this.Canvas.setLineDash([]);
  555. }
  556. else
  557. {
  558. this.Canvas.strokeStyle = item.LineColor;
  559. this.Canvas.beginPath();
  560. this.Canvas.moveTo(xFixed, top);
  561. this.Canvas.lineTo(xFixed, bottom);
  562. this.Canvas.stroke();
  563. }
  564. }
  565. }
  566. if (this.VerticalInfo[i].Message[0] != null && this.ChartBorder.Bottom > 5)
  567. {
  568. let xTextRight = null;
  569. let xTextLeft = null;
  570. if (this.VerticalInfo[i].Font != null)
  571. this.Canvas.font = this.VerticalInfo[i].Font;
  572. this.Canvas.fillStyle=item.TextColor;
  573. this.Canvas.strokeStyle=item.TextColor;
  574. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  575. if (x < testWidth / 2)
  576. {
  577. this.Canvas.textAlign = "left";
  578. this.Canvas.textBaseline = this.XMessageAlign;
  579. xTextRight = x + testWidth;
  580. xTextLeft = x;
  581. }
  582. else if ((x + testWidth / 2) >= this.ChartBorder.GetChartWidth())
  583. {
  584. this.Canvas.textAlign = "right";
  585. this.Canvas.textBaseline = this.XMessageAlign;
  586. xTextRight = x + testWidth;
  587. xTextLeft = x;
  588. }
  589. else
  590. {
  591. this.Canvas.textAlign = "center";
  592. this.Canvas.textBaseline = this.XMessageAlign;
  593. xTextRight = x + testWidth / 2;
  594. xTextLeft = x - testWidth / 2;
  595. }
  596. if (xPrevTextRight != null && xPrevTextRight > xTextLeft) continue;
  597. var yText=bottom;
  598. if (item.LineType==3)
  599. {
  600. var lineLength=this.ShortXLineLength;
  601. this.Canvas.beginPath();
  602. this.Canvas.moveTo(xFixed,yText);
  603. this.Canvas.lineTo(xFixed,yText+lineLength);
  604. this.Canvas.stroke();
  605. yText+=lineLength+2;
  606. }
  607. this.Canvas.fillText(this.VerticalInfo[i].Message[0], x, yText + this.XBottomOffset);
  608. xPrevTextRight = xTextRight;
  609. }
  610. xPrev = x;
  611. }
  612. }
  613. this.GetYData = function (y) //Y坐标转y轴数值
  614. {
  615. if (y < this.ChartBorder.GetTopEx()) return this.HorizontalMax;
  616. if (y > this.ChartBorder.GetBottomEx()) return this.HorizontalMin;
  617. return (this.ChartBorder.GetBottomEx() - y) / this.ChartBorder.GetHeightEx() * (this.HorizontalMax - this.HorizontalMin) + this.HorizontalMin;
  618. }
  619. this.GetXData = function (x) //X坐标转x轴数值
  620. {
  621. if (x <= this.ChartBorder.GetLeft()) return 0;
  622. if (x >= this.ChartBorder.GetRight()) return this.XPointCount;
  623. return (x - this.ChartBorder.GetLeft()) * (this.XPointCount * 1.0 / this.ChartBorder.GetWidth());
  624. }
  625. this.DrawCustomItem = function (item) //显示自定义刻度
  626. {
  627. //if (this.IsHScreen === true) return; //横屏不画
  628. if (!item.Message[1] && !item.Message[0]) return;
  629. if (item.Value > this.HorizontalMax || item.Value < this.HorizontalMin)
  630. {
  631. if (item.CountDown===true) this.SendDrawCountDownEvent( { IsShow:false } );
  632. return;
  633. }
  634. var left = this.ChartBorder.GetLeft();
  635. var right = this.ChartBorder.GetRight();
  636. var bottom = this.ChartBorder.GetBottom();
  637. var top = this.ChartBorder.GetTopTitle();
  638. var borderRight = this.ChartBorder.Right;
  639. var borderLeft = this.ChartBorder.Left;
  640. var titleHeight = this.ChartBorder.TitleHeight;
  641. if (this.IsHScreen)
  642. {
  643. borderLeft = this.ChartBorder.Top;
  644. borderRight = this.ChartBorder.Bottom;
  645. top = this.ChartBorder.GetTop();
  646. bottom = this.ChartBorder.GetBottom();
  647. }
  648. var defaultTextHeight=16
  649. var textHeight = defaultTextHeight;
  650. var y = this.GetYFromData(item.Value);
  651. var position=0;
  652. if (item.ExtendData && item.ExtendData.Custom)
  653. {
  654. var customItem=item.ExtendData.Custom;
  655. if (IFrameSplitOperator.IsNumber(customItem.Position)) position=customItem.Position;
  656. }
  657. if (item.Message[0])
  658. {
  659. if (borderLeft < 10 || position==1) //左边
  660. {
  661. if (item.Font != null) this.Canvas.font = item.Font;
  662. this.Canvas.textAlign = "left";
  663. this.Canvas.textBaseline = "middle";
  664. var textInfo=this.GetCustomItemTextInfo(item,true);
  665. var textWidth = textInfo.MaxWidth;
  666. var fontHeight=this.GetFontHeight();
  667. textHeight=fontHeight>defaultTextHeight? fontHeight:defaultTextHeight;
  668. var bgColor = item.LineColor;
  669. var rgb = this.RGBToStruct(item.LineColor);
  670. if (rgb) bgColor = `rgba(${rgb.R}, ${rgb.G}, ${rgb.B}, ${g_JSChartResource.FrameLatestPrice.BGAlpha})`; //内部刻度 背景增加透明度
  671. var yText=y;
  672. for(var i=0;i<textInfo.Text.length;++i)
  673. {
  674. var itemText=textInfo.Text[i];
  675. if (this.IsHScreen)
  676. {
  677. var bgTop = top;
  678. var textLeft = yText - textHeight / 2 - 1;
  679. this.Canvas.fillStyle = bgColor;
  680. this.Canvas.fillRect(textLeft, bgTop, textHeight, textWidth);
  681. this.DrawHScreenText({ X: yText, Y: bgTop }, { Text: itemText.Text, Color: item.TextColor, XOffset: 1, YOffset: 2 });
  682. if (i==0) this.DrawLine(bgTop + itemText.Width, bottom, yText, item.LineColor,item.LineType);
  683. yText-=textHeight+1;
  684. }
  685. else
  686. {
  687. var bgTop = yText - textHeight / 2 - 1;
  688. var textLeft = left + 1;
  689. this.Canvas.fillStyle = bgColor;
  690. this.Canvas.fillRect(textLeft, bgTop, itemText.Width, textHeight);
  691. this.Canvas.fillStyle = item.TextColor;
  692. this.Canvas.fillText(itemText.Text, textLeft + 1, yText);
  693. if (i==0) this.DrawLine(textLeft + itemText.Width, right, yText, item.LineColor,item.LineType);
  694. yText+=textHeight+1;
  695. }
  696. }
  697. }
  698. else
  699. {
  700. if (item.Font != null) this.Canvas.font = item.Font;
  701. this.Canvas.textAlign = "right";
  702. this.Canvas.textBaseline = "middle";
  703. var textInfo=this.GetCustomItemTextInfo(item,true);
  704. var textWidth=textInfo.MaxWidth;
  705. var fontHeight=this.GetFontHeight();
  706. textHeight=fontHeight>defaultTextHeight? fontHeight:defaultTextHeight;
  707. var yText=y;
  708. for(var i=0;i<textInfo.Text.length;++i)
  709. {
  710. var itemText=textInfo.Text[i];
  711. if (this.IsHScreen)
  712. {
  713. if (i==0) var bgTop=top-itemText.Width;
  714. else var bgTop=top-textWidth;
  715. var textLeft=yText-textHeight/2-1;
  716. this.Canvas.fillStyle=item.LineColor;
  717. this.Canvas.fillRect(textLeft,bgTop,textHeight,itemText.Width);
  718. this.DrawHScreenText({ X: yText, Y: bgTop }, { Text: itemText.Text, Color: item.TextColor, XOffset: 1, YOffset: 2 });
  719. if (i==0) this.DrawLine(bgTop + itemText.Width, bottom, yText, item.LineColor,item.LineType);
  720. yText-=textHeight+1;
  721. }
  722. else
  723. {
  724. var bgTop = yText - textHeight / 2 - 1;
  725. if (i==0)
  726. {
  727. var rectLeft=left-itemText.Width;
  728. var textLeft=left;
  729. }
  730. else
  731. {
  732. var rectLeft=left-textWidth;
  733. var textLeft=left-(textWidth-itemText.Width);
  734. }
  735. this.Canvas.fillStyle = item.LineColor;
  736. this.Canvas.fillRect(rectLeft,bgTop,itemText.Width,textHeight);
  737. this.Canvas.fillStyle = item.TextColor;
  738. this.Canvas.fillText(itemText.Text, textLeft - 1, yText);
  739. if (i==0) this.DrawLine(left, right, yText, item.LineColor,item.LineType);
  740. yText+=textHeight+1;
  741. }
  742. }
  743. }
  744. }
  745. else if (item.Message[1]) //右边
  746. {
  747. if (borderRight < 10 || position==1)
  748. {
  749. if (item.Font != null) this.Canvas.font = item.Font;
  750. this.Canvas.textAlign = "left";
  751. this.Canvas.textBaseline = "middle";
  752. var textInfo=this.GetCustomItemTextInfo(item,false);
  753. var textWidth=textInfo.MaxWidth;
  754. var fontHeight=this.GetFontHeight();
  755. textHeight=fontHeight>defaultTextHeight? fontHeight:defaultTextHeight;
  756. var bgColor = item.LineColor;
  757. var rgb = this.RGBToStruct(item.LineColor);
  758. if (rgb) bgColor = `rgba(${rgb.R}, ${rgb.G}, ${rgb.B}, ${g_JSChartResource.FrameLatestPrice.BGAlpha})`; //内部刻度 背景增加透明度
  759. var yText=y;
  760. for(var i=0;i<textInfo.Text.length;++i)
  761. {
  762. var itemText=textInfo.Text[i];
  763. if (this.IsHScreen)
  764. {
  765. var bgTop=bottom-itemText.Width;
  766. var textLeft=yText-textHeight/2-1;
  767. this.Canvas.fillStyle=bgColor;
  768. this.Canvas.fillRect(textLeft,bgTop,textHeight,itemText.Width);
  769. this.DrawHScreenText({X:yText, Y:bgTop}, {Text:itemText.Text, Color:item.TextColor, XOffset:1, YOffset:2});
  770. if (i==0) this.DrawLine(top, bgTop, yText, item.LineColor,item.LineType);
  771. yText-=textHeight+1;
  772. }
  773. else
  774. {
  775. var bgTop=yText-textHeight/2-1;
  776. var textLeft=right-itemText.Width;
  777. this.Canvas.fillStyle=bgColor;
  778. this.Canvas.fillRect(textLeft, bgTop, itemText.Width, textHeight);
  779. this.Canvas.fillStyle = item.TextColor;
  780. this.Canvas.fillText(itemText.Text, textLeft + 1, yText);
  781. if (i==0) this.DrawLine(left, textLeft,yText , item.LineColor,item.LineType);
  782. if (item.CountDown===true)
  783. {
  784. if (this.GetEventCallback)
  785. {
  786. var bgTop=yText + textHeight / 2 + 1;
  787. var sendData=
  788. {
  789. Top:bgTop, Right:right, Height:null,
  790. IsShow:true, BGColor:bgColor, TextColor:item.TextColor, Position:"Right", IsInside:true
  791. };
  792. this.SendDrawCountDownEvent(sendData);
  793. }
  794. }
  795. yText+=textHeight+1;
  796. }
  797. }
  798. if (item.Type==3 || item.Type==4)
  799. {
  800. if (item.Title)
  801. {
  802. var width=this.Canvas.measureText(item.Title).width+2;
  803. if (this.IsHScreen)
  804. {
  805. var bgTop=bottom-itemText.Width-width;
  806. var textLeft=y-textHeight/2-1;
  807. this.Canvas.fillStyle=bgColor;
  808. this.Canvas.fillRect(textLeft,bgTop,textHeight,width);
  809. this.DrawHScreenText({X:y, Y:bgTop}, {Text:item.Title, Color:item.TextColor, XOffset:1, YOffset:2});
  810. }
  811. else
  812. {
  813. var bgTop=y-textHeight/2-1;
  814. var textLeft=right-textWidth-width-1;
  815. this.Canvas.fillStyle=bgColor;
  816. this.Canvas.fillRect(textLeft,bgTop,width,textHeight);
  817. this.Canvas.fillStyle = item.TextColor;
  818. this.Canvas.fillText(item.Title, textLeft + 1, y);
  819. }
  820. }
  821. }
  822. }
  823. else
  824. {
  825. if (item.Font != null) this.Canvas.font = item.Font;
  826. this.Canvas.textAlign = "left";
  827. this.Canvas.textBaseline = "middle";
  828. var textInfo=this.GetCustomItemTextInfo(item,false);
  829. var textWidth=textInfo.MaxWidth;
  830. var fontHeight=this.GetFontHeight();
  831. textHeight=fontHeight>defaultTextHeight? fontHeight:defaultTextHeight;
  832. var yText=y;
  833. for(var i=0;i<textInfo.Text.length;++i)
  834. {
  835. var itemText=textInfo.Text[i];
  836. if (this.IsHScreen)
  837. {
  838. var bgTop = bottom;
  839. var textLeft=yText-textHeight/2-1;
  840. this.Canvas.fillStyle=item.LineColor;
  841. this.Canvas.fillRect(textLeft, bgTop, textHeight, itemText.Width);
  842. this.DrawHScreenText({ X: yText, Y: bgTop }, { Text: itemText.Text, Color: item.TextColor, XOffset: 1 , YOffset: 2 });
  843. if (i==0) this.DrawLine(top, bgTop, yText, item.LineColor,item.LineType);
  844. yText-=textHeight+1;
  845. }
  846. else
  847. {
  848. var bgTop=yText-textHeight/2-1;
  849. if (i==0)
  850. {
  851. var textLeft=right;
  852. }
  853. else
  854. {
  855. var textLeft=right+textWidth-itemText.Width;
  856. }
  857. this.Canvas.fillStyle = item.LineColor;
  858. this.Canvas.fillRect(textLeft,bgTop,itemText.Width,textHeight);
  859. this.Canvas.fillStyle = item.TextColor;
  860. this.Canvas.fillText(itemText.Text, textLeft+1, yText);
  861. if (i==0) this.DrawLine(left, right, yText, item.LineColor,item.LineType);
  862. if (item.CountDown===true)
  863. {
  864. if (this.GetEventCallback)
  865. {
  866. var bgTop=yText-textHeight/2-1;
  867. var sendData=
  868. {
  869. Top:bgTop, Left:right, Right:this.ChartBorder.GetChartWidth(), Height:null,
  870. IsShow:true, BGColor:item.LineColor, TextColor:item.TextColor, Position:"Right", IsInside:false
  871. };
  872. this.SendDrawCountDownEvent(sendData);
  873. }
  874. }
  875. yText+=textHeight+1;
  876. }
  877. }
  878. if (item.Type==3 || item.Type==4)
  879. {
  880. if (item.Title)
  881. {
  882. var bgColor=item.LineColor;
  883. var rgb=this.RGBToStruct(item.LineColor);
  884. if (rgb) bgColor=`rgba(${rgb.R}, ${rgb.G}, ${rgb.B}, ${g_JSChartResource.FrameLatestPrice.BGAlpha})`; //内部刻度 背景增加透明度
  885. var width=this.Canvas.measureText(item.Title).width+2;
  886. if (this.IsHScreen)
  887. {
  888. var bgTop=bottom-width;
  889. var textLeft=y-textHeight/2-1;
  890. this.Canvas.fillStyle=bgColor;
  891. this.Canvas.fillRect(textLeft,bgTop,textHeight,width);
  892. this.DrawHScreenText({X:y, Y:bgTop}, {Text:item.Title, Color:item.TextColor, XOffset:1, YOffset:2});
  893. }
  894. else
  895. {
  896. var bgTop=y-textHeight/2-1;
  897. var textLeft=right-width-1;
  898. this.Canvas.fillStyle=bgColor;
  899. this.Canvas.fillRect(textLeft,bgTop,width,textHeight);
  900. this.Canvas.fillStyle = item.TextColor;
  901. this.Canvas.fillText(item.Title, textLeft + 1, y);
  902. }
  903. }
  904. }
  905. }
  906. }
  907. }
  908. this.GetCustomItemTextInfo=function(item, bLeft)
  909. {
  910. var text=bLeft?item.Message[0]:item.Message[1];
  911. var aryText=[];
  912. var width=0;
  913. if (Array.isArray(text))
  914. {
  915. for(var i=0;i<text.length;++i)
  916. {
  917. var item=text[i];
  918. if (item.Type===1)
  919. {
  920. aryText.push({ Type: item.Type });
  921. }
  922. else
  923. {
  924. var value=this.Canvas.measureText(item.Text).width;
  925. if (value>width) width=value;
  926. aryText.push({Text:item.Text, Width:value+3});
  927. }
  928. }
  929. if (width>0) width+=3;
  930. }
  931. else
  932. {
  933. width=this.Canvas.measureText(text).width+3;
  934. aryText.push( {Text:text, Width:width} );
  935. }
  936. return { MaxWidth:width, Text:aryText };
  937. }
  938. this.SendDrawCountDownEvent=function(sendData)
  939. {
  940. if (!this.GetEventCallback) return false;
  941. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DRAW_COUNTDOWN);
  942. if (!event || !event.Callback) return false;
  943. event.Callback(event,sendData,this);
  944. return true;
  945. }
  946. this.DrawLine=function(left, right, y, color, lineType)
  947. {
  948. if (lineType==-1) return;
  949. if (lineType==0)
  950. {
  951. this.Canvas.strokeStyle = color;
  952. this.Canvas.beginPath();
  953. if (this.IsHScreen)
  954. {
  955. this.Canvas.moveTo(ToFixedPoint(y), left);
  956. this.Canvas.lineTo(ToFixedPoint(y), right);
  957. }
  958. else
  959. {
  960. this.Canvas.moveTo(left, ToFixedPoint(y));
  961. this.Canvas.lineTo(right, ToFixedPoint(y));
  962. }
  963. this.Canvas.stroke();
  964. }
  965. else
  966. {
  967. this.DrawDotLine(left, right, y, color);
  968. }
  969. }
  970. this.DrawDotLine = function (left, right, y, color)
  971. {
  972. this.Canvas.save();
  973. this.Canvas.strokeStyle = color;
  974. this.Canvas.setLineDash([5, 5]); //虚线
  975. this.Canvas.beginPath();
  976. if (this.IsHScreen)
  977. {
  978. this.Canvas.moveTo(ToFixedPoint(y), left);
  979. this.Canvas.lineTo(ToFixedPoint(y), right);
  980. }
  981. else
  982. {
  983. this.Canvas.moveTo(left, ToFixedPoint(y));
  984. this.Canvas.lineTo(right, ToFixedPoint(y));
  985. }
  986. this.Canvas.stroke();
  987. this.Canvas.restore();
  988. }
  989. this.RGBToStruct = function (rgb)
  990. {
  991. if (/^(rgb|RGB)/.test(rgb))
  992. {
  993. var aColor = rgb.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(",");
  994. var result = {};
  995. if (aColor.length != 3) return null;
  996. result.R = Number(aColor[0]);
  997. result.G = Number(aColor[1]);
  998. result.B = Number(aColor[2]);
  999. return result;
  1000. }
  1001. return null;
  1002. }
  1003. this.DrawHScreenText = function (center, data)
  1004. {
  1005. this.Canvas.textAlign = "left";
  1006. this.Canvas.textBaseline = "middle";
  1007. this.Canvas.fillStyle = data.Color;
  1008. this.Canvas.save();
  1009. this.Canvas.translate(center.X, center.Y);
  1010. this.Canvas.rotate(90 * Math.PI / 180);
  1011. this.Canvas.fillText(data.Text, data.XOffset, data.YOffset);
  1012. this.Canvas.restore();
  1013. }
  1014. this.GetScaleTextWidth=function()
  1015. {
  1016. var border=this.ChartBorder.GetBorder();
  1017. if (this.IsHScreen)
  1018. {
  1019. var borderTop = this.ChartBorder.Top;
  1020. var borderBottom = this.ChartBorder.Bottom;
  1021. var isDrawLeft=borderTop>10 && this.IsShowYText[0]===true;
  1022. var isDrawRight=borderBottom>10 && this.IsShowYText[1]===true;
  1023. }
  1024. else
  1025. {
  1026. var borderRight=this.ChartBorder.Right;
  1027. var borderLeft=this.ChartBorder.Left;
  1028. var isDrawLeft=borderLeft>10 && this.IsShowYText[0]===true;
  1029. var isDrawRight=borderRight>10 && this.IsShowYText[1]===true;
  1030. }
  1031. var width={ Left:null, Right:null };
  1032. if (!isDrawRight && !isDrawLeft) return width;
  1033. for(var i=0;i<this.HorizontalInfo.length;++i)
  1034. {
  1035. var textWidth=null;
  1036. var item=this.HorizontalInfo[i];
  1037. if (!item) continue;
  1038. if (item.Font!=null) this.Canvas.font=item.Font;
  1039. if (item.Message[0]!=null && isDrawLeft)
  1040. {
  1041. textWidth=this.Canvas.measureText(item.Message[0]).width;
  1042. if (width.Left==null || width.Left<textWidth)
  1043. width.Left=textWidth;
  1044. }
  1045. if (item.Message[1]!=null && isDrawRight)
  1046. {
  1047. textWidth=this.Canvas.measureText(item.Message[1]).width;
  1048. if (width.Right==null || width.Right<textWidth)
  1049. width.Right=textWidth;
  1050. }
  1051. }
  1052. if (IFrameSplitOperator.IsNumber(width.Left)) width.Left+=this.YTextPadding[0];
  1053. if (IFrameSplitOperator.IsNumber(width.Right)) width.Right+=this.YTextPadding[1];
  1054. return { TextWidth:width };
  1055. }
  1056. this.GetMainOverlayFrame=function()
  1057. {
  1058. if (!this.FrameData || !this.FrameData.SubFrameItem) return null;
  1059. var subFrame=this.FrameData.SubFrameItem;
  1060. var leftFrame=null, rightFrame=null;
  1061. for(var i=0;i<subFrame.OverlayIndex.length;++i)
  1062. {
  1063. var item=subFrame.OverlayIndex[i];
  1064. var overlayFrame=item.Frame;
  1065. if (overlayFrame.IsShowMainFrame==2) rightFrame=overlayFrame;
  1066. else if (overlayFrame.IsShowMainFrame==1) leftFrame=overlayFrame;
  1067. }
  1068. if (!leftFrame && !rightFrame) return null;
  1069. return [leftFrame, rightFrame];
  1070. }
  1071. }
  1072. function MinuteFrame()
  1073. {
  1074. this.newMethod = AverageWidthFrame; //派生
  1075. this.newMethod();
  1076. delete this.newMethod;
  1077. this.ClassName='MinuteFrame';
  1078. this.DataWidth=1;
  1079. this.DistanceWidth=1;
  1080. this.MinXDistance = 10;
  1081. this.CustomHorizontalInfo = [];
  1082. this.NightDayConfig=CloneData(g_JSChartResource.Minute.NightDay);
  1083. this.DrawFrame = function ()
  1084. {
  1085. if (this.IsMinSize) return;
  1086. this.SplitXYCoordinate();
  1087. this.DrawNightDayBG(); //绘制夜盘 日盘背景
  1088. this.DrawTitleBG();
  1089. this.DrawHorizontal();
  1090. this.DrawVertical();
  1091. }
  1092. //分割x,y轴坐标信息
  1093. this.SplitXYCoordinate = function ()
  1094. {
  1095. if (this.XYSplit == false)
  1096. {
  1097. if (this.YCustomSplit)
  1098. {
  1099. if (this.YSplitOperator && this.YSplitOperator.CustomCoordinate) this.YSplitOperator.CustomCoordinate();
  1100. }
  1101. return;
  1102. }
  1103. if (this.YSplitOperator != null) this.YSplitOperator.Operator();
  1104. if (this.XSplitOperator != null) this.XSplitOperator.Operator();
  1105. }
  1106. this.DrawNightDayBG=function()
  1107. {
  1108. if (this.DayCount!=1) return;
  1109. if (!this.HQChart) return;
  1110. if (!this.HQChart.EnableNightDayBG) return;
  1111. var symbol=this.HQChart.Symbol;
  1112. if (!symbol) return;
  1113. var xIndex=-1;
  1114. //获取夜盘和日期的分界线X索引位置
  1115. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_MINUTE_NIGHT_DAY_X_INDEX)
  1116. if (!event || !event.Callback) return;
  1117. var sendData={ Symbol:symbol, XIndex:xIndex, MinuteTimeStringData:g_MinuteTimeStringData };
  1118. event.Callback(event,sendData,this);
  1119. xIndex=sendData.XIndex;
  1120. if (xIndex<0) return;
  1121. var border=this.ChartBorder.GetBorder();
  1122. var x=this.GetXFromIndex(xIndex);
  1123. var rtNight={ Left: border.Left, Top:border.TopEx, Right:x, Bottom:border.Bottom };
  1124. rtNight.Width=rtNight.Right-rtNight.Left;
  1125. rtNight.Height=rtNight.Bottom-rtNight.Top;
  1126. this.Canvas.fillStyle = this.NightDayConfig.NightBGColor;
  1127. this.Canvas.fillRect(rtNight.Left, rtNight.Top, rtNight.Width, rtNight.Height);
  1128. if (this.Identify!=0) return;
  1129. //显示 日盘夜盘文字
  1130. this.Canvas.font=this.NightDayConfig.Font;
  1131. this.Canvas.textBaseline = "bottom";
  1132. this.Canvas.textAlign = 'left';
  1133. var aryTitle=[{ Title:"夜盘", Position:1, Config:this.NightDayConfig.Night }, { Title:"日盘", Position:0,Config:this.NightDayConfig.Day }];
  1134. var textHeight= this.Canvas.measureText("擎").width;
  1135. for(var i=0;i<aryTitle.length;++i)
  1136. {
  1137. var item=aryTitle[i];
  1138. var text=g_JSChartLocalization.GetText(item.Title,this.HQChart.LanguageID);
  1139. var testWidth = this.Canvas.measureText(text).width;
  1140. var rtItem=
  1141. {
  1142. Width:testWidth+item.Config.Margin.Left+item.Config.Margin.Right,
  1143. Height:textHeight+item.Config.Margin.Top+item.Config.Margin.Bottom,
  1144. Bottom:border.Bottom
  1145. };
  1146. rtItem.Top=rtItem.Bottom-rtItem.Height;
  1147. if (item.Position===1)
  1148. {
  1149. rtItem.Right=x-1;
  1150. rtItem.Left=rtItem.Right-rtItem.Width;
  1151. }
  1152. else
  1153. {
  1154. rtItem.Left=x+1;
  1155. rtItem.Right=rtItem.Left+rtItem.Width;
  1156. }
  1157. if (item.Config.BGColor)
  1158. {
  1159. this.Canvas.fillStyle = item.Config.BGColor;
  1160. this.Canvas.fillRect(rtItem.Left, rtItem.Top, rtItem.Width, rtItem.Height);
  1161. }
  1162. if (item.Config.BorderColor)
  1163. {
  1164. this.Canvas.strokeStyle = item.Config.BorderColor;
  1165. this.Canvas.strokeRect(ToFixedPoint(rtItem.Left), ToFixedPoint(rtItem.Top), ToFixedRect(rtItem.Width), ToFixedRect(rtItem.Height));
  1166. }
  1167. this.Canvas.fillStyle = item.Config.Color;
  1168. this.Canvas.fillText(text, rtItem.Left+item.Config.Margin.Left, rtItem.Bottom-item.Config.Margin.Bottom );
  1169. }
  1170. }
  1171. this.GetXFromIndex = function (index)
  1172. {
  1173. var count = this.XPointCount - 1;
  1174. if (count == 1)
  1175. {
  1176. if (index == 0) return this.ChartBorder.GetLeft();
  1177. else return this.ChartBorder.GetRight();
  1178. }
  1179. else if (count <= 0)
  1180. {
  1181. return this.ChartBorder.GetLeft();
  1182. }
  1183. else if (index >= count)
  1184. {
  1185. return this.ChartBorder.GetRight();
  1186. }
  1187. else
  1188. {
  1189. var offset = this.ChartBorder.GetLeft() + this.ChartBorder.GetWidth() * index / count;
  1190. return offset;
  1191. }
  1192. }
  1193. //X坐标转x轴数值
  1194. this.GetXData = function (x)
  1195. {
  1196. if (x <= this.ChartBorder.GetLeft()) return 0;
  1197. if (x >= this.ChartBorder.GetRight()) return this.XPointCount;
  1198. return (x - this.ChartBorder.GetLeft()) * (this.XPointCount * 1.0 / this.ChartBorder.GetWidth());
  1199. }
  1200. this.DrawCustomHorizontal = function () //Y轴刻度定制显示
  1201. {
  1202. if (this.IsMinSize) return;
  1203. for (var i in this.CustomHorizontalInfo)
  1204. {
  1205. var item = this.CustomHorizontalInfo[i];
  1206. switch (item.Type)
  1207. {
  1208. case 0:
  1209. case 1:
  1210. this.DrawCustomItem(item); //自定义刻度
  1211. break;
  1212. }
  1213. }
  1214. }
  1215. }
  1216. function MinuteHScreenFrame()
  1217. {
  1218. this.newMethod = MinuteFrame; //派生
  1219. this.newMethod();
  1220. delete this.newMethod;
  1221. this.ClassName='MinuteHScreenFrame';
  1222. this.IsHScreen = true; //是否是横屏
  1223. //画标题背景色
  1224. this.DrawTitleBG = function ()
  1225. {
  1226. /*
  1227. if (this.ChartBorder.TitleHeight <= 0) return;
  1228. var left = ToFixedPoint(this.ChartBorder.GetRightEx());
  1229. var top = ToFixedPoint(this.ChartBorder.GetTop());
  1230. var bottom = ToFixedPoint(this.ChartBorder.GetBottom());
  1231. var width = this.ChartBorder.TitleHeight;
  1232. var height = bottom - top;
  1233. this.Canvas.fillStyle = this.TitleBGColor;
  1234. this.Canvas.fillRect(left, top, width, height);
  1235. */
  1236. }
  1237. this.DrawInsideHorizontal = function ()
  1238. {
  1239. if (this.IsMinSize) return;
  1240. if (this.IsShowYText[0] === false && this.IsShowYText[1] === false) return;
  1241. var left = this.ChartBorder.GetLeft();
  1242. var right = this.ChartBorder.GetRightEx();
  1243. var top = this.ChartBorder.GetTop();
  1244. var bottom = this.ChartBorder.GetBottom();
  1245. var borderTop = this.ChartBorder.Top;
  1246. var borderBottom = this.ChartBorder.Bottom;
  1247. var titleHeight = this.ChartBorder.TitleHeight;
  1248. var pixelTatio = 1;
  1249. var isDrawLeft = (borderTop < 10 * pixelTatio || this.YTextPosition[0] == 2) && this.IsShowYText[0] === true;
  1250. var isDrawRight = (borderBottom < 10 * pixelTatio || this.YTextPosition[1] == 2) && this.IsShowYText[1] === true;
  1251. if (isDrawLeft || isDrawRight)
  1252. {
  1253. var yPrev = null; //上一个坐标y的值
  1254. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  1255. {
  1256. var item = this.HorizontalInfo[i];
  1257. var y = this.GetYFromData(item.Value);
  1258. if (y != null && yPrev != null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  1259. //坐标信息 左边 间距小于10 画在内部
  1260. if (item.Message[0] != null && isDrawLeft)
  1261. {
  1262. if (item.Font != null) this.Canvas.font = item.Font;
  1263. this.Canvas.fillStyle = item.TextColor;
  1264. this.Canvas.textAlign = "left";
  1265. if (y >= right - 2) this.Canvas.textBaseline = 'top';
  1266. else if (y <= left + 2) this.Canvas.textBaseline = 'bottom';
  1267. else this.Canvas.textBaseline = "middle";
  1268. var textObj = { X: left, Y: y, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[0] } };
  1269. var xText = y, yText = top;
  1270. this.Canvas.save();
  1271. this.Canvas.translate(xText, yText);
  1272. this.Canvas.rotate(90 * Math.PI / 180);
  1273. this.Canvas.fillText(item.Message[0], 2, 0);
  1274. this.Canvas.restore();
  1275. }
  1276. if (item.Message[1] != null && isDrawRight)
  1277. {
  1278. if (item.Font != null) this.Canvas.font = item.Font;
  1279. this.Canvas.fillStyle = item.TextColor;
  1280. this.Canvas.textAlign = "right";
  1281. if (y >= right - 2) this.Canvas.textBaseline = 'top';
  1282. else if (y <= left + 2) this.Canvas.textBaseline = 'bottom';
  1283. else this.Canvas.textBaseline = "middle";
  1284. var textWidth = this.Canvas.measureText(item.Message[1]).width;
  1285. var textObj = { X: right - textWidth, Y: y, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[1] } };
  1286. var xText = y, yText = bottom;
  1287. this.Canvas.save();
  1288. this.Canvas.translate(xText, yText);
  1289. this.Canvas.rotate(90 * Math.PI / 180);
  1290. this.Canvas.fillText(item.Message[1], -2, 0);
  1291. this.Canvas.restore();
  1292. }
  1293. yPrev = y;
  1294. }
  1295. }
  1296. }
  1297. //Y坐标转y轴数值
  1298. this.GetYData = function (x)
  1299. {
  1300. if (x < this.ChartBorder.GetLeftEx()) return this.HorizontalMin;
  1301. if (x > this.ChartBorder.GetRightEx()) return this.HorizontalMax;
  1302. return (x - this.ChartBorder.GetLeftEx()) / this.ChartBorder.GetWidthEx() * (this.HorizontalMax - this.HorizontalMin) + this.HorizontalMin;
  1303. }
  1304. //X坐标转x轴数值
  1305. this.GetXData = function (y)
  1306. {
  1307. if (y <= this.ChartBorder.GetTop()) return 0;
  1308. if (y >= this.ChartBorder.GetBottom()) return this.XPointCount;
  1309. var count=this.XPointCount-1;
  1310. return (y - this.ChartBorder.GetTop()) * (count * 1.0 / this.ChartBorder.GetHeight());
  1311. }
  1312. this.GetXFromIndex = function (index)
  1313. {
  1314. var count = this.XPointCount - 1;
  1315. if (count == 1)
  1316. {
  1317. if (index == 0) return this.ChartBorder.GetTop();
  1318. else return this.ChartBorder.GetBottom();
  1319. }
  1320. else if (count <= 0)
  1321. {
  1322. return this.ChartBorder.GetTop();
  1323. }
  1324. else if (index >= count)
  1325. {
  1326. return this.ChartBorder.GetBottom();
  1327. }
  1328. else
  1329. {
  1330. var offset = this.ChartBorder.GetTop() + this.ChartBorder.GetHeight() * index / count;
  1331. return offset;
  1332. }
  1333. }
  1334. this.GetYFromData = function (value)
  1335. {
  1336. if (value <= this.HorizontalMin) return this.ChartBorder.GetLeftEx();
  1337. if (value >= this.HorizontalMax) return this.ChartBorder.GetRightEx();
  1338. var width = this.ChartBorder.GetWidthEx() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  1339. return this.ChartBorder.GetLeftEx() + width;
  1340. }
  1341. //画Y轴
  1342. this.DrawHorizontal = function ()
  1343. {
  1344. var top = this.ChartBorder.GetTop();
  1345. var bottom = this.ChartBorder.GetBottom();
  1346. var left=this.ChartBorder.GetLeft();
  1347. var right=this.ChartBorder.GetRight();
  1348. var borderTop = this.ChartBorder.Top;
  1349. var borderBottom = this.ChartBorder.Bottom;
  1350. var yPrev = null; //上一个坐标y的值
  1351. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从左往右画分割线
  1352. {
  1353. var item = this.HorizontalInfo[i];
  1354. var y = this.GetYFromData(item.Value);
  1355. if (y != null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  1356. this.Canvas.strokeStyle = item.LineColor;
  1357. this.Canvas.beginPath();
  1358. this.Canvas.moveTo(ToFixedPoint(y), top);
  1359. this.Canvas.lineTo(ToFixedPoint(y), bottom);
  1360. this.Canvas.stroke();
  1361. if (y >= right - 2)
  1362. {
  1363. this.Canvas.textBaseline = 'top';
  1364. y = right;
  1365. }
  1366. else if (y <= left + 2)
  1367. {
  1368. this.Canvas.textBaseline = 'bottom';
  1369. y=left;
  1370. if (y != null && Math.abs(y - yPrev) < 2*this.MinYDistance) continue; //两个坐标在近了 就不画了
  1371. }
  1372. else
  1373. {
  1374. this.Canvas.textBaseline = "middle";
  1375. }
  1376. //坐标信息 左边 间距小于10 不画坐标
  1377. if (item.Message[0] != null && borderTop > 10)
  1378. {
  1379. if (item.Font != null) this.Canvas.font = item.Font;
  1380. this.Canvas.fillStyle = item.TextColor;
  1381. this.Canvas.textAlign = "right";
  1382. //this.Canvas.textBaseline = "middle";
  1383. var xText = y, yText = top;
  1384. this.Canvas.save();
  1385. this.Canvas.translate(xText, yText);
  1386. this.Canvas.rotate(90 * Math.PI / 180);
  1387. this.Canvas.fillText(item.Message[0], -2, 0);
  1388. this.Canvas.restore();
  1389. }
  1390. //坐标信息 右边 间距小于10 不画坐标
  1391. if (item.Message[1] != null && borderBottom > 10)
  1392. {
  1393. if (item.Font != null) this.Canvas.font = item.Font;
  1394. this.Canvas.fillStyle = item.TextColor;
  1395. this.Canvas.textAlign = "left";
  1396. //this.Canvas.textBaseline = "middle";
  1397. var xText = y, yText = bottom;
  1398. this.Canvas.save();
  1399. this.Canvas.translate(xText, yText);
  1400. this.Canvas.rotate(90 * Math.PI / 180);
  1401. this.Canvas.fillText(item.Message[1], 2, 0);
  1402. this.Canvas.restore();
  1403. }
  1404. yPrev = y;
  1405. }
  1406. }
  1407. //画X轴
  1408. this.DrawVertical = function ()
  1409. {
  1410. var left = this.ChartBorder.GetLeft();
  1411. var right = this.ChartBorder.GetRightEx();
  1412. var bottom = this.ChartBorder.GetBottom();
  1413. var xPrev = null; //上一个坐标x的值
  1414. for (var i in this.VerticalInfo) {
  1415. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  1416. if (x > bottom) break;
  1417. if (xPrev != null && Math.abs(x - xPrev) < this.MinXDistance) continue;
  1418. this.Canvas.strokeStyle = this.VerticalInfo[i].LineColor;
  1419. this.Canvas.beginPath();
  1420. this.Canvas.moveTo(left, ToFixedPoint(x));
  1421. this.Canvas.lineTo(right, ToFixedPoint(x));
  1422. this.Canvas.stroke();
  1423. if (this.VerticalInfo[i].Message[0] != null) {
  1424. if (this.VerticalInfo[i].Font != null)
  1425. this.Canvas.font = this.VerticalInfo[i].Font;
  1426. this.Canvas.fillStyle = this.VerticalInfo[i].TextColor;
  1427. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  1428. if (x < testWidth / 2) {
  1429. this.Canvas.textAlign = "left";
  1430. this.Canvas.textBaseline = "top";
  1431. }
  1432. else if ((x + testWidth / 2) >= this.ChartBorder.GetChartHeight()) {
  1433. this.Canvas.textAlign = "right";
  1434. this.Canvas.textBaseline = "top";
  1435. }
  1436. else {
  1437. this.Canvas.textAlign = "center";
  1438. this.Canvas.textBaseline = "top";
  1439. }
  1440. var xText = left, yText = x;
  1441. this.Canvas.save();
  1442. this.Canvas.translate(xText, yText);
  1443. this.Canvas.rotate(90 * Math.PI / 180);
  1444. this.Canvas.fillText(this.VerticalInfo[i].Message[0], 0, 0);
  1445. this.Canvas.restore();
  1446. }
  1447. xPrev = x;
  1448. }
  1449. }
  1450. this.DrawNightDayBG=function()
  1451. {
  1452. if (this.DayCount!=1) return;
  1453. if (!this.HQChart) return;
  1454. if (!this.HQChart.EnableNightDayBG) return;
  1455. var symbol=this.HQChart.Symbol;
  1456. if (!symbol) return;
  1457. var xIndex=-1;
  1458. //获取夜盘和日期的分界线X索引位置
  1459. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_MINUTE_NIGHT_DAY_X_INDEX)
  1460. if (!event || !event.Callback) return;
  1461. var sendData={ Symbol:symbol, XIndex:xIndex, MinuteTimeStringData:g_MinuteTimeStringData };
  1462. event.Callback(event,sendData,this);
  1463. xIndex=sendData.XIndex;
  1464. if (xIndex<0) return;
  1465. var border=this.ChartBorder.GetHScreenBorder();
  1466. var y=this.GetXFromIndex(xIndex);
  1467. var rtNight={ Left: border.Left, Top:border.Top, Right:border.RightEx, Bottom:y };
  1468. rtNight.Width=rtNight.Right-rtNight.Left;
  1469. rtNight.Height=rtNight.Bottom-rtNight.Top;
  1470. this.Canvas.fillStyle = this.NightDayConfig.NightBGColor;
  1471. this.Canvas.fillRect(rtNight.Left, rtNight.Top, rtNight.Width, rtNight.Height);
  1472. if (this.Identify!=0) return;
  1473. //显示 日盘夜盘文字
  1474. this.Canvas.font=this.NightDayConfig.Font;
  1475. this.Canvas.textBaseline = "bottom";
  1476. this.Canvas.textAlign = 'left';
  1477. var aryTitle=[{ Title:"夜盘", Position:1, Config:this.NightDayConfig.Night }, { Title:"日盘", Position:0,Config:this.NightDayConfig.Day }];
  1478. var textHeight= this.Canvas.measureText("擎").width;
  1479. for(var i=0;i<aryTitle.length;++i)
  1480. {
  1481. var item=aryTitle[i];
  1482. var text=g_JSChartLocalization.GetText(item.Title,this.HQChart.LanguageID);
  1483. var testWidth = this.Canvas.measureText(text).width;
  1484. var rtItem=
  1485. {
  1486. Height:testWidth+item.Config.Margin.Left+item.Config.Margin.Right,
  1487. Width:textHeight+item.Config.Margin.Top+item.Config.Margin.Bottom,
  1488. Left:border.Left
  1489. };
  1490. rtItem.Right=rtItem.Left+rtItem.Width;
  1491. if (item.Position===1)
  1492. {
  1493. rtItem.Bottom=y-1;
  1494. rtItem.Top=rtItem.Bottom-rtItem.Height;
  1495. }
  1496. else
  1497. {
  1498. rtItem.Top=y+1;
  1499. rtItem.Bottom=rtItem.Top+rtItem.Height;
  1500. }
  1501. if (item.Config.BGColor)
  1502. {
  1503. this.Canvas.fillStyle = item.Config.BGColor;
  1504. this.Canvas.fillRect(rtItem.Left, rtItem.Top, rtItem.Width, rtItem.Height);
  1505. }
  1506. if (item.Config.BorderColor)
  1507. {
  1508. this.Canvas.strokeStyle = item.Config.BorderColor;
  1509. this.Canvas.strokeRect(ToFixedPoint(rtItem.Left), ToFixedPoint(rtItem.Top), ToFixedRect(rtItem.Width), ToFixedRect(rtItem.Height));
  1510. }
  1511. this.Canvas.fillStyle = item.Config.Color;
  1512. var xText=rtItem.Left;
  1513. var yText=rtItem.Top;
  1514. this.Canvas.save();
  1515. this.Canvas.translate(xText,yText);
  1516. this.Canvas.rotate(90 * Math.PI / 180);
  1517. this.Canvas.fillText(text, item.Config.Margin.Left, -item.Config.Margin.Bottom);
  1518. this.Canvas.restore();
  1519. }
  1520. }
  1521. }
  1522. function OverlayMinuteFrame()
  1523. {
  1524. this.newMethod=MinuteFrame; //派生
  1525. this.newMethod();
  1526. delete this.newMethod;
  1527. this.ClassName="OverlayMinuteFrame";
  1528. this.IsShow=true; //坐标是否显示
  1529. this.IsShareY=false; //使用和主框架公用Y轴
  1530. this.IsCalculateYMaxMin=true; //是否计算Y最大最小值
  1531. this.Draw=function()
  1532. {
  1533. this.SplitXYCoordinate();
  1534. if (this.IsShow)
  1535. {
  1536. }
  1537. this.SizeChange=false;
  1538. this.XYSplit=false;
  1539. this.XSplit=false;
  1540. this.YCustomSplit=false;
  1541. }
  1542. this.GetScaleTextWidth=function()
  1543. {
  1544. return { TextWidth:0 };
  1545. }
  1546. //分割x,y轴坐标信息
  1547. this.SplitXYCoordinate=function()
  1548. {
  1549. if (this.XYSplit==false) return;
  1550. if (this.IsShareY) //和主图指标共享Y轴坐标
  1551. {
  1552. this.HorizontalMax=this.MainFrame.HorizontalMax;
  1553. this.HorizontalMin=this.MainFrame.HorizontalMin;
  1554. this.HorizontalInfo=[];
  1555. for(var i=0; i<this.MainFrame.HorizontalInfo.length; ++i)
  1556. {
  1557. var item=this.MainFrame.HorizontalInfo[i];
  1558. this.HorizontalInfo.push(item);
  1559. }
  1560. }
  1561. else //独立Y轴坐标
  1562. {
  1563. if (this.YSplitOperator!=null) this.YSplitOperator.Operator();
  1564. }
  1565. }
  1566. }
  1567. function OverlayMinuteHScreenFrame()
  1568. {
  1569. this.newMethod=MinuteHScreenFrame; //派生
  1570. this.newMethod();
  1571. delete this.newMethod;
  1572. this.ClassName="OverlayMinuteHScreenFrame";
  1573. this.IsShow=true; //坐标是否显示
  1574. this.Draw=function()
  1575. {
  1576. this.SplitXYCoordinate();
  1577. if (this.IsShow)
  1578. {
  1579. }
  1580. this.SizeChange=false;
  1581. this.XYSplit=false;
  1582. }
  1583. //分割x,y轴坐标信息
  1584. this.SplitXYCoordinate=function()
  1585. {
  1586. if (this.XYSplit==false) return;
  1587. if (this.IsShareY) //和主图指标共享Y轴坐标
  1588. {
  1589. this.HorizontalMax=this.MainFrame.HorizontalMax;
  1590. this.HorizontalMin=this.MainFrame.HorizontalMin;
  1591. this.HorizontalInfo=[];
  1592. for(var i=0; i<this.MainFrame.HorizontalInfo.length; ++i)
  1593. {
  1594. var item=this.MainFrame.HorizontalInfo[i];
  1595. this.HorizontalInfo.push(item);
  1596. }
  1597. }
  1598. else //独立Y轴坐标
  1599. {
  1600. if (this.YSplitOperator!=null) this.YSplitOperator.Operator();
  1601. }
  1602. }
  1603. }
  1604. //缩放因子
  1605. var ZOOM_SEED = //0=柱子宽度 1=间距
  1606. [
  1607. [48, 10], [44, 10],
  1608. [40, 9], [36, 9],
  1609. [32, 8], [28, 8],
  1610. [24, 7], [20, 7],
  1611. [18, 6], [17, 6],
  1612. [15, 5], [13, 5],
  1613. [9, 4], [5, 4], [3, 3],
  1614. [3, 1], [2,1], [1,1], [1,0]
  1615. /*
  1616. [49, 10], [46, 9], [43, 8],
  1617. [41, 7.5], [39, 7], [37, 6],
  1618. [31, 5.5], [27, 5], [23, 4.5],
  1619. [21, 4], [18, 3.5], [16, 3],
  1620. [13, 2.5], [11, 2], [8, 1.5],
  1621. [6, 1], [3, 0.6], [2.2, 0.5],
  1622. */
  1623. //太多了卡,
  1624. //[1.1,0.3],
  1625. //[0.9,0.2], [0.7,0.15],
  1626. //[0.6,0.12], [0.5,0.1], [0.4,0.08],
  1627. //[0.3,0.06], [0.2,0.04], [0.1,0.02]
  1628. ];
  1629. //K线框架
  1630. function KLineFrame()
  1631. {
  1632. this.newMethod = AverageWidthFrame; //派生
  1633. this.newMethod();
  1634. delete this.newMethod;
  1635. this.ClassName='KLineFrame';
  1636. this.ToolbarID = Guid(); //工具条Div id
  1637. this.ModifyIndex = true; //是否显示'改参数'菜单
  1638. this.ChangeIndex = true; //是否显示'换指标'菜单
  1639. this.CustomHorizontalInfo = [];
  1640. this.LastCalculateStatus = { Width: 0, XPointCount: 0 }; //最后一次计算宽度的状态
  1641. //定制X轴刻度
  1642. //Type:0, Date:, Time: , Name:名字, Line:{ Color:线段颜色, Type:线段类型 0 直线 1 虚线 }
  1643. //Type: 1, Space: 第几个空白间距, Name:名字, Line: { Color: 线段颜色, Type: 线段类型 0 直线 1 虚线 }
  1644. this.CustomVerticalInfo = [];
  1645. this.DrawCustomVerticalEvent;
  1646. this.RightSpaceCount = 0;
  1647. this.TitleBorderLine=
  1648. {
  1649. Color:g_JSChartResource.Frame.TitleBorderLine.Color,
  1650. Dash:g_JSChartResource.Frame.TitleBorderLine.Dash
  1651. };//标题栏底部边框线
  1652. this.DrawFrame = function ()
  1653. {
  1654. if (this.IsMinSize) return;
  1655. this.SplitXYCoordinate();
  1656. if (this.SizeChange == true) this.CalculateDataWidth();
  1657. if (this.DrawOtherChart) this.DrawOtherChart();
  1658. this.DrawTitleBG();
  1659. this.DrawHorizontal();
  1660. this.DrawVertical();
  1661. }
  1662. this.GetXFromIndex = function (index)
  1663. {
  1664. if (index < 0) index = 0;
  1665. if (index > this.xPointCount - 1) index = this.xPointCount - 1;
  1666. var offset = this.ChartBorder.GetLeft() + g_JSChartResource.FrameLeftMargin + this.DistanceWidth / 2 + this.DataWidth / 2;
  1667. for (var i = 1; i <= index; ++i) { offset += this.DistanceWidth + this.DataWidth; }
  1668. return offset;
  1669. }
  1670. //X坐标转x轴数值
  1671. this.GetXData = function (x)
  1672. {
  1673. if (x <= this.ChartBorder.GetLeft()) return 0;
  1674. if (x >= this.ChartBorder.GetRight()) return this.XPointCount-1;
  1675. var left=this.ChartBorder.GetLeft()+g_JSChartResource.FrameLeftMargin;
  1676. var right=this.ChartBorder.GetRight()-g_JSChartResource.FrameRightMargin;
  1677. var distanceWidth = this.DistanceWidth;
  1678. var dataWidth = this.DataWidth;
  1679. var index = 0;
  1680. var xPoint = left + distanceWidth/2 + dataWidth + distanceWidth;
  1681. while (xPoint < right && index < 10000 && index+1<this.XPointCount ) //自己算x的数值
  1682. {
  1683. if (xPoint > x) break;
  1684. xPoint += (dataWidth + distanceWidth);
  1685. ++index;
  1686. }
  1687. //var test=(x-this.ChartBorder.GetLeft())*(this.XPointCount*1.0/this.ChartBorder.GetWidth());
  1688. return index;
  1689. }
  1690. this.DrawCustomHorizontal = function () //Y轴刻度定制显示
  1691. {
  1692. if (this.IsMinSize) return;
  1693. for (var i=0; i<this.CustomHorizontalInfo.length; ++i)
  1694. {
  1695. var item = this.CustomHorizontalInfo[i];
  1696. switch (item.Type)
  1697. {
  1698. case 0: //最新价格刻度
  1699. case 1: //固定价格刻度
  1700. this.DrawCustomItem(item);
  1701. break;
  1702. case 2: //当前屏最后一个K线价格刻度
  1703. case 3: //主图K线涨幅刻度
  1704. case 4: //叠加K线涨幅刻度
  1705. this.DrawCustomItem(item);
  1706. }
  1707. }
  1708. }
  1709. this.DrawCustomVerticalItem = function (item) {
  1710. this.Canvas.save();
  1711. if (item.Data.Line.Type == 1) this.Canvas.setLineDash([5, 5]); //虚线
  1712. this.Canvas.strokeStyle = item.Data.Line.Color;
  1713. this.Canvas.beginPath();
  1714. if (item.IsHScreen) {
  1715. this.Canvas.moveTo(item.Top, ToFixedPoint(item.X));
  1716. this.Canvas.lineTo(item.Bottom, ToFixedPoint(item.X));
  1717. }
  1718. else {
  1719. this.Canvas.moveTo(ToFixedPoint(item.X), item.Top);
  1720. this.Canvas.lineTo(ToFixedPoint(item.X), item.Bottom);
  1721. }
  1722. this.Canvas.stroke();
  1723. this.Canvas.restore();
  1724. }
  1725. this.DrawCustomVertical = function () //X轴定制刻度显示
  1726. {
  1727. if (!this.CustomVerticalInfo) return;
  1728. if (this.CustomVerticalInfo.length <= 0) return;
  1729. if (!this.Data) return;
  1730. var isHScreen = this.IsHScreen;
  1731. var top = this.ChartBorder.GetTopEx();
  1732. var bottom = this.ChartBorder.GetBottomEx();
  1733. var dataWidth = this.DataWidth;
  1734. var distanceWidth = this.DistanceWidth;
  1735. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  1736. if (isHScreen)
  1737. {
  1738. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  1739. top = this.ChartBorder.GetLeftEx();
  1740. bottom = this.ChartBorder.GetRightEx();
  1741. }
  1742. var j = 0;
  1743. for (var i = this.Data.DataOffset; i < this.Data.Data.length && j < this.XPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  1744. {
  1745. var kItem = this.Data.Data[i];
  1746. for (var k in this.CustomVerticalInfo)
  1747. {
  1748. var item = this.CustomVerticalInfo[k];
  1749. if (item.Type != 0) continue;
  1750. if (IFrameSplitOperator.IsNumber(item.Time))
  1751. {
  1752. if (kItem.Date != item.Date || kItem.Time != item.Time) continue;
  1753. }
  1754. else
  1755. {
  1756. if (kItem.Date != item.Date) continue;
  1757. }
  1758. var left = xOffset;
  1759. var right = xOffset + dataWidth;
  1760. var x = left + (right - left) / 2;
  1761. var DrawData = { X: x, Top: top, Bottom: bottom, Data: item, IsHScreen: isHScreen };
  1762. this.DrawCustomVerticalItem(DrawData);
  1763. if (this.DrawCustomVerticalEvent)
  1764. this.DrawCustomVerticalEvent.Callback(this.DrawCustomVerticalEvent, DrawData, this);
  1765. break;
  1766. }
  1767. }
  1768. for (var i = 1; j < this.XPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  1769. {
  1770. for (var k in this.CustomVerticalInfo)
  1771. {
  1772. var item = this.CustomVerticalInfo[k];
  1773. if (item.Type != 1) continue;
  1774. if (item.Space != i) continue;
  1775. var left = xOffset;
  1776. var right = xOffset + dataWidth;
  1777. var x = left + (right - left) / 2;
  1778. var DrawData = { X: x, Top: top, Bottom: bottom, Data: item, IsHScreen: isHScreen };
  1779. this.DrawCustomVerticalItem(DrawData);
  1780. if (this.DrawCustomVerticalEvent)
  1781. this.DrawCustomVerticalEvent.Callback(this.DrawCustomVerticalEvent, DrawData, this);
  1782. break;
  1783. }
  1784. }
  1785. }
  1786. this.CalculateDataWidth = function () //计算数据宽度
  1787. {
  1788. if (this.XPointCount < 2) return;
  1789. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin; //预留4个像素 防止最后1个柱子不够画
  1790. if (this.ZoomIndex>=0 && this.LastCalculateStatus.Width==width && this.LastCalculateStatus.XPointCount==this.XPointCount) //宽度没变 尝试使用原来的柱子宽度
  1791. {
  1792. var caclWidth=(this.DistanceWidth/2+g_JSChartResource.FrameLeftMargin)+(this.DataWidth + this.DistanceWidth)*(this.XPointCount-1);
  1793. var caclWidth2=(this.DataWidth + this.DistanceWidth) * this.XPointCount;
  1794. if (caclWidth<= width) //当前的柱子宽度够用 就不调整了
  1795. return;
  1796. }
  1797. this.LastCalculateStatus.Width=width;
  1798. this.LastCalculateStatus.XPointCount=this.XPointCount;
  1799. for (var i = 0; i < ZOOM_SEED.length; ++i)
  1800. {
  1801. let barWidth = ZOOM_SEED[i][0]; //数据宽度
  1802. let distanceWidth = ZOOM_SEED[i][1]; //间距宽度
  1803. if ((ZOOM_SEED[i][0] + ZOOM_SEED[i][1]) * this.XPointCount < width)
  1804. {
  1805. this.ZoomIndex = i;
  1806. this.DataWidth = ZOOM_SEED[i][0];
  1807. this.DistanceWidth = ZOOM_SEED[i][1];
  1808. this.TrimKLineDataWidth(width);
  1809. JSConsole.Chart.Log(`[KLineFrame::CalculateDataWidth] ZoomIndex=${this.ZoomIndex} DataWidth=${this.DataWidth} DistanceWidth=${this.DistanceWidth}` );
  1810. return;
  1811. }
  1812. }
  1813. //太多了 就平均分了
  1814. this.ZoomIndex = ZOOM_SEED.length - 1;
  1815. this.DataWidth = width / this.XPointCount;
  1816. this.DistanceWidth = 0;
  1817. }
  1818. this.OnSize=function(obj)
  1819. {
  1820. var width=this.GetFrameWidth()-g_JSChartResource.FrameMargin;
  1821. var xPointCount=0;
  1822. var y=this.DistanceWidth/2+g_JSChartResource.FrameLeftMargin+(this.DataWidth+this.DistanceWidth);
  1823. for(;y<width; y+=(this.DataWidth+this.DistanceWidth), ++xPointCount) { }
  1824. obj.CurCount=this.XPointCount;
  1825. obj.CalcCount=xPointCount;
  1826. obj.DataWidth=this.DataWidth;
  1827. obj.DistanceWidth=this.DistanceWidth;
  1828. obj.Changed=false;
  1829. this.LastCalculateStatus.Width=width;
  1830. if (obj.CurCount==obj.CalcCount) return obj;
  1831. this.XPointCount=xPointCount;
  1832. this.LastCalculateStatus.XPointCount=this.XPointCount;
  1833. if (this.Data)
  1834. {
  1835. this.Data.DataOffset+=(obj.CurCount-obj.CalcCount);
  1836. if (this.Data.DataOffset<0) this.Data.DataOffset=0;
  1837. obj.Changed=true;
  1838. }
  1839. return obj;
  1840. }
  1841. this.SetDataWidth=function(dataWidth)
  1842. {
  1843. var zoomIndex=ZOOM_SEED.length-1;
  1844. for(var i in ZOOM_SEED)
  1845. {
  1846. var item=ZOOM_SEED[i];
  1847. if (item[0]<=dataWidth)
  1848. {
  1849. zoomIndex=parseInt(i)-1;
  1850. break;
  1851. }
  1852. }
  1853. this.ZoomIndex=zoomIndex;
  1854. this.DataWidth=ZOOM_SEED[this.ZoomIndex][0];
  1855. this.DistanceWidth=ZOOM_SEED[this.ZoomIndex][1];
  1856. var width=this.GetFrameWidth()-g_JSChartResource.FrameMargin;
  1857. var xPointCount=0;
  1858. var y=this.DistanceWidth/2+g_JSChartResource.FrameLeftMargin+(this.DataWidth+this.DistanceWidth);
  1859. for(;y<=width; y+=(this.DataWidth+this.DistanceWidth), ++xPointCount) { }
  1860. this.XPointCount=xPointCount;
  1861. this.LastCalculateStatus.XPointCount=this.XPointCount;
  1862. this.LastCalculateStatus.Width=width;
  1863. var obj={ XPointCount:this.XPointCount, DataWidth:this.DataWidth, DistanceWidth:this.DistanceWidth };
  1864. return obj;
  1865. }
  1866. this.TrimKLineDataWidth = function (width)
  1867. {
  1868. var zoom = ZOOM_SEED[this.ZoomIndex];
  1869. var dataWidth = ZOOM_SEED[this.ZoomIndex][0];
  1870. var distanceWidth = ZOOM_SEED[this.ZoomIndex][1];
  1871. if (dataWidth == 1 && distanceWidth == 0)
  1872. {
  1873. this.DataWidth = width / this.XPointCount;
  1874. return;
  1875. }
  1876. while(true)
  1877. {
  1878. if((this.DistanceWidth + this.DataWidth) * this.XPointCount + this.DistanceWidth > width)
  1879. {
  1880. this.DistanceWidth -= 0.01;
  1881. break;
  1882. }
  1883. this.DistanceWidth += 0.01;
  1884. }
  1885. /*
  1886. if (zoom[0]<4) //最后2个缩放,调整间距不调整数据宽度, 数据都是画竖线的
  1887. {
  1888. while (true)
  1889. {
  1890. if ((this.DistanceWidth + this.DataWidth) * this.XPointCount + this.DistanceWidth > width)
  1891. {
  1892. this.DistanceWidth -= 0.01;
  1893. break;
  1894. }
  1895. this.DistanceWidth += 0.01;
  1896. }
  1897. }
  1898. else
  1899. {
  1900. while (true)
  1901. {
  1902. if ((this.DistanceWidth + this.DataWidth) * this.XPointCount + this.DistanceWidth > width)
  1903. {
  1904. this.DataWidth -= 0.01;
  1905. break;
  1906. }
  1907. this.DataWidth += 0.01;
  1908. }
  1909. }
  1910. */
  1911. }
  1912. this.IsOverlayMaxMin = function (obj) //当前坐标信息 是否覆盖最大 最小值输出
  1913. {
  1914. if (!this.ChartKLine) return false;
  1915. if (!this.ChartKLine.Max || !this.ChartKLine.Min) return false;
  1916. var textWidth = this.Canvas.measureText(obj.Text.Value).width + 4; //刻度文字宽度
  1917. var max = this.ChartKLine.Max, min = this.ChartKLine.Min;
  1918. var isOverlayMax = false, isOverlayMin = false;
  1919. const textHeight = 20; //字体高度
  1920. if (max.X >= obj.X && max.X <= obj.X + textWidth)
  1921. {
  1922. var y1 = max.Y + textHeight, y2 = max.Y - textHeight;
  1923. if ((y1 >= obj.Y - textHeight && y1 <= obj.Y + textHeight) || (y2 >= obj.Y - textHeight && y2 <= obj.Y + textHeight))
  1924. isOverlayMax = true;
  1925. }
  1926. if (isOverlayMax == true) return true;
  1927. if (min.X >= obj.X && min.X <= obj.X + textWidth) //最小值X 坐标不在 刻度文字范围内
  1928. {
  1929. var y1 = min.Y + textHeight, y2 = min.Y - textHeight;
  1930. if ((y1 >= obj.Y - textHeight && y1 <= obj.Y + textHeight) || (y2 >= obj.Y - textHeight && y2 <= obj.Y + textHeight))
  1931. isOverlayMin = true;
  1932. }
  1933. return isOverlayMax || isOverlayMin;
  1934. }
  1935. //分割x,y轴坐标信息
  1936. this.SplitXYCoordinate = function ()
  1937. {
  1938. if (this.XYSplit == false)
  1939. {
  1940. if (this.XSplit)
  1941. {
  1942. if (this.XSplitOperator) this.XSplitOperator.Operator();
  1943. }
  1944. if (this.YCustomSplit)
  1945. {
  1946. if (this.YSplitOperator && this.YSplitOperator.CustomCoordinate) this.YSplitOperator.CustomCoordinate();
  1947. }
  1948. return;
  1949. }
  1950. if (this.YSplitOperator != null) this.YSplitOperator.Operator();
  1951. if (this.XSplitOperator != null) this.XSplitOperator.Operator();
  1952. }
  1953. this.CalculateCount = function (zoomIndex)
  1954. {
  1955. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin;
  1956. return parseInt(width / (ZOOM_SEED[zoomIndex][0] + ZOOM_SEED[zoomIndex][1]));
  1957. }
  1958. this.ZoomUp = function (cursorIndex)
  1959. {
  1960. if (this.ZoomIndex <= 0) return false;
  1961. if (this.Data.DataOffset < 0) return false;
  1962. var dataCount = this.Data.Data.length;
  1963. var maxDataCount = dataCount + this.RightSpaceCount;
  1964. var rightSpaceCount = 0;
  1965. var lastDataIndex = this.Data.DataOffset + this.XPointCount - 1; //最右边的数据索引
  1966. var lastCursorIndex = this.Data.DataOffset + cursorIndex.Index;
  1967. if (lastDataIndex >= dataCount)
  1968. {
  1969. rightSpaceCount = lastDataIndex - (this.Data.Data.length - 1); //计算右边预留空间
  1970. lastDataIndex = this.Data.Data.length - 1;
  1971. if (rightSpaceCount > this.RightSpaceCount) rightSpaceCount = this.RightSpaceCount;
  1972. }
  1973. var xPointCount = this.CalculateCount(this.ZoomIndex-1);
  1974. --this.ZoomIndex;
  1975. this.XPointCount = xPointCount;
  1976. if (cursorIndex.IsLockRight==true) //固定右边
  1977. {
  1978. var rightDataIndex=this.Data.DataOffset + this.XPointCount; //最右边的数据索引
  1979. if (xPointCount>rightDataIndex)
  1980. {
  1981. xPointCount=rightDataIndex;
  1982. this.XPointCount=xPointCount;
  1983. this.Data.DataOffset=0;
  1984. }
  1985. else
  1986. {
  1987. var dataOffset=lastDataIndex - (xPointCount-rightSpaceCount)+1;
  1988. this.XPointCount=xPointCount;
  1989. this.Data.DataOffset=dataOffset;
  1990. if (this.Data.DataOffset<0) this.Data.DataOffset=0;
  1991. }
  1992. }
  1993. else if (xPointCount >= maxDataCount)
  1994. {
  1995. xPointCount = maxDataCount;
  1996. this.XPointCount = xPointCount;
  1997. this.Data.DataOffset = 0;
  1998. }
  1999. else
  2000. {
  2001. this.XPointCount = xPointCount;
  2002. this.Data.DataOffset = lastDataIndex - (this.XPointCount - rightSpaceCount) + 1;
  2003. if (this.Data.DataOffset<0)
  2004. {
  2005. JSConsole.Chart.Log(`[KLineFrame::ZoomDown] this.Data.DataOffset=${this.Data.DataOffset}, reset this.Data.DataOffset=0`);
  2006. this.Data.DataOffset=0;
  2007. }
  2008. }
  2009. this.DataWidth = ZOOM_SEED[this.ZoomIndex][0];
  2010. this.DistanceWidth = ZOOM_SEED[this.ZoomIndex][1];
  2011. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin;
  2012. this.TrimKLineDataWidth(width);
  2013. this.LastCalculateStatus.XPointCount = this.XPointCount;
  2014. cursorIndex.Index = lastCursorIndex - this.Data.DataOffset;
  2015. return true;
  2016. }
  2017. this.ZoomDown = function (cursorIndex)
  2018. {
  2019. if (this.ZoomIndex + 1 >= ZOOM_SEED.length) return false;
  2020. if (this.Data.DataOffset < 0) return false;
  2021. if (this.Data.DataOffset<=0 && cursorIndex.IsLockRight==true) return false;
  2022. var dataCount = this.Data.Data.length;
  2023. var maxDataCount = dataCount + this.RightSpaceCount;
  2024. //if (this.XPointCount >= dataCount) return false;
  2025. var rightSpaceCount = 0;
  2026. var lastDataIndex = this.Data.DataOffset + this.XPointCount - 1; //最右边的数据索引
  2027. if (lastDataIndex >= this.Data.Data.length)
  2028. {
  2029. rightSpaceCount = lastDataIndex - (this.Data.Data.length - 1); //计算右边预留空间
  2030. lastDataIndex = this.Data.Data.length - 1;
  2031. if (rightSpaceCount > this.RightSpaceCount) rightSpaceCount = this.RightSpaceCount;
  2032. }
  2033. var xPointCount = this.CalculateCount(this.ZoomIndex + 1);
  2034. var lastCursorIndex = this.Data.DataOffset + cursorIndex.Index;
  2035. ++this.ZoomIndex;
  2036. if (cursorIndex.IsLockRight==true) //固定右边
  2037. {
  2038. var rightDataIndex=this.Data.DataOffset + this.XPointCount; //最右边的数据索引
  2039. if (xPointCount>rightDataIndex)
  2040. {
  2041. xPointCount=rightDataIndex;
  2042. this.XPointCount=xPointCount;
  2043. this.Data.DataOffset=0;
  2044. }
  2045. else
  2046. {
  2047. var dataOffset=lastDataIndex - (xPointCount-rightSpaceCount)+1;
  2048. this.XPointCount=xPointCount;
  2049. this.Data.DataOffset=dataOffset;
  2050. if (this.Data.DataOffset<0) this.Data.DataOffset=0;
  2051. }
  2052. }
  2053. else if (xPointCount >= maxDataCount)
  2054. {
  2055. //xPointCount = maxDataCount;
  2056. this.XPointCount = xPointCount;
  2057. this.Data.DataOffset = 0;
  2058. }
  2059. else
  2060. {
  2061. this.XPointCount = xPointCount;
  2062. this.Data.DataOffset = lastDataIndex - (this.XPointCount - rightSpaceCount) + 1;
  2063. if (this.Data.DataOffset<0)
  2064. {
  2065. JSConsole.Chart.Log(`[KLineFrame::ZoomDown] this.Data.DataOffset=${this.Data.DataOffset}, reset this.Data.DataOffset=0`);
  2066. this.Data.DataOffset=0;
  2067. }
  2068. }
  2069. this.DataWidth = ZOOM_SEED[this.ZoomIndex][0];
  2070. this.DistanceWidth = ZOOM_SEED[this.ZoomIndex][1];
  2071. var width = this.GetFrameWidth() - g_JSChartResource.FrameMargin;
  2072. this.TrimKLineDataWidth(width);
  2073. this.LastCalculateStatus.XPointCount = this.XPointCount;
  2074. cursorIndex.Index = lastCursorIndex - this.Data.DataOffset;
  2075. return true;
  2076. }
  2077. this.GetFrameWidth = function ()
  2078. {
  2079. if (this.IsHScreen) return this.ChartBorder.GetHeight();
  2080. return this.ChartBorder.GetWidth();
  2081. }
  2082. this.SetXShowCount=function(showCount)
  2083. {
  2084. var index=-1;
  2085. var width=this.GetFrameWidth()-g_JSChartResource.FrameMargin;
  2086. for(var i=0; i<ZOOM_SEED.length; ++i)
  2087. {
  2088. var item=ZOOM_SEED[i];
  2089. var dataWidth=item[0];
  2090. var distanceWidth=item[1];
  2091. var width=this.GetFrameWidth()-g_JSChartResource.FrameMargin-distanceWidth/2;
  2092. var value=parseInt((width-distanceWidth/2)/(dataWidth + distanceWidth));
  2093. if (value>=showCount)
  2094. {
  2095. index=i;
  2096. this.XPointCount=showCount;
  2097. this.ZoomIndex=index;
  2098. this.DataWidth=dataWidth;
  2099. this.DistanceWidth=distanceWidth;
  2100. if (dataWidth==1 && distanceWidth==0)
  2101. this.DataWidth=width/this.XPointCount;
  2102. this.LastCalculateStatus.XPointCount=this.XPointCount;
  2103. this.LastCalculateStatus.Width=width;
  2104. return;
  2105. }
  2106. }
  2107. //太多了 就平均分了
  2108. this.XPointCount=showCount;
  2109. this.ZoomIndex=ZOOM_SEED.length-1;
  2110. this.DataWidth=width/this.XPointCount;
  2111. this.DistanceWidth=0;
  2112. this.LastCalculateStatus.XPointCount=this.XPointCount;
  2113. this.LastCalculateStatus.Width=width;
  2114. }
  2115. //画标题背景色
  2116. this.DrawTitleBG=function()
  2117. {
  2118. if (!this.TitleBorderLine || !this.TitleBorderLine.Color) return;
  2119. var border=this.GetBorder();
  2120. if (this.ChartBorder.TopSpace<5) return;
  2121. this.Canvas.save();
  2122. this.Canvas.strokeStyle=this.TitleBorderLine.Color;
  2123. if (this.TitleBorderLine.Dash) this.Canvas.setLineDash(this.TitleBorderLine.Dash); //虚线
  2124. var x=ToFixedPoint(border.TopTitle);
  2125. this.Canvas.beginPath();
  2126. this.Canvas.moveTo(border.Left,x);
  2127. this.Canvas.lineTo(border.Right,x);
  2128. this.Canvas.stroke();
  2129. this.Canvas.restore();
  2130. }
  2131. }
  2132. //K线横屏框架
  2133. function KLineHScreenFrame()
  2134. {
  2135. this.newMethod = KLineFrame; //派生
  2136. this.newMethod();
  2137. delete this.newMethod;
  2138. this.ClassName='KLineHScreenFrame';
  2139. this.IsHScreen = true; //是否是横屏
  2140. this.DrawInsideHorizontal = function ()
  2141. {
  2142. if (this.IsMinSize) return;
  2143. if (this.IsShowYText[0] === false && this.IsShowYText[1] === false) return;
  2144. var left = this.ChartBorder.GetLeft();
  2145. var right = this.ChartBorder.GetRightEx();
  2146. var top = this.ChartBorder.GetTop();
  2147. var bottom = this.ChartBorder.GetBottom();
  2148. var borderTop = this.ChartBorder.Top;
  2149. var borderBottom = this.ChartBorder.Bottom;
  2150. var titleHeight = this.ChartBorder.TitleHeight;
  2151. var pixelTatio = 1;
  2152. var isDrawLeft = (borderTop < 10 * pixelTatio || this.YTextPosition[0] == 2) && this.IsShowYText[0] === true;
  2153. var isDrawRight = (borderBottom < 10 * pixelTatio || this.YTextPosition[1] == 2) && this.IsShowYText[1] === true;
  2154. if (isDrawLeft || isDrawRight)
  2155. {
  2156. var yPrev = null; //上一个坐标y的值
  2157. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从上往下画分割线
  2158. {
  2159. var item = this.HorizontalInfo[i];
  2160. var y = this.GetYFromData(item.Value);
  2161. if (y != null && yPrev != null && Math.abs(y - yPrev) < this.MinYDistance) continue; //两个坐标在近了 就不画了
  2162. //坐标信息 左边 间距小于10 画在内部
  2163. if (item.Message[0] != null && isDrawLeft)
  2164. {
  2165. if (item.Font != null) this.Canvas.font = item.Font;
  2166. this.Canvas.fillStyle = item.TextColor;
  2167. this.Canvas.textAlign = "left";
  2168. if (y >= right - 2) this.Canvas.textBaseline = 'top';
  2169. else if (y <= left + 2) this.Canvas.textBaseline = 'bottom';
  2170. else this.Canvas.textBaseline = "middle";
  2171. var textObj = { X: left, Y: y, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[0] } };
  2172. var xText = y, yText = top;
  2173. this.Canvas.save();
  2174. this.Canvas.translate(xText, yText);
  2175. this.Canvas.rotate(90 * Math.PI / 180);
  2176. this.Canvas.fillText(item.Message[0], 2, 0);
  2177. this.Canvas.restore();
  2178. }
  2179. if (item.Message[1] != null && isDrawRight)
  2180. {
  2181. if (item.Font != null) this.Canvas.font = item.Font;
  2182. this.Canvas.fillStyle = item.TextColor;
  2183. this.Canvas.textAlign = "right";
  2184. if (y >= right - 2) this.Canvas.textBaseline = 'top';
  2185. else if (y <= left + 2) this.Canvas.textBaseline = 'bottom';
  2186. else this.Canvas.textBaseline = "middle";
  2187. var textWidth = this.Canvas.measureText(item.Message[1]).width;
  2188. var textObj = { X: right - textWidth, Y: y, Text: { BaseLine: this.Canvas.textBaseline, TextAlign: this.Canvas.textAlign, Font: this.Canvas.font, Value: item.Message[1] } };
  2189. var xText = y, yText = bottom;
  2190. this.Canvas.save();
  2191. this.Canvas.translate(xText, yText);
  2192. this.Canvas.rotate(90 * Math.PI / 180);
  2193. this.Canvas.fillText(item.Message[1], -2, 0);
  2194. this.Canvas.restore();
  2195. }
  2196. yPrev = y;
  2197. }
  2198. }
  2199. }
  2200. //画标题背景色
  2201. this.DrawTitleBG = function ()
  2202. {
  2203. /*
  2204. if (this.ChartBorder.TitleHeight <= 0) return;
  2205. var left = ToFixedPoint(this.ChartBorder.GetRightEx());
  2206. var top = ToFixedPoint(this.ChartBorder.GetTop());
  2207. var bottom = ToFixedPoint(this.ChartBorder.GetBottom());
  2208. var width = this.ChartBorder.TitleHeight;
  2209. var height = bottom - top;
  2210. this.Canvas.fillStyle = this.TitleBGColor;
  2211. this.Canvas.fillRect(left, top, width, height);
  2212. */
  2213. }
  2214. this.GetYFromData = function (value)
  2215. {
  2216. if (value <= this.HorizontalMin) return this.ChartBorder.GetLeftEx();
  2217. if (value >= this.HorizontalMax) return this.ChartBorder.GetRightEx();
  2218. var width = this.ChartBorder.GetWidthEx() * (value - this.HorizontalMin) / (this.HorizontalMax - this.HorizontalMin);
  2219. return this.ChartBorder.GetLeftEx() + width;
  2220. }
  2221. //画Y轴
  2222. this.DrawHorizontal = function ()
  2223. {
  2224. var top = this.ChartBorder.GetTop();
  2225. var bottom = this.ChartBorder.GetBottom();
  2226. var borderTop = this.ChartBorder.Top;
  2227. var borderBottom = this.ChartBorder.Bottom;
  2228. var left=this.ChartBorder.GetLeft();
  2229. var yPrev = null; //上一个坐标y的值
  2230. for (var i = this.HorizontalInfo.length - 1; i >= 0; --i) //从左往右画分割线
  2231. {
  2232. var item = this.HorizontalInfo[i];
  2233. var y = this.GetYFromData(item.Value);
  2234. if (y != null && Math.abs(y - yPrev) < 15) continue; //两个坐标在近了 就不画了
  2235. if (y!=left)
  2236. {
  2237. if (item.LineType==2)
  2238. {
  2239. this.Canvas.strokeStyle = item.LineColor;
  2240. this.Canvas.setLineDash([5,5]); //虚线
  2241. this.Canvas.beginPath();
  2242. this.Canvas.moveTo(ToFixedPoint(y),top);
  2243. this.Canvas.lineTo(ToFixedPoint(y),bottom);
  2244. this.Canvas.stroke();
  2245. this.Canvas.setLineDash([]);
  2246. }
  2247. else if (item.LineType>0)
  2248. {
  2249. this.Canvas.strokeStyle = item.LineColor;
  2250. if (g_JSChartResource.FrameYLineDash)
  2251. {
  2252. this.Canvas.setLineDash(g_JSChartResource.FrameYLineDash); //虚线
  2253. this.Canvas.beginPath();
  2254. this.Canvas.moveTo(ToFixedPoint(y),top);
  2255. this.Canvas.lineTo(ToFixedPoint(y),bottom);
  2256. this.Canvas.stroke();
  2257. this.Canvas.setLineDash([]);
  2258. }
  2259. else
  2260. {
  2261. this.Canvas.beginPath();
  2262. this.Canvas.moveTo(ToFixedPoint(y), top);
  2263. this.Canvas.lineTo(ToFixedPoint(y), bottom);
  2264. this.Canvas.stroke();
  2265. }
  2266. }
  2267. }
  2268. //坐标信息 左边 间距小于10 不画坐标
  2269. if (item.Message[0] != null && borderTop > 10 && this.IsShowYText[0] === true)
  2270. {
  2271. if (item.Font != null) this.Canvas.font = item.Font;
  2272. this.Canvas.fillStyle = item.TextColor;
  2273. this.Canvas.textAlign = "right";
  2274. this.Canvas.textBaseline = "middle";
  2275. var xText = y, yText = top;
  2276. this.Canvas.save();
  2277. this.Canvas.translate(xText, yText);
  2278. this.Canvas.rotate(90 * Math.PI / 180);
  2279. this.Canvas.fillText(item.Message[0], -2, 0);
  2280. this.Canvas.restore();
  2281. }
  2282. //坐标信息 右边 间距小于10 不画坐标
  2283. if (item.Message[1] != null && borderBottom > 10 && this.IsShowYText[1] === true)
  2284. {
  2285. if (item.Font != null) this.Canvas.font = item.Font;
  2286. this.Canvas.fillStyle = item.TextColor;
  2287. this.Canvas.textAlign = "left";
  2288. this.Canvas.textBaseline = "middle";
  2289. var xText = y, yText = bottom;
  2290. this.Canvas.save();
  2291. this.Canvas.translate(xText, yText);
  2292. this.Canvas.rotate(90 * Math.PI / 180);
  2293. this.Canvas.fillText(item.Message[1], 2, 0);
  2294. this.Canvas.restore();
  2295. }
  2296. yPrev = y;
  2297. }
  2298. }
  2299. this.GetXFromIndex = function (index)
  2300. {
  2301. if (index < 0) index = 0;
  2302. if (index > this.xPointCount - 1) index = this.xPointCount - 1;
  2303. var offset = this.ChartBorder.GetTop() + g_JSChartResource.FrameLeftMargin + this.DistanceWidth / 2 + this.DataWidth / 2;
  2304. for (var i = 1; i <= index; ++i)
  2305. {
  2306. offset += this.DistanceWidth + this.DataWidth;
  2307. }
  2308. return offset;
  2309. }
  2310. //画X轴
  2311. this.DrawVertical = function ()
  2312. {
  2313. var left = this.ChartBorder.GetLeft();
  2314. var right = this.ChartBorder.GetRightTitle();
  2315. var bottom = this.ChartBorder.GetBottom();
  2316. var xPrev = null; //上一个坐标x的值
  2317. for (var i in this.VerticalInfo)
  2318. {
  2319. var x = this.GetXFromIndex(this.VerticalInfo[i].Value);
  2320. if (x >= bottom) break;
  2321. if (xPrev != null && Math.abs(x - xPrev) < 80) continue;
  2322. var item=this.VerticalInfo[i];
  2323. if (item.LineType==2)
  2324. {
  2325. this.Canvas.setLineDash([5,5]);
  2326. this.Canvas.beginPath();
  2327. this.Canvas.moveTo(left, ToFixedPoint(x));
  2328. this.Canvas.lineTo(right, ToFixedPoint(x));
  2329. this.Canvas.stroke();
  2330. this.Canvas.setLineDash([]);
  2331. }
  2332. else if (item.LineType>0)
  2333. {
  2334. this.Canvas.strokeStyle = item.LineColor;
  2335. if (g_JSChartResource.FrameXLineDash)
  2336. {
  2337. this.Canvas.setLineDash(g_JSChartResource.FrameXLineDash);
  2338. this.Canvas.beginPath();
  2339. this.Canvas.moveTo(left, ToFixedPoint(x));
  2340. this.Canvas.lineTo(right, ToFixedPoint(x));
  2341. this.Canvas.stroke();
  2342. this.Canvas.setLineDash([]);
  2343. }
  2344. else
  2345. {
  2346. this.Canvas.beginPath();
  2347. this.Canvas.moveTo(left, ToFixedPoint(x));
  2348. this.Canvas.lineTo(right, ToFixedPoint(x));
  2349. this.Canvas.stroke();
  2350. }
  2351. }
  2352. if (this.VerticalInfo[i].Message[0] != null)
  2353. {
  2354. if (this.VerticalInfo[i].Font != null)
  2355. this.Canvas.font = this.VerticalInfo[i].Font;
  2356. this.Canvas.fillStyle = this.VerticalInfo[i].TextColor;
  2357. var testWidth = this.Canvas.measureText(this.VerticalInfo[i].Message[0]).width;
  2358. if (x < testWidth / 2)
  2359. {
  2360. this.Canvas.textAlign = "left";
  2361. this.Canvas.textBaseline = "top";
  2362. }
  2363. else
  2364. {
  2365. this.Canvas.textAlign = "center";
  2366. this.Canvas.textBaseline = "top";
  2367. }
  2368. var xText = left, yText = x;
  2369. this.Canvas.save();
  2370. this.Canvas.translate(xText, yText);
  2371. this.Canvas.rotate(90 * Math.PI / 180);
  2372. this.Canvas.fillText(this.VerticalInfo[i].Message[0], 0, this.XBottomOffset);
  2373. this.Canvas.restore();
  2374. }
  2375. xPrev = x;
  2376. }
  2377. }
  2378. //Y坐标转y轴数值
  2379. this.GetYData = function (x)
  2380. {
  2381. if (x < this.ChartBorder.GetLeftEx()) return this.HorizontalMin;
  2382. if (x > this.ChartBorder.GetRightEx()) return this.HorizontalMax;
  2383. return (x - this.ChartBorder.GetLeftEx()) / this.ChartBorder.GetWidthEx() * (this.HorizontalMax - this.HorizontalMin) + this.HorizontalMin;
  2384. }
  2385. //X坐标转x轴数值
  2386. this.GetXData = function (y)
  2387. {
  2388. if (y <= this.ChartBorder.GetTop()) return 0;
  2389. if (y >= this.ChartBorder.GetBottom()) return this.XPointCount-1;
  2390. var distanceWidth=this.DistanceWidth;
  2391. var dataWidth=this.DataWidth;
  2392. var left=this.ChartBorder.GetTop()+g_JSChartResource.FrameLeftMargin;
  2393. var right=this.ChartBorder.GetBottom()-g_JSChartResource.FrameRightMargin;
  2394. var index=0;
  2395. var xPoint=left+distanceWidth/2+dataWidth+distanceWidth;
  2396. while(xPoint<right && index<10000 && index+1<this.XPointCount) //自己算x的数值
  2397. {
  2398. if (xPoint>=y) break;
  2399. xPoint+=(dataWidth+distanceWidth);
  2400. ++index;
  2401. }
  2402. return index;
  2403. }
  2404. }
  2405. function OverlayKLineFrame()
  2406. {
  2407. this.newMethod=KLineFrame; //派生
  2408. this.newMethod();
  2409. delete this.newMethod;
  2410. this.ClassName='OverlayKLineFrame';
  2411. this.MainFrame=null; //主框架
  2412. this.IsShareY=false; //使用和主框架公用Y轴
  2413. this.IsShowMainFrame=0; //是否显示在主框架坐标上 1=左边 2=右边
  2414. this.IsCalculateYMaxMin=true; //是否计算Y最大最小值
  2415. this.RightOffset=50;
  2416. this.PenBorder=g_JSChartResource.OverlayFrame.BolderPen; //'rgb(0,0,0)'
  2417. this.IsShow=false; //坐标是否显示
  2418. this.IsShowToolbar=true; //是否显示工具条
  2419. this.Title=null;
  2420. this.TitleColor=g_JSChartResource.OverlayFrame.TitleColor;
  2421. this.TitleFont=g_JSChartResource.OverlayFrame.TitleFont;
  2422. this.KLineFrame_ReloadResource=this.ReloadResource;
  2423. this.ReloadResource=function(resource)
  2424. {
  2425. this.KLineFrame_ReloadResource(resource);
  2426. if (!resource)
  2427. {
  2428. this.PenBorder=g_JSChartResource.OverlayFrame.BolderPen; //'rgb(0,0,0)'
  2429. this.TitleColor=g_JSChartResource.OverlayFrame.TitleColor;
  2430. this.TitleFont=g_JSChartResource.OverlayFrame.TitleFont;
  2431. }
  2432. }
  2433. this.Draw=function()
  2434. {
  2435. this.Buttons=[];
  2436. if (this.ChartBorder.IsShowTitleOnly) return;
  2437. this.SplitXYCoordinate();
  2438. if (this.IsShow)
  2439. {
  2440. this.DrawVertical();
  2441. this.DrawHorizontal();
  2442. }
  2443. this.SizeChange=false;
  2444. this.XYSplit=false;
  2445. }
  2446. this.GetScaleTextWidth=function()
  2447. {
  2448. return { TextWidth:0 };
  2449. }
  2450. //分割x,y轴坐标信息
  2451. this.SplitXYCoordinate=function()
  2452. {
  2453. if (this.XYSplit==false) return;
  2454. if (this.IsShareY) //和主图指标共享Y轴坐标
  2455. {
  2456. this.HorizontalMax=this.MainFrame.HorizontalMax;
  2457. this.HorizontalMin=this.MainFrame.HorizontalMin;
  2458. this.HorizontalInfo=[];
  2459. for(var i in this.MainFrame.HorizontalInfo)
  2460. {
  2461. var item=this.MainFrame.HorizontalInfo[i];
  2462. this.HorizontalInfo.push(item);
  2463. }
  2464. this.CoordinateType=this.MainFrame.CoordinateType;
  2465. }
  2466. else //独立Y轴坐标
  2467. {
  2468. if (this.YSplitOperator!=null) this.YSplitOperator.Operator();
  2469. }
  2470. }
  2471. //画Y轴
  2472. this.DrawHorizontal=function()
  2473. {
  2474. var border=this.ChartBorder.GetBorder();
  2475. var left=border.Left;
  2476. var right=border.Right;
  2477. var bottom = border.Bottom;
  2478. var top = this.ChartBorder.GetTopTitle();
  2479. var borderRight=this.ChartBorder.Right;
  2480. right+=this.RightOffset;
  2481. var yPrev=null; //上一个坐标y的值
  2482. for(var i=this.HorizontalInfo.length-1; i>=0; --i) //从上往下画分割线
  2483. {
  2484. var item=this.HorizontalInfo[i];
  2485. var y=this.GetYFromData(item.Value);
  2486. if (y!=null && Math.abs(y-yPrev)<this.MinYDistance) continue; //两个坐标在近了 就不画了
  2487. if (y >= bottom - 2) this.Canvas.textBaseline = 'bottom';
  2488. else if (y <= top + 2) this.Canvas.textBaseline = 'top';
  2489. else this.Canvas.textBaseline = "middle";
  2490. this.Canvas.strokeStyle=this.PenBorder;
  2491. this.Canvas.beginPath();
  2492. this.Canvas.moveTo(right-2,ToFixedPoint(y));
  2493. this.Canvas.lineTo(right,ToFixedPoint(y));
  2494. this.Canvas.stroke();
  2495. //坐标信息 右边 间距小于10 不画坐标
  2496. if (item.Message[1]!=null && borderRight>10)
  2497. {
  2498. if (item.Font!=null) this.Canvas.font=item.Font;
  2499. var text=item.Message[1];
  2500. if (Array.isArray(item.Message[1])) text=item.Message[1][0];
  2501. this.Canvas.fillStyle=item.TextColor;
  2502. this.Canvas.textAlign="left";
  2503. this.Canvas.fillText(text,right+2,y);
  2504. }
  2505. yPrev=y;
  2506. }
  2507. }
  2508. //画X轴
  2509. this.DrawVertical=function()
  2510. {
  2511. var border=this.ChartBorder.GetBorder();
  2512. var top=border.TopEx;
  2513. //var left=this.ChartBorder.GetLeft();
  2514. var right=border.Right;
  2515. var bottom=border.BottomEx;
  2516. right+=this.RightOffset;
  2517. this.Canvas.strokeStyle=this.PenBorder;
  2518. this.Canvas.beginPath();
  2519. this.Canvas.moveTo(ToFixedPoint(right),ToFixedPoint(top));
  2520. this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(bottom));
  2521. this.Canvas.stroke();
  2522. }
  2523. }
  2524. function OverlayKLineHScreenFrame()
  2525. {
  2526. this.newMethod=KLineHScreenFrame; //派生
  2527. this.newMethod();
  2528. delete this.newMethod;
  2529. this.ClassName='OverlayKLineHScreenFrame';
  2530. this.MainFrame=null; //主框架
  2531. this.IsShareY=false; //使用和主框架公用Y轴
  2532. this.IsCalculateYMaxMin=true; //是否计算Y最大最小值
  2533. this.RightOffset=50;
  2534. this.PenBorder=g_JSChartResource.OverlayFrame.BolderPen; //'rgb(0,0,0)'
  2535. this.IsShow=true; //坐标是否显示
  2536. this.Title=null;
  2537. this.TitleColor=g_JSChartResource.OverlayFrame.TitleColor;
  2538. this.TitleFont=g_JSChartResource.OverlayFrame.TitleFont;
  2539. this.Draw=function()
  2540. {
  2541. this.SplitXYCoordinate();
  2542. if (this.IsShow)
  2543. {
  2544. this.DrawVertical();
  2545. this.DrawHorizontal();
  2546. }
  2547. this.SizeChange=false;
  2548. this.XYSplit=false;
  2549. }
  2550. //分割x,y轴坐标信息
  2551. this.SplitXYCoordinate=function()
  2552. {
  2553. if (this.XYSplit==false) return;
  2554. if (this.IsShareY) //和主图指标共享Y轴坐标
  2555. {
  2556. this.HorizontalMax=this.MainFrame.HorizontalMax;
  2557. this.HorizontalMin=this.MainFrame.HorizontalMin;
  2558. this.HorizontalInfo=[];
  2559. for(var i=0; i<this.MainFrame.HorizontalInfo.length; ++i)
  2560. {
  2561. var item=this.MainFrame.HorizontalInfo[i];
  2562. this.HorizontalInfo.push(item);
  2563. }
  2564. }
  2565. else
  2566. {
  2567. if (this.YSplitOperator!=null) this.YSplitOperator.Operator();
  2568. }
  2569. }
  2570. //画Y轴
  2571. this.DrawHorizontal=function()
  2572. {
  2573. }
  2574. //画X轴
  2575. this.DrawVertical=function()
  2576. {
  2577. }
  2578. this.GetScaleTextWidth=function()
  2579. {
  2580. return { TextWidth:0 };
  2581. }
  2582. }
  2583. //深度图框架
  2584. function DepthChartFrame()
  2585. {
  2586. this.newMethod=AverageWidthFrame; //派生
  2587. this.newMethod();
  2588. delete this.newMethod;
  2589. this.ScreenImageData; //截图
  2590. this.Position; //画布的位置
  2591. this.ClassName="DepthChartFrame";
  2592. //X轴价格 最大,最小
  2593. this.VerticalRange={ Max:null, Min:null, Center:null, MaxDiffer:null, Differ:null, Step:0.05 };
  2594. this.AskPrice;
  2595. this.BidPrice;
  2596. this.MinZoom=0.05; //最小缩放
  2597. this.SetPriceList=function(aryAskPrice, aryBidPrice)
  2598. {
  2599. this.AskPrice=aryAskPrice;
  2600. this.BidPrice=aryBidPrice;
  2601. }
  2602. this.SetDrawOtherChart = function (callback) //在画完框架以后调用的扩展画法
  2603. {
  2604. }
  2605. this.DrawFrame=function()
  2606. {
  2607. this.SplitXYCoordinate();
  2608. this.DrawHorizontal();
  2609. this.DrawVertical();
  2610. }
  2611. this.GetXFromIndex=function(value)
  2612. {
  2613. var left=this.ChartBorder.GetLeft();
  2614. var right=this.ChartBorder.GetRight();
  2615. var width=this.ChartBorder.GetWidth();
  2616. var offset=width*(value-this.VerticalRange.Min)/(this.VerticalRange.Max-this.VerticalRange.Min);
  2617. return left+offset;
  2618. }
  2619. this.GetXData=function(x)
  2620. {
  2621. var left=this.ChartBorder.GetLeft();
  2622. var right=this.ChartBorder.GetRight();
  2623. var width=this.ChartBorder.GetWidth();
  2624. return (x-left)/width*(this.VerticalRange.Max-this.VerticalRange.Min)+this.VerticalRange.Min;
  2625. }
  2626. this.GetXFromPrice=function(price)
  2627. {
  2628. var isAskPrice=false;
  2629. var find=this.GetPrice(this.BidPrice, price);
  2630. if (find==null)
  2631. {
  2632. find=this.GetPrice(this.AskPrice, price);
  2633. isAskPrice=true;
  2634. }
  2635. if (find==null)
  2636. {
  2637. if (this.BidPrice && Array.isArray(this.BidPrice) && this.BidPrice.length>0)
  2638. {
  2639. var minPrice=this.BidPrice[0];
  2640. if (price<minPrice)
  2641. {
  2642. isAskPrice=false;
  2643. find= minPrice;
  2644. }
  2645. }
  2646. }
  2647. if (find==null)
  2648. {
  2649. if (this.AskPrice && Array.isArray(this.AskPrice) && this.AskPrice.length>0)
  2650. {
  2651. var maxPrice=this.AskPrice[this.AskPrice.length-1];
  2652. if (price>maxPrice)
  2653. {
  2654. isAskPrice=true;
  2655. find=maxPrice;
  2656. }
  2657. }
  2658. }
  2659. if (find==null) return null;
  2660. var x=this.GetXFromIndex(find);
  2661. return { X:x, Price:find, IsAsk:isAskPrice };
  2662. }
  2663. this.GetPrice=function(aryPrice, price)
  2664. {
  2665. if (!aryPrice || !Array.isArray(aryPrice) || aryPrice.length<=0) return null;
  2666. if (price<aryPrice[0] || price>aryPrice[aryPrice.length-1]) return null;
  2667. var lastPrice=null;
  2668. for(var i in aryPrice)
  2669. {
  2670. var item=aryPrice[i];
  2671. if (price==item)
  2672. {
  2673. return item;
  2674. }
  2675. if (price<item)
  2676. return lastPrice;
  2677. lastPrice=item;
  2678. }
  2679. }
  2680. //分割x,y轴坐标信息
  2681. this.SplitXYCoordinate=function()
  2682. {
  2683. if (this.XYSplit==false) return;
  2684. if (this.YSplitOperator!=null) this.YSplitOperator.Operator();
  2685. if (this.XSplitOperator!=null) this.XSplitOperator.Operator();
  2686. }
  2687. //图形快照
  2688. this.Snapshot=function()
  2689. {
  2690. this.ScreenImageData=this.Canvas.getImageData(0,0,this.ChartBorder.GetChartWidth(),this.ChartBorder.GetChartHeight());
  2691. }
  2692. this.SetSizeChage=function(sizeChange)
  2693. {
  2694. this.SizeChange=sizeChange;
  2695. //画布的位置
  2696. this.Position={
  2697. X:this.ChartBorder.UIElement.offsetLeft,
  2698. Y:this.ChartBorder.UIElement.offsetTop,
  2699. W:this.ChartBorder.UIElement.clientWidth,
  2700. H:this.ChartBorder.UIElement.clientHeight
  2701. };
  2702. }
  2703. this.ZoomUp=function() //放大
  2704. {
  2705. var xRange=this.VerticalRange;
  2706. var differ=xRange.Differ;
  2707. var minDiffer=xRange.MaxDiffer*this.MinZoom;
  2708. if (differ<minDiffer) return false;
  2709. var offsetDiffer=xRange.Differ*xRange.Step;
  2710. differ-=offsetDiffer;
  2711. xRange.Differ=differ;
  2712. xRange.Min=xRange.Center-xRange.Differ;
  2713. xRange.Max=xRange.Center+xRange.Differ;
  2714. return true;
  2715. }
  2716. this.ZoomDown=function() //缩小
  2717. {
  2718. var xRange=this.VerticalRange;
  2719. var differ=xRange.Differ;
  2720. if (differ==xRange.MaxDiffer) return false;
  2721. var offsetDiffer=xRange.Differ*xRange.Step;
  2722. differ+=offsetDiffer;
  2723. if (differ>xRange.MaxDiffer) differ=xRange.MaxDiffer;
  2724. xRange.Differ=differ;
  2725. xRange.Min=xRange.Center-xRange.Differ;
  2726. xRange.Max=xRange.Center+xRange.Differ;
  2727. return true;
  2728. }
  2729. }
  2730. //导出统一使用JSCommon命名空间名
  2731. export
  2732. {
  2733. IChartFramePainting,
  2734. AverageWidthFrame,
  2735. MinuteFrame,
  2736. MinuteHScreenFrame,
  2737. OverlayMinuteFrame,
  2738. OverlayMinuteHScreenFrame,
  2739. OverlayKLineFrame,
  2740. OverlayKLineHScreenFrame,
  2741. ZOOM_SEED,
  2742. KLineFrame,
  2743. KLineHScreenFrame,
  2744. DepthChartFrame,
  2745. };