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.

10564 lines
364 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
  10. {
  11. ChartData, HistoryData,
  12. SingleData, MinuteData,
  13. Rect,
  14. JSCHART_EVENT_ID,
  15. OVERLAY_STATUS_ID,
  16. } from "./umychart.data.wechat.js";
  17. import
  18. {
  19. g_JSChartResource,
  20. g_JSChartLocalization,
  21. JSChartResource,
  22. } from './umychart.resource.wechat.js'
  23. import
  24. {
  25. IFrameSplitOperator,
  26. } from './umychart.framesplit.wechat.js'
  27. import
  28. {
  29. JSCommonCoordinateData,
  30. MARKET_SUFFIX_NAME
  31. } from "./umychart.coordinatedata.wechat.js";
  32. import { JSConsole } from "./umychart.console.wechat.js";
  33. //配色
  34. function JSChartPaintResource()
  35. {
  36. //指标不支持信息
  37. this.Index=
  38. {
  39. NotSupport : { Font: "14px 微软雅黑", TextColor: "rgb(52,52,52)" }
  40. }
  41. }
  42. var g_JSChartPaintResource = new JSChartPaintResource();
  43. function GetFontHeight(context, font, word)
  44. {
  45. if (!context) return null;
  46. if (font) context.font=font;
  47. var text='擎';
  48. if (IFrameSplitOperator.IsString(word)) text=word;
  49. var fontInfo=context.measureText(text);
  50. //var textHeight=fontInfo.fontBoundingBoxAscent + fontInfo.fontBoundingBoxDescent;
  51. var textHeight=fontInfo.width+2;
  52. return textHeight;
  53. }
  54. function ColorToRGBA(color,opacity)
  55. {
  56. var reg = /^(rgb|RGB)/;
  57. if (reg.test(color))
  58. {
  59. var strHex = "#";
  60. var colorArr = color.replace(/(?:\(|\)|rgb|RGB)*/g, "").split(","); // 把RGB的3个数值变成数组
  61. // 转成16进制
  62. for (var i = 0; i < colorArr.length; i++)
  63. {
  64. var hex = Number(colorArr[i]).toString(16);
  65. if (hex === "0") hex += hex;
  66. strHex += hex;
  67. }
  68. color=strHex;
  69. }
  70. return "rgba(" + parseInt("0x" + color.slice(1, 3)) + "," + parseInt("0x" + color.slice(3, 5)) + "," + parseInt("0x" + color.slice(5, 7)) + "," + opacity + ")";
  71. }
  72. //图新画法接口类
  73. function IChartPainting()
  74. {
  75. this.Canvas; //画布
  76. this.ChartBorder; //边框信息
  77. this.ChartFrame; //框架画法
  78. this.Name; //名称
  79. this.ClassName = 'IChartPainting'; //类名
  80. this.Data = new ChartData(); //数据区
  81. this.Script; //图形对应的指标脚本 (只有指标图形才有)
  82. this.NotSupportMessage = null;
  83. this.MessageFont = g_JSChartPaintResource.Index.NotSupport.Font;
  84. this.MessageColor = g_JSChartPaintResource.Index.NotSupport.TextColor;
  85. this.IsDrawFirst = false; //是否比K线先画
  86. this.IsShow = true; //是否显示
  87. this.IsVisible=true; //是否显示 (预留给外部单独设置线段显隐)
  88. this.GetEventCallback;
  89. this.Draw = function () { }
  90. this.GetYFromData=function(value,isLimit)
  91. {
  92. return this.ChartFrame.GetYFromData(value,isLimit);
  93. }
  94. this.IsMinuteFrame=function()
  95. {
  96. var isMinute=(this.ChartFrame.ClassName=="MinuteFrame" || this.ChartFrame.ClassName=="MinuteHScreenFrame" ||
  97. this.ChartFrame.ClassName=="OverlayMinuteFrame" || this.ChartFrame.ClassName=="OverlayMinuteHScreenFrame");
  98. return isMinute
  99. }
  100. //是否隐藏指标
  101. this.IsHideScriptIndex=function()
  102. {
  103. if (this.Script && this.Script.IsShow==false) return true;
  104. return false;
  105. }
  106. this.DrawNotSupportmessage = function ()
  107. {
  108. this.Canvas.font = this.MessageFont;
  109. this.Canvas.fillStyle = this.MessageColor;
  110. var left = this.ChartBorder.GetLeft();
  111. var width = this.ChartBorder.GetWidth();
  112. var top = this.ChartBorder.GetTopEx();
  113. var height = this.ChartBorder.GetHeightEx();
  114. var x = left + width / 2;
  115. var y = top + height / 2;
  116. this.Canvas.textAlign = "center";
  117. this.Canvas.textBaseline = "middle";
  118. this.Canvas.fillText(this.NotSupportMessage, x, y);
  119. }
  120. this.GetTooltipData = function (x, y, tooltip)
  121. {
  122. return false;
  123. }
  124. this.GetMaxMin = function ()
  125. {
  126. var xPointCount = this.ChartFrame.XPointCount;
  127. var range = {};
  128. range.Min = null;
  129. range.Max = null;
  130. if (!this.Data || !this.Data.Data) return range;
  131. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  132. {
  133. var value = this.Data.Data[i];
  134. if (value == null || isNaN(value)) continue;
  135. if (range.Max == null) range.Max = value;
  136. if (range.Min == null) range.Min = value;
  137. if (range.Max < value) range.Max = value;
  138. if (range.Min > value) range.Min = value;
  139. }
  140. return range;
  141. }
  142. this.GetDynamicFont = function (dataWidth) //根据宽度自动获取对应字体
  143. {
  144. var font;
  145. if (dataWidth < 5) font = '4px Arial'; //字体根据数据宽度动态调整
  146. else if (dataWidth < 7) font = '6px Arial';
  147. else if (dataWidth < 9) font = '8px Arial';
  148. else if (dataWidth < 11) font = '10px Arial';
  149. else if (dataWidth < 13) font = '12px Arial';
  150. else if (dataWidth < 15) font = '14px Arial';
  151. else font = '16px Arial';
  152. return font;
  153. }
  154. this.GetDynamicFontEx=function(dataWidth, distanceWidth, maxSize, minSize, zoom, fontname) //根据宽度自动获取对应字体
  155. {
  156. if (maxSize==minSize)
  157. {
  158. var font=`${maxSize.toFixed(0)}px ${fontname}` ;
  159. return font;
  160. }
  161. var fontSize=(dataWidth+distanceWidth);
  162. if (zoom)
  163. {
  164. if (zoom.Type==0)
  165. {
  166. if (zoom.Value>0) fontSize=(dataWidth*zoom.Value);
  167. }
  168. else if (zoom.Type==1)
  169. {
  170. if (zoom.Value>0) fontSize=(dataWidth+distanceWidth)*zoom.Value;
  171. }
  172. else if (zoom.Type==2)
  173. {
  174. if (IFrameSplitOperator.IsNumber(zoom.Value))
  175. fontSize=(dataWidth+distanceWidth) + (2*zoom.Value);
  176. }
  177. }
  178. if (fontSize<minSize) fontSize=minSize;
  179. else if (fontSize>maxSize) fontSize=maxSize;
  180. var font=`${fontSize.toFixed(0)}px ${fontname}` ;
  181. return font;
  182. }
  183. this.SetFillStyle = function (color, x0, y0, x1, y1)
  184. {
  185. if (Array.isArray(color))
  186. {
  187. let gradient = this.Canvas.createLinearGradient(x0, y0, x1, y1);
  188. var offset = 1 / (color.length-1);
  189. for (var i=0;i<color.length;++i)
  190. {
  191. gradient.addColorStop(i * offset, color[i]);
  192. }
  193. this.Canvas.fillStyle = gradient;
  194. }
  195. else
  196. {
  197. this.Canvas.fillStyle = color;
  198. }
  199. }
  200. this.GetFontHeight=function(font)
  201. {
  202. return GetFontHeight(this.Canvas, font, "擎");
  203. }
  204. this.GetLockRect=function()
  205. {
  206. return this.ChartFrame.GetLockRect();
  207. }
  208. this.ClipClient=function(isHScreen) //裁剪客户端
  209. {
  210. if (isHScreen==true)
  211. {
  212. var left=this.ChartBorder.GetLeftEx();
  213. var right=this.ChartBorder.GetRightEx();
  214. var top=this.ChartBorder.GetTop();
  215. var bottom=this.ChartBorder.GetBottom();
  216. }
  217. else
  218. {
  219. var left=this.ChartBorder.GetLeft();
  220. var right=this.ChartBorder.GetRight();
  221. var top=this.ChartBorder.GetTopEx();
  222. var bottom=this.ChartBorder.GetBottomEx();
  223. }
  224. this.Canvas.beginPath();
  225. this.Canvas.rect(left,top,(right-left),(bottom-top));
  226. //this.Canvas.stroke(); //调试用
  227. this.Canvas.clip();
  228. }
  229. }
  230. //K线画法
  231. function ChartKLine()
  232. {
  233. this.newMethod = IChartPainting; //派生
  234. this.newMethod();
  235. delete this.newMethod;
  236. this.ClassName = 'ChartKLine';
  237. this.Symbol; //股票代码
  238. this.DrawType = 0; // 0=K线 1=收盘价线 2=美国线 3=空心K线柱子 4=收盘价面积 6=空心阴线阳线柱 9=自定义颜色K线
  239. this.CloseLineColor = g_JSChartResource.CloseLineColor;
  240. this.CloseLineAreaColor = g_JSChartResource.CloseLineAreaColor;
  241. this.UpColor = g_JSChartResource.UpBarColor;
  242. this.DownColor = g_JSChartResource.DownBarColor;
  243. this.UnchagneColor = g_JSChartResource.UnchagneBarColor; //平盘
  244. this.ColorData; //五彩K线颜色 >0 UpColor 其他 DownColor
  245. this.TradeData; //交易系统 包含买卖数据{Buy:, Sell:}
  246. this.IsShowMaxMinPrice = true; //是否显示最大最小值
  247. this.TextFont = g_JSChartResource.KLine.MaxMin.Font;
  248. this.TextColor = g_JSChartResource.KLine.MaxMin.Color;
  249. this.InfoPointColor = g_JSChartResource.KLine.Info.Color;
  250. this.InfoPointColor2 = g_JSChartResource.KLine.Info.Color2;
  251. this.InfoDrawType = 0; //0=在底部画远点 1=在最低价画三角
  252. this.PtMax; //最大值的位置
  253. this.PtMin; //最小值的位置
  254. this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
  255. this.MinColorBarWidth=g_JSChartResource.MinColorKBarWidth;
  256. this.CustomKLine; //自定义K线, key=date*1000000+time, key={ Color:, DrawType: }
  257. //当前屏显示K线信息
  258. this.ShowRange={ }; //K线显示范围 { Start:, End:, DataCount:, ShowCount: }
  259. this.DrawKRange={ Start:null, End:null }; //当前屏K线的索引{ Start: , End:}
  260. //未回补的价格缺口
  261. this.PriceGap={ Enable:false, Count:1 };
  262. this.PriceGapStyple=
  263. {
  264. Line:{ Color:g_JSChartResource.PriceGapStyple.Line.Color },
  265. Text:{ Color:g_JSChartResource.PriceGapStyple.Text.Color, Font: g_JSChartResource.PriceGapStyple.Text.Font }
  266. };
  267. this.AryPriceGapCache=[]; //缺口数据 { }
  268. this.OneLimitBarType=0; //一字板颜色类型 4个价格全部都在同一个价位上 0=使用平盘颜色 1=跟昨收比较
  269. this.DrawAKLine = function () //美国线
  270. {
  271. var isHScreen = (this.ChartFrame.IsHScreen === true);
  272. var dataWidth = this.ChartFrame.DataWidth;
  273. var distanceWidth = this.ChartFrame.DistanceWidth;
  274. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
  275. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
  276. var chartright = this.ChartBorder.GetRight();
  277. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  278. var xPointCount = this.ChartFrame.XPointCount;
  279. this.ShowRange.Start=this.Data.DataOffset;
  280. this.ShowRange.End=this.ShowRange.Start;
  281. this.ShowRange.DataCount=0;
  282. this.ShowRange.ShowCount=xPointCount;
  283. this.DrawKRange.Start=this.Data.DataOffset;
  284. var eventUnchangeKLine=null; //定制平盘K线颜色事件
  285. if (this.GetEventCallback)
  286. {
  287. eventUnchangeKLine=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_UNCHANGE_KLINE_COLOR);
  288. }
  289. var upColor=this.UpColor;
  290. var downColor=this.DownColor;
  291. var unchagneColor=this.UnchagneColor;
  292. var ptMax = { X: null, Y: null, Value: null, Align: 'left' };
  293. var ptMin = { X: null, Y: null, Value: null, Align: 'left' };
  294. var preKItemInfo=null;
  295. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
  296. {
  297. var data = this.Data.Data[i];
  298. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  299. var left = xOffset;
  300. var right = xOffset + dataWidth;
  301. if (right > chartright) break;
  302. var x = left + (right - left) / 2;
  303. var yLow = this.ChartFrame.GetYFromData(data.Low);
  304. var yHigh = this.ChartFrame.GetYFromData(data.High);
  305. var yOpen = this.ChartFrame.GetYFromData(data.Open);
  306. var yClose = this.ChartFrame.GetYFromData(data.Close);
  307. this.DrawKRange.End=i;
  308. var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right } };
  309. if (ptMax.Value == null || ptMax.Value < data.High) //求最大值
  310. {
  311. ptMax.X = x;
  312. ptMax.Y = yHigh;
  313. ptMax.Value = data.High;
  314. ptMax.Align = j < xPointCount / 2 ? 'left' : 'right';
  315. }
  316. if (ptMin.Value == null || ptMin.Value > data.Low) //求最小值
  317. {
  318. ptMin.X = x;
  319. ptMin.Y = yLow;
  320. ptMin.Value = data.Low;
  321. ptMin.Align = j < xPointCount / 2 ? 'left' : 'right';
  322. }
  323. if (data.Open < data.Close)
  324. {
  325. this.Canvas.strokeStyle =upColor; //阳线
  326. }
  327. else if (data.Open > data.Close)
  328. {
  329. this.Canvas.strokeStyle = downColor; //阴线
  330. }
  331. else
  332. {
  333. if (eventUnchangeKLine && eventUnchangeKLine.Callback)
  334. {
  335. var sendData={ KItem:data, DataIndex:i, DefaultColor:unchagneColor, BarColor:null };
  336. eventUnchangeKLine.Callback(eventUnchangeKLine, sendData, this);
  337. if (sendData.BarColor) unchagneColor=sendData.BarColor;
  338. }
  339. this.Canvas.strokeStyle =unchagneColor; //平线
  340. }
  341. this.Canvas.beginPath(); //最高-最低
  342. if (isHScreen)
  343. {
  344. if (data.High==data.Low && dataWidth < this.MinBarWidth)
  345. {
  346. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  347. this.Canvas.lineTo(yLow-1, ToFixedPoint(x));
  348. }
  349. else
  350. {
  351. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  352. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  353. }
  354. }
  355. else
  356. {
  357. if (data.High==data.Low && dataWidth < this.MinBarWidth)
  358. {
  359. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  360. this.Canvas.lineTo(ToFixedPoint(x), yLow+1);
  361. }
  362. else
  363. {
  364. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  365. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  366. }
  367. }
  368. this.Canvas.stroke();
  369. if (dataWidth >= this.MinBarWidth)
  370. {
  371. this.Canvas.beginPath(); //开盘
  372. if (isHScreen)
  373. {
  374. this.Canvas.moveTo(ToFixedPoint(yOpen), left);
  375. this.Canvas.lineTo(ToFixedPoint(yOpen), x);
  376. }
  377. else
  378. {
  379. this.Canvas.moveTo(left, ToFixedPoint(yOpen));
  380. this.Canvas.lineTo(x, ToFixedPoint(yOpen));
  381. }
  382. this.Canvas.stroke();
  383. this.Canvas.beginPath(); //收盘
  384. if (isHScreen)
  385. {
  386. this.Canvas.moveTo(ToFixedPoint(yClose), right);
  387. this.Canvas.lineTo(ToFixedPoint(yClose), x);
  388. }
  389. else
  390. {
  391. this.Canvas.moveTo(right, ToFixedPoint(yClose));
  392. this.Canvas.lineTo(x, ToFixedPoint(yClose));
  393. }
  394. this.Canvas.stroke();
  395. }
  396. if (this.Data.DataType == 0 && ChartData.IsDayPeriod(this.Data.Period,true)) //信息地雷
  397. {
  398. var infoItem = { X: x, Xleft: left, XRight: right, YMax: yHigh, YMin: yLow, DayData: data, Index: j };
  399. this.DrawInfoDiv(infoItem);
  400. }
  401. if (this.PriceGap.Enable && preKItemInfo)
  402. {
  403. this.CheckPriceGap(kItemInfo);
  404. var value=this.IsPriceGap(kItemInfo,preKItemInfo);
  405. if (value>0)
  406. this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
  407. }
  408. preKItemInfo=kItemInfo;
  409. }
  410. this.PtMax = ptMax;
  411. this.PtMin = ptMin;
  412. }
  413. this.DrawCloseLine = function () //收盘价线
  414. {
  415. var isHScreen = (this.ChartFrame.IsHScreen === true);
  416. var dataWidth = this.ChartFrame.DataWidth;
  417. var distanceWidth = this.ChartFrame.DistanceWidth;
  418. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  419. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  420. var chartright = this.ChartBorder.GetRight();
  421. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  422. var xPointCount = this.ChartFrame.XPointCount;
  423. this.ShowRange.Start=this.Data.DataOffset;
  424. this.ShowRange.End=this.ShowRange.Start;
  425. this.ShowRange.DataCount=0;
  426. this.ShowRange.ShowCount=xPointCount;
  427. this.DrawKRange.Start=this.Data.DataOffset;
  428. var bFirstPoint = true;
  429. this.Canvas.beginPath();
  430. this.Canvas.strokeStyle = this.CloseLineColor;
  431. var preKItemInfo=null;
  432. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
  433. {
  434. var data = this.Data.Data[i];
  435. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  436. var left = xOffset;
  437. var right = xOffset + dataWidth;
  438. if (right > chartright) break;
  439. var x = left + (right - left) / 2;
  440. var yClose = this.ChartFrame.GetYFromData(data.Close);
  441. this.DrawKRange.End=i;
  442. if (bFirstPoint) {
  443. if (isHScreen) this.Canvas.moveTo(yClose, x);
  444. else this.Canvas.moveTo(x, yClose);
  445. bFirstPoint = false;
  446. }
  447. else {
  448. if (isHScreen) this.Canvas.lineTo(yClose, x);
  449. else this.Canvas.lineTo(x, yClose);
  450. }
  451. if (this.PriceGap.Enable )
  452. {
  453. var yLow=this.GetYFromData(data.Low, false);
  454. var yHigh=this.GetYFromData(data.High, false);
  455. var yOpen=this.GetYFromData(data.Open, false);
  456. var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right }};
  457. if (preKItemInfo)
  458. {
  459. this.CheckPriceGap(kItemInfo);
  460. var value=this.IsPriceGap(kItemInfo,preKItemInfo);
  461. if (value>0) this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
  462. }
  463. preKItemInfo=kItemInfo;
  464. }
  465. }
  466. if (bFirstPoint == false) this.Canvas.stroke();
  467. }
  468. this.DrawCloseArea = function () //收盘价面积
  469. {
  470. var isHScreen = (this.ChartFrame.IsHScreen === true);
  471. var dataWidth = this.ChartFrame.DataWidth;
  472. var distanceWidth = this.ChartFrame.DistanceWidth;
  473. var xPointCount = this.ChartFrame.XPointCount;
  474. if (isHScreen)
  475. {
  476. var border=this.ChartBorder.GetHScreenBorder();
  477. var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  478. var chartright=border.BottomEx;
  479. var borderLeft=border.TopEx;
  480. }
  481. else
  482. {
  483. var border=this.ChartBorder.GetBorder();
  484. var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  485. var chartright=border.RightEx;
  486. var borderLeft=border.LeftEx;
  487. }
  488. var bFirstPoint = true;
  489. var firstPoint = null;
  490. this.Canvas.beginPath();
  491. this.Canvas.strokeStyle = this.CloseLineColor;
  492. var ptLast=null;
  493. this.ShowRange.Start=this.Data.DataOffset;
  494. this.ShowRange.End=this.ShowRange.Start;
  495. this.ShowRange.DataCount=0;
  496. this.ShowRange.ShowCount=xPointCount;
  497. this.DrawKRange.Start=this.Data.DataOffset;
  498. if (this.Data.DataOffset>0) //把最左边的一个点连上
  499. {
  500. var data=this.Data.Data[this.Data.DataOffset-1];
  501. if (data && IFrameSplitOperator.IsNumber(data.Close))
  502. {
  503. var x=borderLeft;
  504. var yClose=this.GetYFromData(data.Close,false);
  505. if (isHScreen)
  506. {
  507. this.Canvas.moveTo(yClose,x);
  508. firstPoint={ X:yClose, Y:x };
  509. }
  510. else
  511. {
  512. this.Canvas.moveTo(x,yClose);
  513. firstPoint={ X:x, Y:yClose };
  514. }
  515. bFirstPoint=false;
  516. }
  517. }
  518. var preKItemInfo=null;
  519. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
  520. {
  521. var data = this.Data.Data[i];
  522. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  523. var left = xOffset;
  524. var right = xOffset + dataWidth;
  525. if (right > chartright) break;
  526. var x = left + (right - left) / 2;
  527. var yClose = this.ChartFrame.GetYFromData(data.Close);
  528. this.DrawKRange.End=i;
  529. if (bFirstPoint)
  530. {
  531. if (isHScreen)
  532. {
  533. this.Canvas.moveTo(yClose, x);
  534. firstPoint = { X: yClose, Y: x };
  535. }
  536. else
  537. {
  538. this.Canvas.moveTo(x, yClose);
  539. firstPoint = { X: x, Y: yClose };
  540. }
  541. bFirstPoint = false;
  542. }
  543. else
  544. {
  545. if (isHScreen) this.Canvas.lineTo(yClose, x);
  546. else this.Canvas.lineTo(x, yClose);
  547. }
  548. if (i==this.Data.Data.length-1)
  549. {
  550. ptLast={ X:x, Y:yClose, XLeft:left, XRight:right, KItem:data, ChartRight:chartright };
  551. }
  552. if (this.PriceGap.Enable )
  553. {
  554. var yLow=this.GetYFromData(data.Low, false);
  555. var yHigh=this.GetYFromData(data.High, false);
  556. var yOpen=this.GetYFromData(data.Open, false);
  557. var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right }};
  558. if (preKItemInfo)
  559. {
  560. this.CheckPriceGap(kItemInfo);
  561. var value=this.IsPriceGap(kItemInfo,preKItemInfo);
  562. if (value>0) this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
  563. }
  564. preKItemInfo=kItemInfo;
  565. }
  566. }
  567. this.DrawLastPointEvent(ptLast); //通知外部绘制最后一个点
  568. if (bFirstPoint) return;
  569. this.Canvas.stroke();
  570. //画面积
  571. if (isHScreen)
  572. {
  573. this.Canvas.lineTo(this.ChartBorder.GetLeft(), x);
  574. this.Canvas.lineTo(this.ChartBorder.GetLeft(), firstPoint.Y);
  575. }
  576. else
  577. {
  578. this.Canvas.lineTo(x, this.ChartBorder.GetBottom());
  579. this.Canvas.lineTo(firstPoint.X, this.ChartBorder.GetBottom());
  580. }
  581. this.Canvas.closePath();
  582. if (Array.isArray(this.CloseLineAreaColor))
  583. {
  584. if (isHScreen)
  585. {
  586. let gradient = this.Canvas.createLinearGradient(this.ChartBorder.GetRightEx(), this.ChartBorder.GetTop(), this.ChartBorder.GetLeft(), this.ChartBorder.GetTop());
  587. gradient.addColorStop(0, this.CloseLineAreaColor[0]);
  588. gradient.addColorStop(1, this.CloseLineAreaColor[1]);
  589. this.Canvas.fillStyle = gradient;
  590. }
  591. else
  592. {
  593. let gradient = this.Canvas.createLinearGradient(firstPoint.X, this.ChartBorder.GetTopEx(), firstPoint.X, this.ChartBorder.GetBottom());
  594. gradient.addColorStop(0, this.CloseLineAreaColor[0]);
  595. gradient.addColorStop(1, this.CloseLineAreaColor[1]);
  596. this.Canvas.fillStyle = gradient;
  597. }
  598. }
  599. else
  600. {
  601. this.Canvas.fillStyle = this.CloseLineAreaColor;
  602. }
  603. this.Canvas.fill();
  604. }
  605. this.DrawKBar = function ()
  606. {
  607. var isHScreen = (this.ChartFrame.IsHScreen === true);
  608. var dataWidth = this.ChartFrame.DataWidth;
  609. var distanceWidth = this.ChartFrame.DistanceWidth;
  610. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  611. var chartright = this.ChartBorder.GetRight();
  612. var xPointCount = this.ChartFrame.XPointCount;
  613. var border=this.ChartBorder.GetBorder();
  614. if (isHScreen)
  615. {
  616. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  617. chartright = this.ChartBorder.GetBottom();
  618. }
  619. var ptMax = { X: null, Y: null, Value: null, Align: 'left' };
  620. var ptMin = { X: null, Y: null, Value: null, Align: 'left' };
  621. var upColor = this.UpColor;
  622. var downColor = this.DownColor;
  623. var unchagneColor = this.UnchagneColor;
  624. var ptLast=null;
  625. this.ShowRange.Start=this.Data.DataOffset;
  626. this.ShowRange.End=this.ShowRange.Start;
  627. this.ShowRange.DataCount=0;
  628. this.ShowRange.ShowCount=xPointCount;
  629. this.DrawKRange.Start=this.Data.DataOffset;
  630. var eventUnchangeKLine=null; //定制平盘K线颜色事件
  631. if (this.GetEventCallback)
  632. {
  633. eventUnchangeKLine=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_UNCHANGE_KLINE_COLOR);
  634. }
  635. var preKItemInfo=null;
  636. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth), ++this.ShowRange.DataCount)
  637. {
  638. var data = this.Data.Data[i];
  639. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  640. var left = xOffset;
  641. var right = xOffset + dataWidth;
  642. if (right > chartright) break;
  643. this.DrawKRange.End=i;
  644. var x = left + (right - left) / 2;
  645. var yLow = this.ChartFrame.GetYFromData(data.Low);
  646. var yHigh = this.ChartFrame.GetYFromData(data.High);
  647. var yOpen = this.ChartFrame.GetYFromData(data.Open);
  648. var yClose = this.ChartFrame.GetYFromData(data.Close);
  649. var y = yHigh;
  650. var kItemInfo={ Data:data, Coordinate:{ X:x, Low:yLow, High:yHigh, Close:yClose, Open:yOpen, Left:left, Right:right }};
  651. if (ptMax.Value == null || ptMax.Value < data.High) //求最大值
  652. {
  653. ptMax.X = x;
  654. ptMax.Y = yHigh;
  655. ptMax.Value = data.High;
  656. ptMax.Align = j < xPointCount / 2 ? 'left' : 'right';
  657. }
  658. if (ptMin.Value == null || ptMin.Value > data.Low) //求最小值
  659. {
  660. ptMin.X = x;
  661. ptMin.Y = yLow;
  662. ptMin.Value = data.Low;
  663. ptMin.Align = j < xPointCount / 2 ? 'left' : 'right';
  664. }
  665. if (this.ColorData) ///五彩K线颜色设置
  666. {
  667. if (i < this.ColorData.length)
  668. upColor = downColor = unchagneColor = (this.ColorData[i] > 0 ? this.UpColor : this.DownColor);
  669. else
  670. upColor = downColor = unchagneColor = this.DownColor;
  671. }
  672. var kLineOption=this.GetCustomKLine(data);
  673. if (kLineOption)
  674. {
  675. var barColor=kLineOption.Color;
  676. if (!barColor)
  677. {
  678. if (data.Open<data.Close) barColor=upColor;
  679. else if (data.Open>data.Close) barColor=downColor;
  680. else barColor=unchagneColor;
  681. }
  682. var drawType=this.DrawType;
  683. if (IFrameSplitOperator.IsNumber(kLineOption.DrawType)) drawType=kLineOption.DrawType;
  684. this.DrawKBar_Custom(data, dataWidth, barColor, drawType, kLineOption, x, y, left, right, yLow, yHigh, yOpen, yClose, border, isHScreen);
  685. }
  686. else if (this.DrawType==9 && data.ColorData)
  687. {
  688. this.DrawColorKBar(data, data.ColorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  689. }
  690. else if (data.Open < data.Close) //阳线
  691. {
  692. this.DrawKBar_Up(data, dataWidth, upColor, this.DrawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  693. }
  694. else if (data.Open > data.Close) //阴线
  695. {
  696. this.DrawKBar_Down(data, dataWidth, downColor, this.DrawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  697. }
  698. else // 平线
  699. {
  700. var barColor=unchagneColor;
  701. if (eventUnchangeKLine && eventUnchangeKLine.Callback)
  702. {
  703. var sendData={ KItem:data, DataIndex:i, DefaultColor:barColor, BarColor:null };
  704. eventUnchangeKLine.Callback(eventUnchangeKLine, sendData, this);
  705. if (sendData.BarColor) barColor=sendData.BarColor;
  706. }
  707. this.DrawKBar_Unchagne(data, dataWidth, barColor, this.DrawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  708. }
  709. if (this.Data.DataType == 0 && ChartData.IsDayPeriod(this.Data.Period,true)) //信息地雷
  710. {
  711. var infoItem = { X: x, Xleft: left, XRight: right, YMax: yHigh, YMin: yLow, DayData: data, Index: j };
  712. this.DrawInfoDiv(infoItem);
  713. }
  714. if (i==this.Data.Data.length-1)
  715. {
  716. ptLast={ X:x, Y:yClose, XLeft:left, XRight:right, KItem:data, ChartRight:chartright };
  717. }
  718. if (this.PriceGap.Enable && preKItemInfo)
  719. {
  720. this.CheckPriceGap(kItemInfo);
  721. var value=this.IsPriceGap(kItemInfo,preKItemInfo);
  722. if (value>0) this.AryPriceGapCache.push({ Data:[preKItemInfo, kItemInfo], Type:value });
  723. }
  724. preKItemInfo=kItemInfo;
  725. }
  726. this.DrawLastPointEvent(ptLast); //通知外部绘制最后一个点
  727. this.PtMax = ptMax;
  728. this.PtMin = ptMin;
  729. }
  730. this.DrawKBar_Up = function(data, dataWidth, upColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen) //阳线
  731. {
  732. var isEmptyBar=(drawType==3 || drawType==6);
  733. if (dataWidth >= this.MinBarWidth)
  734. {
  735. if (isEmptyBar)
  736. {
  737. if ((dataWidth%2)!=0) dataWidth-=1;
  738. }
  739. this.Canvas.strokeStyle = upColor;
  740. if (data.High > data.Close) //上影线
  741. {
  742. this.Canvas.beginPath();
  743. if (isHScreen)
  744. {
  745. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  746. this.Canvas.lineTo(ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : yClose), ToFixedPoint(x));
  747. }
  748. else
  749. {
  750. if (isEmptyBar)
  751. {
  752. var xFixed=left+dataWidth/2;
  753. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(y));
  754. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(Math.min(yClose,yOpen)));
  755. }
  756. else
  757. {
  758. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  759. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yClose));
  760. }
  761. }
  762. this.Canvas.stroke();
  763. y = yClose;
  764. }
  765. else
  766. {
  767. y = yClose;
  768. }
  769. this.Canvas.fillStyle = upColor;
  770. if (isHScreen)
  771. {
  772. if (Math.abs(yOpen - y) < 1)
  773. {
  774. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  775. }
  776. else
  777. {
  778. if (isEmptyBar) //空心柱
  779. {
  780. this.Canvas.beginPath();
  781. this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
  782. this.Canvas.stroke();
  783. }
  784. else
  785. {
  786. //宽度是负数竟然不会画, h5就可以
  787. //this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
  788. this.Canvas.fillRect(ToFixedRect(Math.min(yOpen, y)), ToFixedRect(left), ToFixedRect(Math.abs(yOpen - y)), ToFixedRect(dataWidth));
  789. }
  790. }
  791. }
  792. else
  793. {
  794. if (Math.abs(yOpen - y) < 1)
  795. {
  796. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  797. }
  798. else
  799. {
  800. if (isEmptyBar) //空心柱
  801. {
  802. this.Canvas.beginPath();
  803. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
  804. this.Canvas.stroke();
  805. }
  806. else
  807. {
  808. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
  809. }
  810. }
  811. }
  812. if (data.Open > data.Low) //下影线
  813. {
  814. this.Canvas.beginPath();
  815. if (isHScreen)
  816. {
  817. this.Canvas.moveTo(ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : y), ToFixedPoint(x));
  818. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  819. }
  820. else
  821. {
  822. if (isEmptyBar)
  823. {
  824. var xFixed=left+dataWidth/2;
  825. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(Math.max(yClose,yOpen)));
  826. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
  827. }
  828. else
  829. {
  830. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  831. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  832. }
  833. }
  834. this.Canvas.stroke();
  835. }
  836. }
  837. else
  838. {
  839. this.Canvas.beginPath();
  840. if (isHScreen)
  841. {
  842. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  843. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  844. }
  845. else
  846. {
  847. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  848. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  849. }
  850. this.Canvas.strokeStyle = upColor;
  851. this.Canvas.stroke();
  852. }
  853. }
  854. this.DrawKBar_Down=function(data, dataWidth, downColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen) //阴线
  855. {
  856. var isEmptyBar=(drawType==6);
  857. if (dataWidth >= this.MinBarWidth)
  858. {
  859. if (isEmptyBar)
  860. {
  861. if ((dataWidth%2)!=0) dataWidth-=1;
  862. }
  863. this.Canvas.strokeStyle = downColor;
  864. if (data.High > data.Close) //上影线
  865. {
  866. this.Canvas.beginPath();
  867. if (isHScreen)
  868. {
  869. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  870. this.Canvas.lineTo(ToFixedPoint(yOpen), ToFixedPoint(x));
  871. }
  872. else
  873. {
  874. if (isEmptyBar)
  875. {
  876. var xFixed=left+dataWidth/2;
  877. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(y));
  878. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(Math.min(yClose,yOpen)));
  879. }
  880. else
  881. {
  882. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  883. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yOpen));
  884. }
  885. }
  886. this.Canvas.stroke();
  887. y = yOpen;
  888. }
  889. else
  890. {
  891. y = yOpen
  892. }
  893. this.Canvas.fillStyle = downColor;
  894. if (isHScreen)
  895. {
  896. if (Math.abs(yClose - y) < 1)
  897. {
  898. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  899. }
  900. else
  901. {
  902. //宽度是负数竟然不会画, h5就可以
  903. this.Canvas.fillRect(ToFixedRect(Math.min(yClose, y)), ToFixedRect(left), ToFixedRect(Math.abs(yClose - y)), ToFixedRect(dataWidth));
  904. }
  905. }
  906. else
  907. {
  908. if (Math.abs(yClose - y) < 1)
  909. {
  910. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  911. }
  912. else
  913. {
  914. if (isEmptyBar) //空心柱
  915. {
  916. this.Canvas.beginPath();
  917. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
  918. this.Canvas.stroke();
  919. }
  920. else
  921. {
  922. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
  923. }
  924. }
  925. }
  926. if (data.Open > data.Low) //下影线
  927. {
  928. this.Canvas.beginPath();
  929. if (isHScreen)
  930. {
  931. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  932. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  933. }
  934. else
  935. {
  936. if (isEmptyBar)
  937. {
  938. var xFixed=left+dataWidth/2;
  939. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(Math.max(yClose,yOpen)));
  940. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
  941. }
  942. else
  943. {
  944. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  945. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  946. }
  947. }
  948. this.Canvas.stroke();
  949. }
  950. }
  951. else
  952. {
  953. this.Canvas.beginPath();
  954. if (isHScreen)
  955. {
  956. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  957. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  958. }
  959. else
  960. {
  961. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  962. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  963. }
  964. this.Canvas.strokeStyle = downColor;
  965. this.Canvas.stroke();
  966. }
  967. }
  968. this.DrawKBar_Unchagne=function(data, dataWidth, unchagneColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen) //平线
  969. {
  970. if (this.OneLimitBarType===1 && this.IsOneLimitBar(data)) //一字板
  971. {
  972. unchagneColor=this.GetOneLimitBarColor(data);
  973. }
  974. if (dataWidth >= this.MinBarWidth)
  975. {
  976. if ((dataWidth%2)!=0) dataWidth-=1;
  977. this.Canvas.strokeStyle = unchagneColor;
  978. this.Canvas.beginPath();
  979. if (data.High > data.Close) //上影线
  980. {
  981. if (isHScreen)
  982. {
  983. this.Canvas.moveTo(y, ToFixedPoint(x));
  984. this.Canvas.lineTo(yOpen, ToFixedPoint(x));
  985. }
  986. else
  987. {
  988. var xFixed=left+dataWidth/2;
  989. this.Canvas.moveTo(ToFixedPoint(xFixed), y);
  990. this.Canvas.lineTo(ToFixedPoint(xFixed), yOpen);
  991. }
  992. y = yOpen;
  993. }
  994. else
  995. {
  996. y = yOpen;
  997. }
  998. if (isHScreen)
  999. {
  1000. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(left));
  1001. this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(right));
  1002. }
  1003. else
  1004. {
  1005. this.Canvas.moveTo(ToFixedPoint(left), ToFixedPoint(y));
  1006. this.Canvas.lineTo(ToFixedPoint(left+dataWidth), ToFixedPoint(y));
  1007. }
  1008. if (data.Open > data.Low) //下影线
  1009. {
  1010. if (isHScreen)
  1011. {
  1012. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  1013. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  1014. }
  1015. else
  1016. {
  1017. var xFixed=left+dataWidth/2;
  1018. this.Canvas.moveTo(ToFixedPoint(xFixed), ToFixedPoint(y));
  1019. this.Canvas.lineTo(ToFixedPoint(xFixed), ToFixedPoint(yLow));
  1020. }
  1021. }
  1022. this.Canvas.stroke();
  1023. }
  1024. else
  1025. {
  1026. this.Canvas.beginPath();
  1027. if (isHScreen)
  1028. {
  1029. if (data.High==data.Low)
  1030. {
  1031. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  1032. this.Canvas.lineTo(yLow-1,ToFixedPoint(x));
  1033. }
  1034. else
  1035. {
  1036. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  1037. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  1038. }
  1039. }
  1040. else
  1041. {
  1042. if (data.High==data.Low)
  1043. {
  1044. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  1045. this.Canvas.lineTo(ToFixedPoint(x),yLow+1);
  1046. }
  1047. else
  1048. {
  1049. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  1050. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  1051. }
  1052. }
  1053. this.Canvas.strokeStyle = unchagneColor;
  1054. this.Canvas.stroke();
  1055. }
  1056. }
  1057. //是否是一字板
  1058. this.IsOneLimitBar=function(kItem)
  1059. {
  1060. if (kItem.Open==kItem.Close && kItem.High==kItem.Low && kItem.Open==kItem.High) return true;
  1061. return false;
  1062. }
  1063. //一字板颜色 和昨收比较
  1064. this.GetOneLimitBarColor=function(kItem)
  1065. {
  1066. if (!kItem || !IFrameSplitOperator.IsNumber(kItem.YClose)) return this.UnchagneColor;
  1067. if (kItem.Close>kItem.YClose) return this.UpColor;
  1068. else if (kItem.Close<kItem.YClose) return this.DownColor;
  1069. else return this.UnchagneColor;
  1070. }
  1071. this.DrawKBar_Custom=function(data, dataWidth, barColor, drawType, option, x, y, left, right, yLow, yHigh, yOpen, yClose, border, isHScreen)
  1072. {
  1073. if (option.BGColor) //画背景色
  1074. {
  1075. this.Canvas.fillStyle=option.BGColor;
  1076. var distanceWidth=this.ChartFrame.DistanceWidth;
  1077. if (isHScreen)
  1078. {
  1079. var yLeft=left-(distanceWidth/2);
  1080. var yRight=right+(distanceWidth/2);
  1081. var xTop=border.RightEx;
  1082. var xBottom=border.LeftEx;
  1083. this.Canvas.fillRect(ToFixedRect(xBottom),ToFixedRect(yLeft),ToFixedRect(xTop-xBottom),ToFixedRect(yRight-yLeft));
  1084. }
  1085. else
  1086. {
  1087. var xLeft=left-(distanceWidth/2);
  1088. var xRight=right+(distanceWidth/2);
  1089. var yTop=border.TopEx;
  1090. var yBottom=border.BottomEx;
  1091. this.Canvas.fillRect(ToFixedRect(xLeft),ToFixedRect(yTop),ToFixedRect(xRight-xLeft),ToFixedRect(yBottom-yTop));
  1092. }
  1093. }
  1094. if (dataWidth>=4)
  1095. {
  1096. this.Canvas.strokeStyle=barColor;
  1097. if (data.High>data.Close) //上影线
  1098. {
  1099. this.Canvas.beginPath();
  1100. if (isHScreen)
  1101. {
  1102. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  1103. this.Canvas.lineTo(ToFixedPoint(drawType==3?Math.max(yClose,yOpen):yClose),ToFixedPoint(x));
  1104. }
  1105. else
  1106. {
  1107. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  1108. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(drawType==3?Math.min(yClose,yOpen):yClose));
  1109. }
  1110. this.Canvas.stroke();
  1111. y=yClose;
  1112. }
  1113. else
  1114. {
  1115. y=yClose;
  1116. }
  1117. this.Canvas.fillStyle=barColor;
  1118. if (isHScreen)
  1119. {
  1120. if (Math.abs(yOpen-y)<1)
  1121. {
  1122. this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  1123. }
  1124. else
  1125. {
  1126. if (drawType==3) //空心柱
  1127. {
  1128. this.Canvas.beginPath();
  1129. this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
  1130. this.Canvas.stroke();
  1131. }
  1132. else
  1133. {
  1134. this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
  1135. }
  1136. }
  1137. }
  1138. else
  1139. {
  1140. if (Math.abs(yOpen-y)<1)
  1141. {
  1142. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
  1143. }
  1144. else
  1145. {
  1146. if (drawType==3) //空心柱
  1147. {
  1148. this.Canvas.beginPath();
  1149. this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(y),ToFixedRect(dataWidth),ToFixedRect(yOpen-y));
  1150. this.Canvas.stroke();
  1151. }
  1152. else
  1153. {
  1154. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yOpen)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yOpen-y)));
  1155. }
  1156. }
  1157. }
  1158. if (data.Open>data.Low) //下影线
  1159. {
  1160. this.Canvas.beginPath();
  1161. if (isHScreen)
  1162. {
  1163. this.Canvas.moveTo(ToFixedPoint(drawType==3?Math.min(yClose,yOpen):y),ToFixedPoint(x));
  1164. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  1165. }
  1166. else
  1167. {
  1168. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(drawType==3?Math.max(yClose,yOpen):y));
  1169. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  1170. }
  1171. this.Canvas.stroke();
  1172. }
  1173. }
  1174. else
  1175. {
  1176. this.Canvas.beginPath();
  1177. if (isHScreen)
  1178. {
  1179. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  1180. this.Canvas.lineTo(yLow,ToFixedPoint(x));
  1181. }
  1182. else
  1183. {
  1184. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  1185. this.Canvas.lineTo(ToFixedPoint(x),yLow);
  1186. }
  1187. this.Canvas.strokeStyle=barColor;
  1188. this.Canvas.stroke();
  1189. }
  1190. }
  1191. //绘制自定义K线
  1192. this.DrawColorKBar=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  1193. {
  1194. if (Math.abs(yClose-yOpen)<1)
  1195. this.DrawColorKBar_Line(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  1196. else if (colorData.Border || colorData.Type===0)
  1197. this.DrawColorKBar_Border(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  1198. else
  1199. this.DrawColorKBar_NoBorder(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  1200. }
  1201. //带边框柱子
  1202. this.DrawColorKBar_Border=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  1203. {
  1204. if (dataWidth>=this.MinColorBarWidth)
  1205. {
  1206. if ((dataWidth%2)!=0) dataWidth-=1;
  1207. var topPrice=Math.max(data.Close,data.Open);
  1208. var bottomPrice=Math.min(data.Close,data.Open);
  1209. if (isHScreen)
  1210. {
  1211. var yBarTop=Math.max(yClose,yOpen);
  1212. var yBarBottom=Math.min(yClose,yOpen);
  1213. }
  1214. else
  1215. {
  1216. var yBarTop=Math.min(yClose,yOpen);
  1217. var yBarBottom=Math.max(yClose,yOpen);
  1218. }
  1219. var yBarHeight=Math.abs(yClose-yOpen);
  1220. //上影线
  1221. if (data.High>topPrice && colorData.Line)
  1222. {
  1223. this.Canvas.strokeStyle=colorData.Line.Color;
  1224. this.Canvas.beginPath();
  1225. if (isHScreen)
  1226. {
  1227. this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
  1228. this.Canvas.lineTo(ToFixedPoint(yBarTop),ToFixedPoint(x));
  1229. }
  1230. else
  1231. {
  1232. var xFixed=left+dataWidth/2;
  1233. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yHigh));
  1234. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yBarTop));
  1235. }
  1236. this.Canvas.stroke();
  1237. }
  1238. //下影线
  1239. if (bottomPrice>data.Low && colorData.Line)
  1240. {
  1241. this.Canvas.strokeStyle=colorData.Line.Color;
  1242. this.Canvas.beginPath();
  1243. if (isHScreen)
  1244. {
  1245. this.Canvas.moveTo(ToFixedPoint(yBarBottom),ToFixedPoint(x));
  1246. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  1247. }
  1248. else
  1249. {
  1250. var xFixed=left+dataWidth/2;
  1251. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yBarBottom));
  1252. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
  1253. }
  1254. this.Canvas.stroke();
  1255. }
  1256. //中心柱子
  1257. this.Canvas.beginPath();
  1258. if (isHScreen)
  1259. {
  1260. this.Canvas.rect(ToFixedPoint(yBarBottom),ToFixedPoint(left),ToFixedRect(yBarHeight),ToFixedRect(dataWidth));
  1261. }
  1262. else
  1263. {
  1264. this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(yBarTop),ToFixedRect(dataWidth),ToFixedRect(yBarHeight));
  1265. }
  1266. this.Canvas.closePath();
  1267. if (colorData.Type==0) //空心柱子
  1268. {
  1269. if (colorData.BarColor) //边框
  1270. {
  1271. this.Canvas.strokeStyle=colorData.BarColor;
  1272. this.Canvas.stroke();
  1273. }
  1274. if (colorData.Border)
  1275. {
  1276. this.Canvas.strokeStyle=colorData.Border.Color;
  1277. this.Canvas.stroke();
  1278. }
  1279. }
  1280. else if (colorData.Type==1) //实心
  1281. {
  1282. if (colorData.BarColor) //内部填充
  1283. {
  1284. this.Canvas.fillStyle=colorData.BarColor;
  1285. this.Canvas.fill();
  1286. }
  1287. if (colorData.Border) //边框
  1288. {
  1289. this.Canvas.strokeStyle=colorData.Border.Color;
  1290. this.Canvas.stroke();
  1291. }
  1292. }
  1293. }
  1294. else
  1295. {
  1296. this.DrawColorKBar_MinBar(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  1297. }
  1298. }
  1299. //不带边框柱子
  1300. this.DrawColorKBar_NoBorder=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  1301. {
  1302. if (dataWidth>=this.MinColorBarWidth)
  1303. {
  1304. var topPrice=Math.max(data.Close,data.Open);
  1305. var bottomPrice=Math.min(data.Close,data.Open);
  1306. if (isHScreen)
  1307. {
  1308. var yBarTop=Math.max(yClose,yOpen);
  1309. var yBarBottom=Math.min(yClose,yOpen);
  1310. }
  1311. else
  1312. {
  1313. var yBarTop=Math.min(yClose,yOpen);
  1314. var yBarBottom=Math.max(yClose,yOpen);
  1315. }
  1316. var yBarHeight=Math.abs(yClose-yOpen);
  1317. //上影线
  1318. if (data.High>topPrice && colorData.Line)
  1319. {
  1320. this.Canvas.strokeStyle=colorData.Line.Color;
  1321. this.Canvas.beginPath();
  1322. if (isHScreen)
  1323. {
  1324. this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
  1325. this.Canvas.lineTo(ToFixedPoint(yBarTop),ToFixedPoint(x));
  1326. }
  1327. else
  1328. {
  1329. var xFixed=left+dataWidth/2;
  1330. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yHigh));
  1331. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yBarTop));
  1332. }
  1333. this.Canvas.stroke();
  1334. }
  1335. //下影线
  1336. if (bottomPrice>data.Low && colorData.Line)
  1337. {
  1338. this.Canvas.strokeStyle=colorData.Line.Color;
  1339. this.Canvas.beginPath();
  1340. if (isHScreen)
  1341. {
  1342. this.Canvas.moveTo(ToFixedPoint(yBarBottom),ToFixedPoint(x));
  1343. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  1344. }
  1345. else
  1346. {
  1347. var xFixed=left+dataWidth/2;
  1348. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(yBarBottom));
  1349. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
  1350. }
  1351. this.Canvas.stroke();
  1352. }
  1353. //中心柱子
  1354. this.Canvas.beginPath();
  1355. if (isHScreen)
  1356. {
  1357. this.Canvas.rect(ToFixedPoint(yBarBottom),ToFixedPoint(left),ToFixedRect(yBarHeight),ToFixedRect(dataWidth));
  1358. }
  1359. else
  1360. {
  1361. this.Canvas.rect(ToFixedRect(left),ToFixedRect(yBarTop),ToFixedRect(dataWidth),ToFixedRect(yBarHeight));
  1362. }
  1363. this.Canvas.closePath();
  1364. if (colorData.Type==1) //实心
  1365. {
  1366. if (colorData.BarColor) //内部填充
  1367. {
  1368. this.Canvas.fillStyle=colorData.BarColor;
  1369. this.Canvas.fill();
  1370. }
  1371. }
  1372. }
  1373. else
  1374. {
  1375. this.DrawColorKBar_MinBar(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  1376. }
  1377. }
  1378. this.DrawColorKBar_MinBar=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  1379. {
  1380. if (colorData.Line)
  1381. {
  1382. this.Canvas.strokeStyle=colorData.Line.Color;
  1383. this.Canvas.beginPath();
  1384. if (isHScreen)
  1385. {
  1386. this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
  1387. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  1388. }
  1389. else
  1390. {
  1391. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yHigh));
  1392. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  1393. }
  1394. this.Canvas.stroke();
  1395. }
  1396. /*
  1397. var barColor;
  1398. if (colorData.Type==0) //空心柱子
  1399. {
  1400. if (colorData.Border) barColor=colorData.Border.Color;
  1401. else if (colorData.BarColor) barColor=colorData.BarColor;
  1402. }
  1403. else if (colorData.Type==1) //实心
  1404. {
  1405. if (colorData.Border) barColor=colorData.Border.Color;
  1406. else if (colorData.BarColor) barColor=colorData.BarColor;
  1407. }
  1408. if (barColor)
  1409. {
  1410. this.Canvas.strokeStyle=barColor;
  1411. this.Canvas.beginPath();
  1412. if (isHScreen)
  1413. {
  1414. this.Canvas.moveTo(ToFixedPoint(yOpen),ToFixedPoint(x));
  1415. this.Canvas.lineTo(ToFixedPoint(yClose),ToFixedPoint(x));
  1416. }
  1417. else
  1418. {
  1419. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yOpen));
  1420. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yClose));
  1421. }
  1422. this.Canvas.stroke();
  1423. }
  1424. */
  1425. }
  1426. //十字线
  1427. this.DrawColorKBar_Line=function(data, colorData, dataWidth, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  1428. {
  1429. if (dataWidth>=this.MinColorBarWidth)
  1430. {
  1431. if (colorData.Line)
  1432. {
  1433. this.Canvas.strokeStyle=colorData.Line.Color;
  1434. this.Canvas.beginPath();
  1435. if (isHScreen)
  1436. {
  1437. this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
  1438. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  1439. }
  1440. else
  1441. {
  1442. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yHigh));
  1443. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  1444. }
  1445. this.Canvas.stroke();
  1446. }
  1447. var barColor;
  1448. if (colorData.Type==0) //空心柱子
  1449. {
  1450. if (colorData.Border) barColor=colorData.Border.Color;
  1451. else if (colorData.BarColor) barColor=colorData.BarColor;
  1452. }
  1453. else if (colorData.Type==1) //实心
  1454. {
  1455. if (colorData.Border) barColor=colorData.Border.Color;
  1456. else if (colorData.BarColor) barColor=colorData.BarColor;
  1457. }
  1458. if (barColor)
  1459. {
  1460. this.Canvas.strokeStyle=barColor;
  1461. this.Canvas.beginPath();
  1462. if (isHScreen)
  1463. {
  1464. this.Canvas.moveTo(ToFixedPoint(yOpen),ToFixedPoint(left));
  1465. this.Canvas.lineTo(ToFixedPoint(yOpen),ToFixedPoint(right));
  1466. }
  1467. else
  1468. {
  1469. this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(yOpen));
  1470. this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(yOpen));
  1471. }
  1472. this.Canvas.stroke();
  1473. }
  1474. }
  1475. else
  1476. {
  1477. if (colorData.Line)
  1478. {
  1479. var xFixed=left+dataWidth/2;
  1480. this.Canvas.strokeStyle=colorData.Line.Color;
  1481. this.Canvas.beginPath();
  1482. if (isHScreen)
  1483. {
  1484. this.Canvas.moveTo(ToFixedPoint(yHigh),ToFixedPoint(x));
  1485. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  1486. }
  1487. else
  1488. {
  1489. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(yHigh));
  1490. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  1491. }
  1492. this.Canvas.stroke();
  1493. }
  1494. }
  1495. }
  1496. this.ClearCustomKLine=function()
  1497. {
  1498. this.CustomKLine=null;
  1499. }
  1500. this.GetCustomKLine=function(kItem)
  1501. {
  1502. if (!this.CustomKLine) return null;
  1503. if (!kItem) return null;
  1504. var key=kItem.Date*1000000;
  1505. if (IFrameSplitOperator.IsNumber(kItem.Time)) key+=kItem.Time;
  1506. if (!this.CustomKLine.has(key)) return null;
  1507. var value=this.CustomKLine.get(key);
  1508. return value;
  1509. }
  1510. this.DrawTrade = function () //交易系统
  1511. {
  1512. if (!this.TradeData) return;
  1513. var isHScreen = (this.ChartFrame.IsHScreen === true);
  1514. var dataWidth = this.ChartFrame.DataWidth;
  1515. var distanceWidth = this.ChartFrame.DistanceWidth;
  1516. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  1517. var chartright = this.ChartBorder.GetRight();
  1518. var xPointCount = this.ChartFrame.XPointCount;
  1519. if (isHScreen) {
  1520. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  1521. chartright = this.ChartBorder.GetBottom();
  1522. }
  1523. var sellData = this.TradeData.Sell;
  1524. var buyData = this.TradeData.Buy;
  1525. var arrowWidth = dataWidth;
  1526. if (arrowWidth > 10) arrowWidth = 10;
  1527. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth)) {
  1528. var data = this.Data.Data[i];
  1529. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  1530. var buy = false, sell = false;
  1531. if (sellData && i < sellData.length) sell = sellData[i] > 0;
  1532. if (buyData && i < buyData.length) buy = buyData[i] > 0;
  1533. if (!sell && !buy) continue;
  1534. var left = xOffset;
  1535. var right = xOffset + dataWidth;
  1536. if (right > chartright) break;
  1537. var x = left + (right - left) / 2;
  1538. var yLow = this.ChartFrame.GetYFromData(data.Low);
  1539. var yHigh = this.ChartFrame.GetYFromData(data.High);
  1540. var yOpen = this.ChartFrame.GetYFromData(data.Open);
  1541. var yClose = this.ChartFrame.GetYFromData(data.Close);
  1542. var y = yHigh;
  1543. if (buy) {
  1544. this.Canvas.fillStyle = this.UpColor;
  1545. this.Canvas.strokeStyle = this.UnchagneColor;
  1546. this.Canvas.beginPath();
  1547. if (isHScreen) {
  1548. this.Canvas.moveTo(yLow - 1, x);
  1549. this.Canvas.lineTo(yLow - arrowWidth - 1, x - arrowWidth / 2);
  1550. this.Canvas.lineTo(yLow - arrowWidth - 1, x + arrowWidth / 2);
  1551. }
  1552. else {
  1553. this.Canvas.moveTo(x, yLow + 1);
  1554. this.Canvas.lineTo(x - arrowWidth / 2, yLow + arrowWidth + 1);
  1555. this.Canvas.lineTo(x + arrowWidth / 2, yLow + arrowWidth + 1);
  1556. }
  1557. this.Canvas.closePath();
  1558. this.Canvas.fill();
  1559. this.Canvas.stroke();
  1560. }
  1561. if (sell) {
  1562. this.Canvas.fillStyle = this.DownColor;
  1563. this.Canvas.strokeStyle = this.UnchagneColor;
  1564. this.Canvas.beginPath();
  1565. if (isHScreen) {
  1566. this.Canvas.moveTo(yHigh + 1, x);
  1567. this.Canvas.lineTo(yHigh + arrowWidth + 1, x - arrowWidth / 2);
  1568. this.Canvas.lineTo(yHigh + arrowWidth + 1, x + arrowWidth / 2);
  1569. }
  1570. else {
  1571. this.Canvas.moveTo(x, yHigh - 1);
  1572. this.Canvas.lineTo(x - arrowWidth / 2, yHigh - arrowWidth - 1);
  1573. this.Canvas.lineTo(x + arrowWidth / 2, yHigh - arrowWidth - 1);
  1574. }
  1575. this.Canvas.closePath();
  1576. this.Canvas.fill();
  1577. this.Canvas.stroke();
  1578. }
  1579. }
  1580. }
  1581. this.Draw = function ()
  1582. {
  1583. this.PtMax = { X: null, Y: null, Value: null, Align: 'left' }; //清空最大
  1584. this.PtMin = { X: null, Y: null, Value: null, Align: 'left' }; //清空最小
  1585. this.ChartFrame.ChartKLine = { Max: null, Min: null }; //保存K线上 显示最大最小值坐标
  1586. this.DrawKRange={ Start:null, End:null };
  1587. this.AryPriceGapCache=[];
  1588. if (this.IsShow == false) return;
  1589. if (this.DrawType == 1)
  1590. {
  1591. this.DrawCloseLine();
  1592. if (this.PriceGap.Enable) this.DrawPriceGap();
  1593. return;
  1594. }
  1595. else if (this.DrawType == 2)
  1596. {
  1597. this.DrawAKLine();
  1598. }
  1599. else if (this.DrawType == 4)
  1600. {
  1601. this.DrawCloseArea();
  1602. }
  1603. else if (this.DrawType==9)
  1604. {
  1605. this.DrawKBar();
  1606. }
  1607. else
  1608. {
  1609. this.DrawKBar();
  1610. }
  1611. this.DrawTrade();
  1612. if (this.PriceGap.Enable) this.DrawPriceGap();
  1613. if (this.IsShowMaxMinPrice) //标注最大值最小值
  1614. {
  1615. if (this.ChartFrame.IsHScreen === true) this.HScreenDrawMaxMinPrice(this.PtMax, this.PtMin);
  1616. else this.DrawMaxMinPrice(this.PtMax, this.PtMin);
  1617. }
  1618. }
  1619. this.OnFormatHighLowTitle=function(ptMax, ptMin)
  1620. {
  1621. if (!ptMax || !ptMin) return null;
  1622. if (!IFrameSplitOperator.IsNumber(ptMax.Value) || !IFrameSplitOperator.IsNumber(ptMin.Value)) return null;
  1623. var defaultfloatPrecision=JSCommonCoordinateData.GetfloatPrecision(this.Symbol); //小数位数
  1624. var title=
  1625. {
  1626. High:ptMax.Value.toFixed(defaultfloatPrecision),
  1627. Low:ptMin.Value.toFixed(defaultfloatPrecision)
  1628. };
  1629. if (!this.GetEventCallback) return title;
  1630. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_FORMAT_KLINE_HIGH_LOW_TITLE);
  1631. if (!event || !event.Callback) return title;
  1632. var data={ Max:ptMax, Min:ptMin, Symbol:this.Symbol, Title:{ High:title.High, Low:title.Low }, Decimal:defaultfloatPrecision, PreventDefault:false };
  1633. event.Callback(event, data, this);
  1634. if (data.PreventDefault) return data.Title; //使用外部回调的数值
  1635. return title;
  1636. }
  1637. this.DrawMaxMinPrice = function (ptMax, ptMin)
  1638. {
  1639. if (ptMax.X == null || ptMax.Y == null || ptMax.Value == null) return;
  1640. if (ptMin.X == null || ptMin.Y == null || ptMin.Value == null) return;
  1641. var title=this.OnFormatHighLowTitle(ptMax,ptMin);
  1642. if (!title) return;
  1643. var leftArrow=g_JSChartResource.KLine.MaxMin.LeftArrow;
  1644. var rightArrow=g_JSChartResource.KLine.MaxMin.RightArrow;
  1645. var highYOffset=g_JSChartResource.KLine.MaxMin.HighYOffset;
  1646. var lowYOffset=g_JSChartResource.KLine.MaxMin.LowYOffset;
  1647. var defaultfloatPrecision = JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
  1648. this.Canvas.font = this.TextFont;
  1649. this.Canvas.textAlign = ptMax.Align;
  1650. this.Canvas.textBaseline = 'bottom';
  1651. var left = ptMax.X;
  1652. if (IFrameSplitOperator.IsNumber(highYOffset)) ptMax.Y+=highYOffset;
  1653. //var text = ptMax.Value.toFixed(defaultfloatPrecision);
  1654. var text=title.High;
  1655. var textColor=this.TextColor;
  1656. if (title.HighColor) textColor=title.HighColor;
  1657. this.Canvas.fillStyle = textColor;
  1658. if (ptMax.Align == 'left') text = leftArrow + text;
  1659. else text = text + rightArrow;
  1660. this.Canvas.fillText(text, left, ptMax.Y);
  1661. this.ChartFrame.ChartKLine.Max = { X: left, Y: ptMax.Y, Text: { BaseLine: 'bottom' } };
  1662. this.Canvas.textAlign = ptMin.Align;
  1663. this.Canvas.textBaseline = 'top';
  1664. var left = ptMin.X;
  1665. if (IFrameSplitOperator.IsNumber(lowYOffset)) ptMin.Y+=lowYOffset;
  1666. //text = ptMin.Value.toFixed(defaultfloatPrecision);
  1667. var text=title.Low;
  1668. var textColor=this.TextColor;
  1669. if (title.LowColor) textColor=title.LowColor;
  1670. this.Canvas.fillStyle = textColor;
  1671. if (ptMin.Align == 'left') text = leftArrow + text;
  1672. else text = text + rightArrow;
  1673. this.Canvas.fillText(text, left, ptMin.Y);
  1674. this.ChartFrame.ChartKLine.Min = { X: left, Y: ptMin.Y, Text: { BaseLine: 'top' } };
  1675. }
  1676. this.HScreenDrawMaxMinPrice = function (ptMax, ptMin) //横屏模式下显示最大最小值
  1677. {
  1678. if (ptMax.X == null || ptMax.Y == null || ptMax.Value == null) return;
  1679. if (ptMin.X == null || ptMin.Y == null || ptMin.Value == null) return;
  1680. var title=this.OnFormatHighLowTitle(ptMax,ptMin);
  1681. if (!title) return;
  1682. var leftArrow=g_JSChartResource.KLine.MaxMin.LeftArrow;
  1683. var rightArrow=g_JSChartResource.KLine.MaxMin.RightArrow;
  1684. var highYOffset=g_JSChartResource.KLine.MaxMin.HighYOffset;
  1685. var lowYOffset=g_JSChartResource.KLine.MaxMin.LowYOffset;
  1686. var defaultfloatPrecision = JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
  1687. var xText = ptMax.Y;
  1688. var yText = ptMax.X;
  1689. if (IFrameSplitOperator.IsNumber(highYOffset)) xText+=highYOffset;
  1690. this.Canvas.save();
  1691. this.Canvas.translate(xText, yText);
  1692. this.Canvas.rotate(90 * Math.PI / 180);
  1693. this.Canvas.font = this.TextFont;
  1694. if (title.HighColor) this.Canvas.fillStyle=title.HighColor;
  1695. else this.Canvas.fillStyle=this.TextColor;
  1696. this.Canvas.textAlign = ptMax.Align;
  1697. this.Canvas.textBaseline = 'bottom';
  1698. var text=title.High;
  1699. //var text = ptMax.Value.toFixed(defaultfloatPrecision);
  1700. if (ptMax.Align == 'left') text = leftArrow + text;
  1701. else text = text + rightArrow;
  1702. this.Canvas.fillText(text, 0, 0);
  1703. this.Canvas.restore();
  1704. var xText = ptMin.Y;
  1705. var yText = ptMin.X;
  1706. if (IFrameSplitOperator.IsNumber(lowYOffset)) xText+=lowYOffset;
  1707. this.Canvas.save();
  1708. this.Canvas.translate(xText, yText);
  1709. this.Canvas.rotate(90 * Math.PI / 180);
  1710. this.Canvas.font = this.TextFont;
  1711. if (title.LowColor) this.Canvas.fillStyle=title.LowColor;
  1712. else this.Canvas.fillStyle=this.TextColor;
  1713. this.Canvas.textAlign = ptMin.Align;
  1714. this.Canvas.textBaseline = 'top';
  1715. var text=title.Low;
  1716. //var text = ptMin.Value.toFixed(defaultfloatPrecision);
  1717. if (ptMin.Align == 'left') text = leftArrow + text;
  1718. else text = text + rightArrow;
  1719. this.Canvas.fillText(text, 0, 0);
  1720. this.Canvas.restore();
  1721. }
  1722. //画某一天的信息地雷 画在底部
  1723. this.DrawInfoDiv = function (item) {
  1724. if (!this.InfoData || this.InfoData.size <= 0) return;
  1725. var dataWidth = this.ChartFrame.DataWidth;
  1726. var distanceWidth = this.ChartFrame.DistanceWidth;
  1727. var infoData = this.InfoData.get(item.DayData.Date.toString());
  1728. if (!infoData || infoData.Data.length <= 0) return;
  1729. var bHScreen = (this.ChartFrame.IsHScreen === true);
  1730. if (this.InfoDrawType === 1) {
  1731. this.Canvas.font = this.GetDynamicFont(dataWidth);
  1732. this.Canvas.fillStyle = this.InfoPointColor2;
  1733. this.Canvas.textAlign = 'center';
  1734. this.Canvas.textBaseline = 'top';
  1735. if (bHScreen) {
  1736. var xText = item.YMin;
  1737. var yText = item.X;
  1738. this.Canvas.save();
  1739. this.Canvas.translate(xText, yText);
  1740. this.Canvas.rotate(90 * Math.PI / 180);
  1741. this.Canvas.fillText('▲', 0, 0);
  1742. this.Canvas.restore();
  1743. }
  1744. else {
  1745. var left = ToFixedPoint(item.X);
  1746. this.Canvas.fillText('▲', left, item.YMin);
  1747. }
  1748. }
  1749. else {
  1750. var dataWidth = this.ChartFrame.DataWidth;
  1751. var radius = dataWidth / 2;
  1752. if (radius > 3) radius = 3;
  1753. var x = item.X;
  1754. var y = this.ChartFrame.ChartBorder.GetBottom() - 2 - radius;
  1755. if (bHScreen) y = this.ChartFrame.ChartBorder.GetLeft() + 2 + radius;
  1756. this.Canvas.fillStyle = this.InfoPointColor;
  1757. this.Canvas.beginPath();
  1758. if (bHScreen) this.Canvas.arc(y, x, radius, 0, Math.PI * 2, true);
  1759. else this.Canvas.arc(ToFixedPoint(x), y, radius, 0, Math.PI * 2, true);
  1760. this.Canvas.closePath();
  1761. this.Canvas.fill();
  1762. }
  1763. }
  1764. this.GetTooltipData = function (x, y, tooltip) {
  1765. return false;
  1766. }
  1767. this.GetMaxMin = function () //计算当天显示数据的最大最小值
  1768. {
  1769. var xPointCount = this.ChartFrame.XPointCount;
  1770. var range = {};
  1771. range.Max = null;
  1772. range.Min = null;
  1773. if (this.IsShow == false) return range;
  1774. if (this.DrawType==1 || this.DrawType==4 ) // 1=收盘价线 4=收盘价面积图
  1775. {
  1776. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
  1777. {
  1778. var data=this.Data.Data[i];
  1779. if (!IFrameSplitOperator.IsNumber(data.Close)) continue;
  1780. if (range.Max==null) range.Max=data.Close;
  1781. if (range.Min==null) range.Min=data.Close;
  1782. if (range.Max<data.Close) range.Max=data.Close;
  1783. if (range.Min>data.Close) range.Min=data.Close;
  1784. }
  1785. }
  1786. else
  1787. {
  1788. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  1789. {
  1790. var data = this.Data.Data[i];
  1791. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  1792. if (range.Max == null) range.Max = data.High;
  1793. if (range.Min == null) range.Min = data.Low;
  1794. if (range.Max < data.High) range.Max = data.High;
  1795. if (range.Min > data.Low) range.Min = data.Low;
  1796. }
  1797. }
  1798. return range;
  1799. }
  1800. this.DrawLastPointEvent=function(ptLast)
  1801. {
  1802. if (!this.GetEventCallback) return;
  1803. //通知外部绘制最后一个点
  1804. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_DRAW_KLINE_LAST_POINT);
  1805. if (event)
  1806. {
  1807. var kWidth={ Data: this.ChartFrame.DataWidth, Distance:this.ChartFrame.DistanceWidth };
  1808. if (ptLast) var data={ LastPoint:{ X:ptLast.X, Y:ptLast.Y, XLeft:ptLast.XLeft, XRight:ptLast.XRight }, KItem:ptLast.KItem, DrawType:this.DrawType, KWidth:kWidth, ChartRight:ptLast.ChartRight };
  1809. else var data={ LastPoint:null, KItem:null, KWidth:kWidth };
  1810. event.Callback(event,data,this);
  1811. }
  1812. }
  1813. //////////////////////////////////////////////////////////////
  1814. // 标识缺口
  1815. /////////////////////////////////////////////////////////////
  1816. this.DrawPriceGap=function()
  1817. {
  1818. if (!IFrameSplitOperator.IsNonEmptyArray(this.AryPriceGapCache)) return;
  1819. if (this.PriceGap.Count<=0) return;
  1820. var index=this.AryPriceGapCache.length-this.PriceGap.Count;
  1821. if (index<0) index=0;
  1822. var isHScreen=(this.ChartFrame.IsHScreen===true);
  1823. var border=null;
  1824. if (isHScreen) border=this.ChartBorder.GetHScreenBorder();
  1825. else border=this.ChartBorder.GetBorder();
  1826. this.Canvas.font=this.PriceGapStyple.Text.Font;
  1827. this.Canvas.textAlign = 'left';
  1828. this.Canvas.textBaseline = 'bottom';
  1829. var textHeight=this.Canvas.measureText("擎").width;
  1830. var decNum=JSCommonCoordinateData.GetfloatPrecision(this.Symbol);
  1831. for(var i=index;i<this.AryPriceGapCache.length;++i)
  1832. {
  1833. var item=this.AryPriceGapCache[i];
  1834. var start=item.Data[0];
  1835. var end=item.Data[1];
  1836. var rect=null, rtText=null, text=null;
  1837. if (item.Type==1) //上缺口
  1838. {
  1839. if (isHScreen)
  1840. {
  1841. rect={ Left:start.Coordinate.High, Right:end.Coordinate.Low, Top:start.Coordinate.X, Bottom: border.Bottom };
  1842. rect.Width=rect.Right-rect.Left;
  1843. rect.Height=rect.Bottom-rect.Top;
  1844. rtText={ Left:start.Coordinate.High-textHeight-2, Top:start.Coordinate.Right+2, Height:textHeight };
  1845. rtText.Bottom=rtText.Top+rtText.Height;
  1846. }
  1847. else
  1848. {
  1849. rect={ Left:start.Coordinate.X, Right:border.Right, Top:end.Coordinate.Low, Bottom:start.Coordinate.High };
  1850. rect.Width=rect.Right-rect.Left;
  1851. rect.Height=rect.Bottom-rect.Top;
  1852. rtText={ Left:start.Coordinate.Right+2, Top:rect.Bottom+2, Right:rect.Right, Height:textHeight };
  1853. rtText.Bottom=rtText.Top+rtText.Height;
  1854. }
  1855. text=`${start.Data.High.toFixed(decNum)}-${end.Data.Low.toFixed(decNum)}`;
  1856. }
  1857. else if (item.Type==2) //下缺口
  1858. {
  1859. if (isHScreen)
  1860. {
  1861. rect={ Left:start.Coordinate.Low, Right:end.Coordinate.High, Top:start.Coordinate.X, Bottom: border.Bottom };
  1862. rect.Width=rect.Right-rect.Left;
  1863. rect.Height=rect.Bottom-rect.Top;
  1864. rtText={ Left:start.Coordinate.Low+2, Top:start.Coordinate.Right+2, Height:textHeight };
  1865. rtText.Bottom=rtText.Top+rtText.Height;
  1866. }
  1867. else
  1868. {
  1869. rect={ Left:start.Coordinate.X, Right:border.Right, Top:start.Coordinate.Low, Bottom:end.Coordinate.High };
  1870. rect.Width=rect.Right-rect.Left;
  1871. rect.Height=rect.Bottom-rect.Top;
  1872. rtText={ Left:start.Coordinate.Right+2, Bottom:rect.Top, Right:rect.Right, Height:textHeight };
  1873. rtText.Top=rtText.Bottom-rtText.Height;
  1874. }
  1875. text=`${start.Data.Low.toFixed(decNum)}-${end.Data.High.toFixed(decNum)}`;
  1876. }
  1877. else
  1878. {
  1879. continue;
  1880. }
  1881. if (!rect) return;
  1882. this.Canvas.fillStyle=this.PriceGapStyple.Line.Color;
  1883. this.Canvas.fillRect(rect.Left, rect.Top,rect.Width, rect.Height);
  1884. if (rtText)
  1885. {
  1886. var textWidth=this.Canvas.measureText(text).width;
  1887. rtText.Width=textWidth;
  1888. rtText.Right=rtText.Left+rtText.Width;
  1889. this.Canvas.fillStyle=this.PriceGapStyple.Text.Color;
  1890. if (isHScreen)
  1891. {
  1892. this.Canvas.save();
  1893. this.Canvas.translate(rtText.Left, rtText.Top);
  1894. this.Canvas.rotate(90 * Math.PI / 180);
  1895. this.Canvas.fillText(text,0,0);
  1896. this.Canvas.restore();
  1897. }
  1898. else
  1899. {
  1900. if (rtText.Right>rect.Right)
  1901. {
  1902. rtText.Right=rect.Right;
  1903. rtText.Left=rtText.Right-rtText.Width;
  1904. }
  1905. this.Canvas.fillStyle=this.PriceGapStyple.Text.Color;
  1906. this.Canvas.fillText(text,rtText.Left,rtText.Bottom);
  1907. }
  1908. //this.Canvas.fillStyle="rgb(250,250,250)"
  1909. //this.Canvas.fillRect(rtText.Left, rtText.Top, rtText.Width, rtText.Height);
  1910. }
  1911. }
  1912. }
  1913. //是否有缺口
  1914. this.IsPriceGap=function(item, preItem)
  1915. {
  1916. if (!preItem || !item) return 0;
  1917. if (preItem.Data.Low>item.Data.High) return 2; //下缺口
  1918. if (preItem.Data.High<item.Data.Low) return 1; //上缺口
  1919. return -1;
  1920. }
  1921. //检测缺口是不回补了
  1922. this.CheckPriceGap=function(kItemInfo)
  1923. {
  1924. var kItem=kItemInfo.Data;
  1925. for(var i=0;i<this.AryPriceGapCache.length;++i)
  1926. {
  1927. var item=this.AryPriceGapCache[i];
  1928. var start=item.Data[0];
  1929. var end=item.Data[1];
  1930. if (item.Type==1) //上缺口
  1931. {
  1932. if (kItem.Low<=start.Data.High)
  1933. {
  1934. this.AryPriceGapCache.splice(i,1);
  1935. --i;
  1936. continue;
  1937. }
  1938. if (kItem.Low<end.Data.Low) item.Data[1]=kItemInfo;
  1939. }
  1940. else if (item.Type==2) //下缺口
  1941. {
  1942. if (kItem.High>=start.Data.Low)
  1943. {
  1944. this.AryPriceGapCache.splice(i,1);
  1945. --i;
  1946. continue;
  1947. }
  1948. if (kItem.High>end.Data.High) item.Data[1]=kItemInfo;
  1949. }
  1950. }
  1951. }
  1952. }
  1953. function ChartColorKline()
  1954. {
  1955. this.newMethod=IChartPainting; //派生
  1956. this.newMethod();
  1957. delete this.newMethod;
  1958. this.ClassName='ChartColorKline'; //类名
  1959. this.Symbol; //股票代码
  1960. this.Color='rgb(0,255,44)';
  1961. this.IsEmptyBar=false;
  1962. this.DrawType=0; //0=实心K线柱子 3=空心K线柱子
  1963. this.KLineColor; //Map key=K线索引 value=设置
  1964. this.DrawName;
  1965. this.Draw=function()
  1966. {
  1967. if (!this.IsShow) return;
  1968. if (this.DrawName=="DRAWCOLORKLINE")
  1969. {
  1970. this.DrawColorBar();
  1971. }
  1972. else
  1973. {
  1974. if (!this.KLineColor) return;
  1975. this.DrawBar();
  1976. }
  1977. }
  1978. this.DrawUpBarItem=function(data, xOffset, dataWidth, option)
  1979. {
  1980. var isHScreen=(this.ChartFrame.IsHScreen===true);
  1981. var left=xOffset;
  1982. var right=xOffset+dataWidth;
  1983. var x=left+(right-left)/2;
  1984. var yLow=this.ChartFrame.GetYFromData(data.Low);
  1985. var yHigh=this.ChartFrame.GetYFromData(data.High);
  1986. var yOpen=this.ChartFrame.GetYFromData(data.Open);
  1987. var yClose=this.ChartFrame.GetYFromData(data.Close);
  1988. var y=yHigh;
  1989. if (dataWidth>=4)
  1990. {
  1991. if (data.High>data.Close) //上影线
  1992. {
  1993. this.Canvas.beginPath();
  1994. if (isHScreen)
  1995. {
  1996. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  1997. this.Canvas.lineTo(ToFixedPoint(this.DrawType==3?Math.max(yClose,yOpen):yClose),ToFixedPoint(x));
  1998. }
  1999. else
  2000. {
  2001. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  2002. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(this.DrawType==3?Math.min(yClose,yOpen):yClose));
  2003. }
  2004. this.Canvas.stroke();
  2005. y=yClose;
  2006. }
  2007. else
  2008. {
  2009. y=yClose;
  2010. }
  2011. if (isHScreen)
  2012. {
  2013. if (Math.abs(yOpen-y)<1)
  2014. {
  2015. this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  2016. }
  2017. else
  2018. {
  2019. if (this.DrawType==3) //空心柱
  2020. {
  2021. this.Canvas.beginPath();
  2022. this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
  2023. this.Canvas.stroke();
  2024. }
  2025. else
  2026. {
  2027. this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
  2028. }
  2029. }
  2030. }
  2031. else
  2032. {
  2033. if (Math.abs(yOpen-y)<1)
  2034. {
  2035. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
  2036. }
  2037. else
  2038. {
  2039. if (this.DrawType==3) //空心柱
  2040. {
  2041. this.Canvas.beginPath();
  2042. this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(y),ToFixedRect(dataWidth),ToFixedRect(yOpen-y));
  2043. this.Canvas.stroke();
  2044. }
  2045. else
  2046. {
  2047. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yOpen)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yOpen-y)));
  2048. }
  2049. }
  2050. }
  2051. if (data.Open>data.Low) //下影线
  2052. {
  2053. this.Canvas.beginPath();
  2054. if (isHScreen)
  2055. {
  2056. this.Canvas.moveTo(ToFixedPoint(this.DrawType==3?Math.min(yClose,yOpen):y),ToFixedPoint(x));
  2057. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  2058. }
  2059. else
  2060. {
  2061. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(this.DrawType==3?Math.max(yClose,yOpen):y));
  2062. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  2063. }
  2064. this.Canvas.stroke();
  2065. }
  2066. }
  2067. else
  2068. {
  2069. this.Canvas.beginPath();
  2070. if (isHScreen)
  2071. {
  2072. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  2073. this.Canvas.lineTo(yLow,ToFixedPoint(x));
  2074. }
  2075. else
  2076. {
  2077. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  2078. this.Canvas.lineTo(ToFixedPoint(x),yLow);
  2079. }
  2080. this.Canvas.stroke();
  2081. }
  2082. }
  2083. this.DrawDownBarItem=function(data, xOffset, dataWidth, option)
  2084. {
  2085. var isHScreen=(this.ChartFrame.IsHScreen===true);
  2086. var left=xOffset;
  2087. var right=xOffset+dataWidth;
  2088. var x=left+(right-left)/2;
  2089. var yLow=this.ChartFrame.GetYFromData(data.Low);
  2090. var yHigh=this.ChartFrame.GetYFromData(data.High);
  2091. var yOpen=this.ChartFrame.GetYFromData(data.Open);
  2092. var yClose=this.ChartFrame.GetYFromData(data.Close);
  2093. var y=yHigh;
  2094. if (dataWidth>=4)
  2095. {
  2096. if (data.High>data.Close) //上影线
  2097. {
  2098. this.Canvas.beginPath();
  2099. if (isHScreen)
  2100. {
  2101. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  2102. this.Canvas.lineTo(ToFixedPoint(yOpen),ToFixedPoint(x));
  2103. }
  2104. else
  2105. {
  2106. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  2107. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yOpen));
  2108. }
  2109. this.Canvas.stroke();
  2110. y=yOpen;
  2111. }
  2112. else
  2113. {
  2114. y=yOpen
  2115. }
  2116. if (isHScreen)
  2117. {
  2118. if (Math.abs(yClose-y)<1) this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  2119. else this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yClose-y),ToFixedRect(dataWidth));
  2120. }
  2121. else
  2122. {
  2123. if (Math.abs(yClose-y)<1) this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
  2124. else this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yClose)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yClose-y)));
  2125. }
  2126. if (data.Open>data.Low) //下影线
  2127. {
  2128. this.Canvas.beginPath();
  2129. if (isHScreen)
  2130. {
  2131. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  2132. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  2133. }
  2134. else
  2135. {
  2136. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  2137. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  2138. }
  2139. this.Canvas.stroke();
  2140. }
  2141. }
  2142. else
  2143. {
  2144. this.Canvas.beginPath();
  2145. if (isHScreen)
  2146. {
  2147. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  2148. this.Canvas.lineTo(yLow,ToFixedPoint(x));
  2149. }
  2150. else
  2151. {
  2152. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  2153. this.Canvas.lineTo(ToFixedPoint(x),yLow);
  2154. }
  2155. this.Canvas.stroke();
  2156. }
  2157. }
  2158. this.DrawUnChangeBarItem=function(data, xOffset, dataWidth, option)
  2159. {
  2160. var isHScreen=(this.ChartFrame.IsHScreen===true);
  2161. var left=xOffset;
  2162. var right=xOffset+dataWidth;
  2163. var x=left+(right-left)/2;
  2164. var yLow=this.ChartFrame.GetYFromData(data.Low);
  2165. var yHigh=this.ChartFrame.GetYFromData(data.High);
  2166. var yOpen=this.ChartFrame.GetYFromData(data.Open);
  2167. var yClose=this.ChartFrame.GetYFromData(data.Close);
  2168. var y=yHigh;
  2169. if (dataWidth>=4)
  2170. {
  2171. this.Canvas.beginPath();
  2172. if (data.High>data.Close) //上影线
  2173. {
  2174. if (isHScreen)
  2175. {
  2176. this.Canvas.moveTo(y,ToFixedPoint(x));
  2177. this.Canvas.lineTo(yOpen,ToFixedPoint(x));
  2178. }
  2179. else
  2180. {
  2181. this.Canvas.moveTo(ToFixedPoint(x),y);
  2182. this.Canvas.lineTo(ToFixedPoint(x),yOpen);
  2183. }
  2184. y=yOpen;
  2185. }
  2186. else
  2187. {
  2188. y=yOpen;
  2189. }
  2190. if (isHScreen)
  2191. {
  2192. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(left));
  2193. this.Canvas.lineTo(ToFixedPoint(y),ToFixedPoint(right));
  2194. }
  2195. else
  2196. {
  2197. this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(y));
  2198. this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(y));
  2199. }
  2200. if (data.Open>data.Low) //下影线
  2201. {
  2202. if (isHScreen)
  2203. {
  2204. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  2205. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  2206. }
  2207. else
  2208. {
  2209. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  2210. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  2211. }
  2212. }
  2213. this.Canvas.stroke();
  2214. }
  2215. else
  2216. {
  2217. this.Canvas.beginPath();
  2218. if (isHScreen)
  2219. {
  2220. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  2221. this.Canvas.lineTo(yLow,ToFixedPoint(x));
  2222. }
  2223. else
  2224. {
  2225. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  2226. this.Canvas.lineTo(ToFixedPoint(x),yLow);
  2227. }
  2228. this.Canvas.stroke();
  2229. }
  2230. }
  2231. this.DrawBar=function()
  2232. {
  2233. var dataWidth=this.ChartFrame.DataWidth;
  2234. var distanceWidth=this.ChartFrame.DistanceWidth;
  2235. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+2.0;
  2236. var chartright=this.ChartBorder.GetRight();
  2237. var xPointCount=this.ChartFrame.XPointCount;
  2238. if (this.IsHScreen)
  2239. {
  2240. xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+2.0;
  2241. chartright=this.ChartBorder.GetBottom();
  2242. }
  2243. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  2244. {
  2245. var data=this.Data.Data[i];
  2246. if (data.Open==null || data.High==null || data.Low==null || data.Close==null) continue;
  2247. if (!this.KLineColor.has(i)) continue;
  2248. var itemOption=this.KLineColor.get(i);
  2249. var left=xOffset;
  2250. var right=xOffset+dataWidth;
  2251. if (right>chartright) break;
  2252. if (itemOption.Color)
  2253. {
  2254. this.Canvas.strokeStyle=itemOption.Color;
  2255. this.Canvas.fillStyle=itemOption.Color;
  2256. }
  2257. else
  2258. {
  2259. this.Canvas.strokeStyle=this.Color;
  2260. this.Canvas.fillStyle=this.Color;
  2261. }
  2262. if (data.Open<data.Close) //阳线
  2263. {
  2264. this.DrawUpBarItem(data,xOffset,dataWidth,itemOption);
  2265. }
  2266. else if (data.Open>data.Close) //阴线
  2267. {
  2268. this.DrawDownBarItem(data,xOffset,dataWidth,itemOption);
  2269. }
  2270. else //平线
  2271. {
  2272. this.DrawUnChangeBarItem(data,xOffset,dataWidth,itemOption);
  2273. }
  2274. }
  2275. }
  2276. this.DrawColorBar=function()
  2277. {
  2278. var isHScreen=(this.ChartFrame.IsHScreen===true);
  2279. var dataWidth=this.ChartFrame.DataWidth;
  2280. var distanceWidth=this.ChartFrame.DistanceWidth;
  2281. var border=this.ChartBorder.GetBorder();
  2282. var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  2283. var chartright=border.RightEx;
  2284. var xPointCount=this.ChartFrame.XPointCount;
  2285. if (isHScreen)
  2286. {
  2287. var border=this.ChartBorder.GetHScreenBorder();
  2288. xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  2289. chartright=border.BottomEx;
  2290. }
  2291. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  2292. {
  2293. var data=this.Data.Data[i];
  2294. if (!data) continue;
  2295. if (!IFrameSplitOperator.IsNumber(data.Open) || !IFrameSplitOperator.IsNumber(data.High) ||
  2296. !IFrameSplitOperator.IsNumber(data.Low) || !IFrameSplitOperator.IsNumber(data.Close)) continue;
  2297. var left=xOffset;
  2298. var right=xOffset+dataWidth;
  2299. if (right>chartright) break;
  2300. var x=left+(right-left)/2;
  2301. var yLow=this.GetYFromData(data.Low, false);
  2302. var yHigh=this.GetYFromData(data.High, false);
  2303. var yOpen=this.GetYFromData(data.Open, false);
  2304. var yClose=this.GetYFromData(data.Close, false);
  2305. var y=yHigh;
  2306. if (data.Open==data.Close)
  2307. this.DrawKBar_Unchagne(data, dataWidth, this.Color, this.IsEmptyBar, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  2308. else
  2309. this.DrawKBar_Custom(data, dataWidth, this.Color, this.IsEmptyBar, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen);
  2310. }
  2311. }
  2312. this.DrawKBar_Unchagne=function(data, dataWidth, unchagneColor, drawType, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  2313. {
  2314. if (dataWidth>=4)
  2315. {
  2316. if ((dataWidth%2)!=0) dataWidth-=1;
  2317. this.Canvas.strokeStyle=unchagneColor;
  2318. this.Canvas.beginPath();
  2319. if (data.High>data.Close) //上影线
  2320. {
  2321. if (isHScreen)
  2322. {
  2323. this.Canvas.moveTo(y,ToFixedPoint(x));
  2324. this.Canvas.lineTo(yOpen,ToFixedPoint(x));
  2325. }
  2326. else
  2327. {
  2328. var xFixed=ToFixedPoint(left+dataWidth/2);
  2329. this.Canvas.moveTo(xFixed,y);
  2330. this.Canvas.lineTo(xFixed,yOpen);
  2331. }
  2332. y=yOpen;
  2333. }
  2334. else
  2335. {
  2336. y=yOpen;
  2337. }
  2338. if (isHScreen)
  2339. {
  2340. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(left));
  2341. this.Canvas.lineTo(ToFixedPoint(y),ToFixedPoint(right));
  2342. }
  2343. else
  2344. {
  2345. this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(y));
  2346. this.Canvas.lineTo(ToFixedPoint(left+dataWidth),ToFixedPoint(y));
  2347. }
  2348. if (data.Open>data.Low) //下影线
  2349. {
  2350. if (isHScreen)
  2351. {
  2352. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  2353. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  2354. }
  2355. else
  2356. {
  2357. var xFixed=ToFixedPoint(left+dataWidth/2);
  2358. this.Canvas.moveTo(xFixed,ToFixedPoint(y));
  2359. this.Canvas.lineTo(xFixed,ToFixedPoint(yLow));
  2360. }
  2361. }
  2362. this.Canvas.stroke();
  2363. }
  2364. else
  2365. {
  2366. this.Canvas.beginPath();
  2367. if (isHScreen)
  2368. {
  2369. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  2370. this.Canvas.lineTo(yLow,ToFixedPoint(x));
  2371. }
  2372. else
  2373. {
  2374. if (data.High==data.Low)
  2375. {
  2376. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  2377. this.Canvas.lineTo(ToFixedPoint(x),yLow+1);
  2378. }
  2379. else
  2380. {
  2381. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  2382. this.Canvas.lineTo(ToFixedPoint(x),yLow);
  2383. }
  2384. }
  2385. this.Canvas.strokeStyle=unchagneColor;
  2386. this.Canvas.stroke();
  2387. }
  2388. }
  2389. this.DrawKBar_Custom=function(data, dataWidth, barColor, isEmptyBar, x, y, left, right, yLow, yHigh, yOpen, yClose, isHScreen)
  2390. {
  2391. if (isEmptyBar)
  2392. {
  2393. if ((dataWidth%2)!=0) dataWidth-=1;
  2394. }
  2395. if (dataWidth>=4)
  2396. {
  2397. this.Canvas.strokeStyle=barColor;
  2398. if (data.High>data.Close) //上影线
  2399. {
  2400. this.Canvas.beginPath();
  2401. if (isHScreen)
  2402. {
  2403. this.Canvas.moveTo(ToFixedPoint(y),ToFixedPoint(x));
  2404. this.Canvas.lineTo(ToFixedPoint(isEmptyBar?Math.max(yClose,yOpen):yClose),ToFixedPoint(x));
  2405. }
  2406. else
  2407. {
  2408. if (isEmptyBar)
  2409. {
  2410. var xFixed=left+dataWidth/2;
  2411. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(y));
  2412. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(Math.min(yClose,yOpen)));
  2413. }
  2414. else
  2415. {
  2416. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  2417. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yClose));
  2418. }
  2419. }
  2420. this.Canvas.stroke();
  2421. y=yClose;
  2422. }
  2423. else
  2424. {
  2425. y=yClose;
  2426. }
  2427. this.Canvas.fillStyle=barColor;
  2428. if (isHScreen)
  2429. {
  2430. if (Math.abs(yOpen-y)<1)
  2431. {
  2432. this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),1,ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  2433. }
  2434. else
  2435. {
  2436. if (isEmptyBar) //空心柱
  2437. {
  2438. this.Canvas.beginPath();
  2439. this.Canvas.rect(ToFixedPoint(y),ToFixedPoint(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
  2440. this.Canvas.stroke();
  2441. }
  2442. else
  2443. {
  2444. this.Canvas.fillRect(ToFixedRect(y),ToFixedRect(left),ToFixedRect(yOpen-y),ToFixedRect(dataWidth));
  2445. }
  2446. }
  2447. }
  2448. else
  2449. {
  2450. if (Math.abs(yOpen-y)<1)
  2451. {
  2452. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(y),ToFixedRect(dataWidth),1); //高度小于1,统一使用高度1
  2453. }
  2454. else
  2455. {
  2456. if (isEmptyBar) //空心柱
  2457. {
  2458. this.Canvas.beginPath();
  2459. this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(y),ToFixedRect(dataWidth),ToFixedRect(yOpen-y));
  2460. this.Canvas.stroke();
  2461. }
  2462. else
  2463. {
  2464. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,yOpen)),ToFixedRect(dataWidth),ToFixedRect(Math.abs(yOpen-y)));
  2465. }
  2466. }
  2467. }
  2468. if (data.Open>data.Low) //下影线
  2469. {
  2470. this.Canvas.beginPath();
  2471. if (isHScreen)
  2472. {
  2473. this.Canvas.moveTo(ToFixedPoint(isEmptyBar?Math.min(yClose,yOpen):y),ToFixedPoint(x));
  2474. this.Canvas.lineTo(ToFixedPoint(yLow),ToFixedPoint(x));
  2475. }
  2476. else
  2477. {
  2478. if (isEmptyBar)
  2479. {
  2480. var xFixed=left+dataWidth/2;
  2481. this.Canvas.moveTo(ToFixedPoint(xFixed),ToFixedPoint(Math.max(yClose,yOpen)));
  2482. this.Canvas.lineTo(ToFixedPoint(xFixed),ToFixedPoint(yLow));
  2483. }
  2484. else
  2485. {
  2486. this.Canvas.moveTo(ToFixedPoint(x),ToFixedPoint(y));
  2487. this.Canvas.lineTo(ToFixedPoint(x),ToFixedPoint(yLow));
  2488. }
  2489. }
  2490. this.Canvas.stroke();
  2491. }
  2492. }
  2493. else
  2494. {
  2495. this.Canvas.beginPath();
  2496. if (isHScreen)
  2497. {
  2498. this.Canvas.moveTo(yHigh,ToFixedPoint(x));
  2499. this.Canvas.lineTo(yLow,ToFixedPoint(x));
  2500. }
  2501. else
  2502. {
  2503. this.Canvas.moveTo(ToFixedPoint(x),yHigh);
  2504. this.Canvas.lineTo(ToFixedPoint(x),yLow);
  2505. }
  2506. this.Canvas.strokeStyle=barColor;
  2507. this.Canvas.stroke();
  2508. }
  2509. }
  2510. this.GetMaxMin=function()
  2511. {
  2512. var range={Max:null,Min:null };
  2513. if (this.DrawName=="DRAWCOLORKLINE")
  2514. {
  2515. var xPointCount=this.ChartFrame.XPointCount;
  2516. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
  2517. {
  2518. var data=this.Data.Data[i];
  2519. if (!data) continue;
  2520. if (data.Open==null || data.High==null || data.Low==null || data.Close==null) continue;
  2521. if (range.Max==null) range.Max=data.High;
  2522. if (range.Min==null) range.Min=data.Low;
  2523. if (range.Max<data.High) range.Max=data.High;
  2524. if (range.Min>data.Low) range.Min=data.Low;
  2525. }
  2526. }
  2527. return range;
  2528. }
  2529. }
  2530. function ChartDrawIcon()
  2531. {
  2532. this.newMethod = IChartPainting; //派生
  2533. this.newMethod();
  2534. delete this.newMethod;
  2535. this.ClassName="ChartDrawIcon";
  2536. this.IsHScreen=false; //是否横屏
  2537. this.DrawCallback; //function(op, obj) op:1=开始 2=绘制 4=销毁
  2538. this.IsDestroy=false; //是否已销毁
  2539. this.TextAlign = 'left';
  2540. this.TextBaseline="middle";
  2541. this.IconID;
  2542. this.Color;
  2543. this.FixedIconSize;
  2544. this.DrawItem=[];
  2545. this.Identify;
  2546. this.Draw=function()
  2547. {
  2548. this.DrawItem=[];
  2549. if (this.DrawCallback) this.DrawCallback(1, {Self:this} );
  2550. this.DrawAllText();
  2551. if (this.DrawCallback) this.DrawCallback(2, { Self:this, Draw:this.DrawItem } );
  2552. }
  2553. this.DrawAllText=function()
  2554. {
  2555. var isHScreen = (this.ChartFrame.IsHScreen === true)
  2556. var dataWidth = this.ChartFrame.DataWidth;
  2557. var distanceWidth = this.ChartFrame.DistanceWidth;
  2558. var chartright = this.ChartBorder.GetRight();
  2559. var top = this.ChartBorder.GetTopEx();
  2560. var bottom = this.ChartBorder.GetBottomEx();
  2561. if (isHScreen)
  2562. {
  2563. chartright = this.ChartBorder.GetBottom();
  2564. top = this.ChartBorder.GetRightEx();
  2565. bottom = this.ChartBorder.GetLeftEx();
  2566. }
  2567. var xPointCount = this.ChartFrame.XPointCount;
  2568. var isArrayText = Array.isArray(this.Text);
  2569. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  2570. {
  2571. var value = this.Data.Data[i];
  2572. if (value == null) continue;
  2573. var x = this.ChartFrame.GetXFromIndex(j);
  2574. var y = this.ChartFrame.GetYFromData(value);
  2575. if (x > chartright) break;
  2576. var drawTextInfo=
  2577. {
  2578. Text:
  2579. {
  2580. Color:this.Color,
  2581. Align:this.TextAlign,
  2582. Baseline:this.TextBaseline,
  2583. },
  2584. X:x, Y:y,
  2585. IconID:this.IconID
  2586. };
  2587. this.DrawItem.push(drawTextInfo);
  2588. }
  2589. }
  2590. this.OnDestroy=function()
  2591. {
  2592. this.IsDestroy=true;
  2593. if (this.DrawCallback) this.DrawCallback(4, { Self:this } );
  2594. }
  2595. }
  2596. /*
  2597. 文字输出 支持横屏
  2598. 数组不为null的数据中输出 this.Text文本
  2599. */
  2600. function ChartSingleText()
  2601. {
  2602. this.newMethod = IChartPainting; //派生
  2603. this.newMethod();
  2604. delete this.newMethod;
  2605. this.Color = "rgb(255,193,37)"; //线段颜色
  2606. this.TextFont = "14px 微软雅黑"; //字体
  2607. this.Text;
  2608. this.TextAlign = 'left';
  2609. this.Direction = 0; //0=middle 1=bottom 2=top
  2610. this.FixedFontSize=-1; //固定字体大小
  2611. this.YOffset = 0;
  2612. this.Position; //指定输出位置
  2613. this.TextBG; //{ Color:"rgb(0,0,92)", Border:"rgb(205,0,92)", Margin:[0,1,1,1], } // { Color:背景色, Border:边框颜色, Margin=[上,下,左, 右] }
  2614. this.ShowOffset={ X:0, Y:0 }; //显示偏移
  2615. this.TextSize=
  2616. {
  2617. Max: g_JSChartResource.DRAWICON.Text.MaxSize, Min:g_JSChartResource.DRAWICON.Text.MinSize, //字体的最大最小值
  2618. Zoom:{ Type:g_JSChartResource.DRAWICON.Text.Zoom.Type , Value:g_JSChartResource.DRAWICON.Text.Zoom.Value }, //放大倍数
  2619. FontName:g_JSChartResource.DRAWICON.Text.FontName
  2620. }
  2621. this.ReloadResource=function(resource)
  2622. {
  2623. if (this.Name=="DRAWTEXT")
  2624. {
  2625. this.TextSize=
  2626. {
  2627. Max: g_JSChartResource.DRAWTEXT.MaxSize, Min:g_JSChartResource.DRAWTEXT.MinSize, //字体的最大最小值
  2628. Zoom:{ Type:g_JSChartResource.DRAWTEXT.Zoom.Type , Value:g_JSChartResource.DRAWTEXT.Zoom.Value }, //放大倍数
  2629. FontName:g_JSChartResource.DRAWTEXT.FontName
  2630. }
  2631. }
  2632. else if (this.Name=="DRAWNUMBER")
  2633. {
  2634. this.TextSize=
  2635. {
  2636. Max: g_JSChartResource.DRAWNUMBER.MaxSize, Min:g_JSChartResource.DRAWNUMBER.MinSize, //字体的最大最小值
  2637. Zoom:{ Type:g_JSChartResource.DRAWNUMBER.Zoom.Type , Value:g_JSChartResource.DRAWNUMBER.Zoom.Value }, //放大倍数
  2638. FontName:g_JSChartResource.DRAWNUMBER.FontName
  2639. }
  2640. }
  2641. }
  2642. this.Draw = function ()
  2643. {
  2644. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  2645. if (this.NotSupportMessage)
  2646. {
  2647. this.DrawNotSupportmessage();
  2648. return;
  2649. }
  2650. if (this.Name=="DRAWTEXTREL" || this.Name=="DRAWTEXTABS")
  2651. {
  2652. this.DrawRectText();
  2653. return;
  2654. }
  2655. if (this.Position)
  2656. {
  2657. this.DrawPosition();
  2658. return;
  2659. }
  2660. if (!this.Data || !this.Data.Data) return;
  2661. var isHScreen = (this.ChartFrame.IsHScreen === true)
  2662. var dataWidth = this.ChartFrame.DataWidth;
  2663. var distanceWidth = this.ChartFrame.DistanceWidth;
  2664. var chartright = this.ChartBorder.GetRight();
  2665. var top = this.ChartBorder.GetTopEx();
  2666. var bottom = this.ChartBorder.GetBottomEx();
  2667. if (isHScreen)
  2668. {
  2669. chartright = this.ChartBorder.GetBottom();
  2670. top = this.ChartBorder.GetRightEx();
  2671. bottom = this.ChartBorder.GetLeftEx();
  2672. }
  2673. var xPointCount = this.ChartFrame.XPointCount;
  2674. var isArrayText = Array.isArray(this.Text);
  2675. var text;
  2676. var drawTextInfo={ Text:{ }, Font:{ } };
  2677. //上下位置
  2678. if (this.Direction == 1)
  2679. {
  2680. this.Canvas.textBaseline = 'bottom';
  2681. drawTextInfo.Text={ Baseline: 'bottom'};
  2682. }
  2683. else if (this.Direction == 2)
  2684. {
  2685. this.Canvas.textBaseline = 'top';
  2686. drawTextInfo.Text={ Baseline: 'top'};
  2687. }
  2688. else
  2689. {
  2690. this.Canvas.textBaseline = 'middle';
  2691. drawTextInfo.Text={ Baseline: 'middle'};
  2692. }
  2693. //字体大小
  2694. if (this.FixedFontSize>0)
  2695. this.TextFont=`${this.FixedFontSize}px ${this.TextSize.FontName}`;
  2696. else
  2697. this.TextFont = this.GetDynamicFontEx(dataWidth,distanceWidth,this.TextSize.Max,this.TextSize.Min,this.TextSize.Zoom,this.TextSize.FontName);
  2698. drawTextInfo.Font={ Height:this.GetFontHeight(this.TextFont) };
  2699. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  2700. {
  2701. var value = this.Data.Data[i];
  2702. if (value == null) continue;
  2703. var x = this.ChartFrame.GetXFromIndex(j);
  2704. var y = this.ChartFrame.GetYFromData(value);
  2705. if (x > chartright) break;
  2706. y+=this.ShowOffset.Y;
  2707. x+=this.ShowOffset.X;
  2708. this.Canvas.textAlign = this.TextAlign;
  2709. this.Canvas.fillStyle = this.Color;
  2710. this.Canvas.font = this.TextFont;
  2711. drawTextInfo.Text.Color=this.Color;
  2712. drawTextInfo.Text.Align=this.TextAlign;
  2713. drawTextInfo.X=x;
  2714. drawTextInfo.Y=y;
  2715. if (this.YOffset > 0 && this.Direction > 0)
  2716. {
  2717. var yPrice = y;
  2718. this.Canvas.save();
  2719. this.Canvas.setLineDash([5, 10]);
  2720. this.Canvas.strokeStyle = this.Color;
  2721. this.Canvas.beginPath();
  2722. if (isHScreen)
  2723. {
  2724. if (this.Direction == 1)
  2725. {
  2726. y = top - this.YOffset;
  2727. yPrice += 5;
  2728. }
  2729. else
  2730. {
  2731. y = bottom + this.YOffset;
  2732. yPrice -= 5;
  2733. }
  2734. this.Canvas.moveTo(ToFixedPoint(yPrice), ToFixedPoint(x));
  2735. this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(x));
  2736. }
  2737. else
  2738. {
  2739. if (this.Direction == 1)
  2740. {
  2741. y = top + this.YOffset;
  2742. yPrice += 5;
  2743. }
  2744. else
  2745. {
  2746. y = bottom - this.YOffset;
  2747. yPrice -= 5;
  2748. }
  2749. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(yPrice));
  2750. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(y));
  2751. }
  2752. this.Canvas.stroke();
  2753. this.Canvas.restore();
  2754. }
  2755. if (isArrayText)
  2756. {
  2757. text = this.Text[i];
  2758. if (!text) continue;
  2759. if (isHScreen)
  2760. {
  2761. if (this.Name=='DRAWNUMBER')
  2762. {
  2763. if (this.Direction==1) y+=g_JSChartResource.DRAWABOVE.YOffset;
  2764. else if (this.Direction==2) y-=4;
  2765. }
  2766. }
  2767. else
  2768. {
  2769. if (this.Name=='DRAWNUMBER')
  2770. {
  2771. if (this.Direction==1) y-=g_JSChartResource.DRAWABOVE.YOffset;
  2772. else if (this.Direction==2) y+=4;
  2773. }
  2774. }
  2775. if (this.Name=="DRAWTEXT")
  2776. this.DrawTextV2(text,drawTextInfo,isHScreen);
  2777. else
  2778. this.DrawText(text, x, y, isHScreen);
  2779. }
  2780. else
  2781. {
  2782. if (this.Name=="DRAWTEXT")
  2783. {
  2784. this.DrawTextV2(this.Text,drawTextInfo,isHScreen);
  2785. }
  2786. else
  2787. {
  2788. this.DrawText(this.Text, x, y, isHScreen);
  2789. }
  2790. }
  2791. }
  2792. }
  2793. this.DrawPosition=function() //绘制在指定位置上
  2794. {
  2795. if (!this.Text) return;
  2796. var isHScreen=(this.ChartFrame.IsHScreen===true)
  2797. if (isHScreen)
  2798. {
  2799. var y=this.ChartBorder.GetRightEx()-this.ChartBorder.GetWidthEx()*this.Position.Y;
  2800. var x=this.ChartBorder.GetTop()+this.ChartBorder.GetHeight()*this.Position.X;
  2801. }
  2802. else
  2803. {
  2804. var x=this.ChartBorder.GetLeft()+this.ChartBorder.GetWidth()*this.Position.X;
  2805. var y=this.ChartBorder.GetTopEx()+this.ChartBorder.GetHeight()*this.Position.Y;
  2806. }
  2807. this.Canvas.fillStyle=this.Color;
  2808. //TYPE:0为左对齐,1为右对齐.
  2809. if (this.Position.Type==0) this.Canvas.textAlign='left';
  2810. else if (this.Position.Type==1) this.Canvas.textAlign='right';
  2811. else this.Canvas.textAlign='center';
  2812. if (this.Direction==1) this.Canvas.textBaseline='bottom';
  2813. else if (this.Direction==2) this.Canvas.textBaseline='top';
  2814. else this.Canvas.textBaseline='middle';
  2815. this.DrawText(this.Text,x,y,isHScreen);
  2816. }
  2817. this.DrawText = function (text, x, y, isHScreen)
  2818. {
  2819. if (isHScreen)
  2820. {
  2821. this.Canvas.save();
  2822. this.Canvas.translate(y, x);
  2823. this.Canvas.rotate(90 * Math.PI / 180);
  2824. this.Canvas.fillText(text, 0, 0);
  2825. this.Canvas.restore();
  2826. }
  2827. else
  2828. {
  2829. this.Canvas.fillText(text, x, y);
  2830. }
  2831. }
  2832. this.DrawTextV2=function(text, drawInfo, isHScreen)
  2833. {
  2834. var textWidth=this.Canvas.measureText(text).width;
  2835. if (isHScreen)
  2836. {
  2837. var x=drawInfo.Y;
  2838. var y=drawInfo.X;
  2839. if (drawInfo.Text.Align=="right") y=y-textWidth;
  2840. else if (drawInfo.Text.Align=="center") y=y-textWidth/2;
  2841. if (drawInfo.Text.Baseline=="top") x-=drawInfo.Font.Height;
  2842. else if (drawInfo.Text.Baseline=="middle") x-=drawInfo.Font.Height/2;
  2843. if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
  2844. {
  2845. var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
  2846. var xRect=x-margin[0];
  2847. var yRect=y-margin[2];
  2848. var bgWidth=textWidth+margin[2]+margin[3];
  2849. var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
  2850. if (this.TextBG.Color)
  2851. {
  2852. this.Canvas.fillStyle=this.TextBG.Color;
  2853. this.Canvas.fillRect(xRect,yRect,bgHeight,bgWidth);
  2854. }
  2855. if (this.TextBG.Border)
  2856. {
  2857. this.Canvas.strokeStyle=this.TextBG.Border;
  2858. this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgHeight),ToFixedRect(bgWidth));
  2859. }
  2860. }
  2861. this.Canvas.textBaseline="bottom";
  2862. this.Canvas.textAlign="left";
  2863. this.Canvas.fillStyle=drawInfo.Text.Color;
  2864. this.Canvas.save();
  2865. this.Canvas.translate(x, y);
  2866. this.Canvas.rotate(90 * Math.PI / 180);
  2867. this.Canvas.fillText(text,0,0);
  2868. this.Canvas.restore();
  2869. }
  2870. else
  2871. {
  2872. var x=drawInfo.X;
  2873. var y=drawInfo.Y;
  2874. if (drawInfo.Text.Align=="right") x=x-textWidth;
  2875. else if (drawInfo.Text.Align=="center") x=x-textWidth/2;
  2876. if (drawInfo.Text.Baseline=="top") y+=drawInfo.Font.Height;
  2877. else if (drawInfo.Text.Baseline=="middle") y+=drawInfo.Font.Height/2;
  2878. if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
  2879. {
  2880. var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
  2881. var xRect=x-margin[2];
  2882. var yRect=y-drawInfo.Font.Height-margin[1];
  2883. var bgWidth=textWidth+margin[2]+margin[3];
  2884. var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
  2885. if (this.TextBG.Color)
  2886. {
  2887. this.Canvas.fillStyle=this.TextBG.Color;
  2888. this.Canvas.fillRect(xRect,yRect,bgWidth,bgHeight);
  2889. }
  2890. if (this.TextBG.Border)
  2891. {
  2892. this.Canvas.strokeStyle=this.TextBG.Border;
  2893. this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgWidth),ToFixedRect(bgHeight));
  2894. }
  2895. }
  2896. this.Canvas.textBaseline="bottom";
  2897. this.Canvas.textAlign="left";
  2898. this.Canvas.fillStyle=drawInfo.Text.Color;
  2899. this.Canvas.fillText(text,x,y);
  2900. }
  2901. }
  2902. this.DrawRectText=function()
  2903. {
  2904. if (!this.DrawData) return;
  2905. var isHScreen=(this.ChartFrame.IsHScreen===true)
  2906. var border=this.ChartFrame.GetBorder();
  2907. if (this.Name=="DRAWTEXTREL")
  2908. {
  2909. if (isHScreen)
  2910. {
  2911. var height=border.RightTitle-border.LeftEx;
  2912. var width=border.BottomEx-border.TopEx;
  2913. var x=this.DrawData.Point.X/1000*width+border.TopEx;
  2914. var y=border.RightTitle-this.DrawData.Point.Y/1000*width;
  2915. }
  2916. else
  2917. {
  2918. var width=border.RightEx-border.LeftEx;
  2919. var height=border.BottomEx-border.TopTitle;
  2920. var x=this.DrawData.Point.X/1000*width+border.LeftEx;
  2921. var y=this.DrawData.Point.Y/1000*height+border.TopTitle;
  2922. }
  2923. }
  2924. else if (this.Name=="DRAWTEXTABS")
  2925. {
  2926. if (isHScreen)
  2927. {
  2928. var x=this.DrawData.Point.X+border.TopEx;
  2929. var y=border.RightTitle-this.DrawData.Point.Y;
  2930. }
  2931. else
  2932. {
  2933. var x=this.DrawData.Point.X+border.LeftEx;
  2934. var y=this.DrawData.Point.Y+border.TopTitle;
  2935. }
  2936. }
  2937. else
  2938. {
  2939. return;
  2940. }
  2941. if (this.Direction==1) this.Canvas.textBaseline='bottom';
  2942. else if (this.Direction==2) this.Canvas.textBaseline='top';
  2943. else this.Canvas.textBaseline='middle';
  2944. this.Canvas.textAlign='left';
  2945. this.Canvas.font=this.TextFont;
  2946. this.Canvas.fillStyle=this.Color;
  2947. this.DrawText(this.DrawData.Text,x,y,isHScreen);
  2948. }
  2949. this.SuperGetMaxMin=this.GetMaxMin;
  2950. this.GetMaxMin=function()
  2951. {
  2952. if (this.Name=="DRAWTEXTREL" || this.Name=="DRAWTEXTABS")
  2953. {
  2954. return { Min:null,Max:null };
  2955. }
  2956. else
  2957. {
  2958. return this.SuperGetMaxMin();
  2959. }
  2960. }
  2961. }
  2962. function ChartDrawText()
  2963. {
  2964. this.newMethod=IChartPainting; //派生
  2965. this.newMethod();
  2966. delete this.newMethod;
  2967. this.ClassName='ChartDrawText'; //类名
  2968. this.Color = "rgb(255,193,37)"; //线段颜色
  2969. this.TextFont = "14px 微软雅黑"; //字体
  2970. this.Text;
  2971. this.TextAlign = 'left';
  2972. this.TextBaseline="middle";
  2973. this.FixedFontSize=-1; //固定字体大小
  2974. this.YOffset = 0;
  2975. this.FixedPosition=-1; //固定位置输出 1顶部, 2底部
  2976. this.TextBG; //{ Color:"rgb(0,0,92)", Border:"rgb(205,0,92)", Margin:[0,1,1,1], } // { Color:背景色, Border:边框颜色, Margin=[上,下,左, 右] }
  2977. this.VerticalLine; //垂直线
  2978. this.ShowOffset={ X:0, Y:0 }; //显示偏移
  2979. this.TextSize=
  2980. {
  2981. Max: g_JSChartResource.DRAWICON.Text.MaxSize, Min:g_JSChartResource.DRAWICON.Text.MinSize, //字体的最大最小值
  2982. Zoom:{ Type:g_JSChartResource.DRAWICON.Text.Zoom.Type , Value:g_JSChartResource.DRAWICON.Text.Zoom.Value }, //放大倍数
  2983. FontName:g_JSChartResource.DRAWICON.Text.FontName
  2984. }
  2985. this.ReloadResource=function(resource)
  2986. {
  2987. this.TextSize=
  2988. {
  2989. Max: g_JSChartResource.DRAWTEXT.MaxSize, Min:g_JSChartResource.DRAWTEXT.MinSize, //字体的最大最小值
  2990. Zoom:{ Type:g_JSChartResource.DRAWTEXT.Zoom.Type , Value:g_JSChartResource.DRAWTEXT.Zoom.Value }, //放大倍数
  2991. FontName:g_JSChartResource.DRAWTEXT.FontName
  2992. }
  2993. }
  2994. this.Draw = function ()
  2995. {
  2996. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  2997. if (this.NotSupportMessage)
  2998. {
  2999. this.DrawNotSupportmessage();
  3000. return;
  3001. }
  3002. if (!this.Data || !this.Data.Data) return;
  3003. var isHScreen = (this.ChartFrame.IsHScreen === true)
  3004. var dataWidth = this.ChartFrame.DataWidth;
  3005. var distanceWidth = this.ChartFrame.DistanceWidth;
  3006. var chartright = this.ChartBorder.GetRight();
  3007. var top = this.ChartBorder.GetTopEx();
  3008. var bottom = this.ChartBorder.GetBottomEx();
  3009. if (isHScreen)
  3010. {
  3011. chartright = this.ChartBorder.GetBottom();
  3012. top = this.ChartBorder.GetRightEx();
  3013. bottom = this.ChartBorder.GetLeftEx();
  3014. }
  3015. var xPointCount = this.ChartFrame.XPointCount;
  3016. var isArrayText = Array.isArray(this.Text);
  3017. var text;
  3018. var drawTextInfo={ Text:{ Color:this.Color, Align:this.TextAlign, Baseline:this.TextBaseline }, Font:{ } };
  3019. //字体大小
  3020. if (this.FixedFontSize>0)
  3021. this.TextFont=`${this.FixedFontSize}px ${this.TextSize.FontName}`;
  3022. else
  3023. this.TextFont = this.GetDynamicFontEx(dataWidth,distanceWidth,this.TextSize.Max,this.TextSize.Min,this.TextSize.Zoom,this.TextSize.FontName);
  3024. drawTextInfo.Font={ Height:this.GetFontHeight(this.TextFont) };
  3025. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3026. {
  3027. var value = this.Data.Data[i];
  3028. if (value == null) continue;
  3029. var x = this.ChartFrame.GetXFromIndex(j);
  3030. var y;
  3031. if (this.FixedPosition===1) y=top;
  3032. else if (this.FixedPosition===2) y=bottom;
  3033. else y=this.ChartFrame.GetYFromData(value);
  3034. if (x > chartright) break;
  3035. y+=this.ShowOffset.Y;
  3036. x+=this.ShowOffset.X;
  3037. drawTextInfo.X=x;
  3038. drawTextInfo.Y=y;
  3039. if (isArrayText)
  3040. {
  3041. text = this.Text[i];
  3042. if (!text) continue;
  3043. this.DrawText(text,drawTextInfo,isHScreen);
  3044. }
  3045. else
  3046. {
  3047. this.DrawText(this.Text,drawTextInfo,isHScreen);
  3048. }
  3049. this.DrawVerticalLine(i, drawTextInfo, isHScreen);
  3050. }
  3051. }
  3052. this.DrawText=function(text, drawInfo, isHScreen)
  3053. {
  3054. var textWidth=this.Canvas.measureText(text).width;
  3055. if (isHScreen)
  3056. {
  3057. var x=drawInfo.Y;
  3058. var y=drawInfo.X;
  3059. if (drawInfo.Text.Align=="right") y=y-textWidth;
  3060. else if (drawInfo.Text.Align=="center") y=y-textWidth/2;
  3061. if (drawInfo.Text.Baseline=="top") x-=drawInfo.Font.Height;
  3062. else if (drawInfo.Text.Baseline=="middle") x-=drawInfo.Font.Height/2;
  3063. if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
  3064. {
  3065. var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
  3066. var xRect=x-margin[0];
  3067. var yRect=y-margin[2];
  3068. var bgWidth=textWidth+margin[2]+margin[3];
  3069. var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
  3070. if (this.TextBG.Color)
  3071. {
  3072. this.Canvas.fillStyle=this.TextBG.Color;
  3073. this.Canvas.fillRect(xRect,yRect,bgHeight,bgWidth);
  3074. }
  3075. if (this.TextBG.Border)
  3076. {
  3077. this.Canvas.strokeStyle=this.TextBG.Border;
  3078. this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgHeight),ToFixedRect(bgWidth));
  3079. }
  3080. drawInfo.Rect={Bottom:xRect, Top:xRect+bgHeight };
  3081. }
  3082. else
  3083. {
  3084. var xRect=x;
  3085. var bgHeight=drawInfo.Font.Height;
  3086. drawInfo.Rect={Bottom:xRect, Top:xRect+bgHeight };
  3087. }
  3088. this.Canvas.textBaseline="bottom";
  3089. this.Canvas.textAlign="left";
  3090. this.Canvas.fillStyle=drawInfo.Text.Color;
  3091. this.Canvas.save();
  3092. this.Canvas.translate(x, y);
  3093. this.Canvas.rotate(90 * Math.PI / 180);
  3094. this.Canvas.fillText(text,0,0);
  3095. this.Canvas.restore();
  3096. }
  3097. else
  3098. {
  3099. var x=drawInfo.X;
  3100. var y=drawInfo.Y;
  3101. if (drawInfo.Text.Align=="right") x=x-textWidth;
  3102. else if (drawInfo.Text.Align=="center") x=x-textWidth/2;
  3103. if (drawInfo.Text.Baseline=="top") y+=drawInfo.Font.Height;
  3104. else if (drawInfo.Text.Baseline=="middle") y+=drawInfo.Font.Height/2;
  3105. if (this.TextBG && (this.TextBG.Color || this.TextBG.Border))
  3106. {
  3107. var margin=this.TextBG.Margin; //0=上 1=下 2=左 3=右
  3108. var xRect=x-margin[2];
  3109. var yRect=y-drawInfo.Font.Height-margin[1];
  3110. var bgWidth=textWidth+margin[2]+margin[3];
  3111. var bgHeight=drawInfo.Font.Height+margin[0]+margin[1];
  3112. if (this.TextBG.Color)
  3113. {
  3114. this.Canvas.fillStyle=this.TextBG.Color;
  3115. this.Canvas.fillRect(xRect,yRect,bgWidth,bgHeight);
  3116. }
  3117. if (this.TextBG.Border)
  3118. {
  3119. this.Canvas.strokeStyle=this.TextBG.Border;
  3120. this.Canvas.strokeRect(ToFixedPoint(xRect),ToFixedPoint(yRect),ToFixedRect(bgWidth),ToFixedRect(bgHeight));
  3121. }
  3122. drawInfo.Rect={Top:yRect, Bottom:yRect+bgHeight };
  3123. }
  3124. else
  3125. {
  3126. var yRect=y-drawInfo.Font.Height;
  3127. var bgHeight=drawInfo.Font.Height;
  3128. drawInfo.Rect={Top:yRect, Bottom:yRect+bgHeight };
  3129. }
  3130. this.Canvas.textBaseline="bottom";
  3131. this.Canvas.textAlign="left";
  3132. this.Canvas.fillStyle=drawInfo.Text.Color;
  3133. this.Canvas.fillText(text,x,y);
  3134. }
  3135. }
  3136. //画连线
  3137. this.DrawVerticalLine=function(index, drawTextInfo, isHScreen)
  3138. {
  3139. if (!this.VerticalLine) return;
  3140. var item=this.VerticalLine.Data[index];
  3141. if (!item) return;
  3142. if (!IFrameSplitOperator.IsNumber(item.High)) return;
  3143. if (!IFrameSplitOperator.IsNumber(item.Low)) return;
  3144. var yHigh=this.ChartFrame.GetYFromData(item.High);
  3145. var yLow=this.ChartFrame.GetYFromData(item.Low);
  3146. var yLine, yLine2;
  3147. if (isHScreen)
  3148. {
  3149. if (drawTextInfo.Rect.Bottom>yHigh)
  3150. {
  3151. yLine=drawTextInfo.Rect.Bottom-1;
  3152. yLine2=yHigh+1;
  3153. }
  3154. else if (drawTextInfo.Rect.Top<yLow)
  3155. {
  3156. yLine=drawTextInfo.Rect.Top-1;
  3157. yLine2=yLow-1;
  3158. }
  3159. else
  3160. {
  3161. return;
  3162. }
  3163. }
  3164. else
  3165. {
  3166. if (drawTextInfo.Rect.Bottom<yHigh)
  3167. {
  3168. yLine=drawTextInfo.Rect.Bottom+1;
  3169. yLine2=yHigh-1;
  3170. }
  3171. else if (drawTextInfo.Rect.Top>yLow)
  3172. {
  3173. yLine=drawTextInfo.Rect.Top-1;
  3174. yLine2=yLow+1;
  3175. }
  3176. else
  3177. {
  3178. return;
  3179. }
  3180. }
  3181. this.Canvas.save();
  3182. var pixelTatio =1;
  3183. var xLine=drawTextInfo.X;
  3184. if (this.VerticalLine.LineType==1)
  3185. {
  3186. if (this.VerticalLine.LineDotted)
  3187. this.Canvas.setLineDash(this.VerticalLine.LineDotted);
  3188. else
  3189. this.Canvas.setLineDash([3,3]);
  3190. }
  3191. if (IFrameSplitOperator.IsPlusNumber(this.VerticalLine.LineWidth))
  3192. {
  3193. this.Canvas.lineWidth=this.VerticalLine.LineWidth*pixelTatio;
  3194. }
  3195. this.Canvas.strokeStyle=this.VerticalLine.Color;
  3196. this.Canvas.beginPath();
  3197. if (isHScreen)
  3198. {
  3199. this.Canvas.moveTo(ToFixedPoint(yLine),ToFixedPoint(xLine));
  3200. this.Canvas.lineTo(ToFixedPoint(yLine2),ToFixedPoint(xLine));
  3201. }
  3202. else
  3203. {
  3204. this.Canvas.moveTo(ToFixedPoint(xLine),ToFixedPoint(yLine));
  3205. this.Canvas.lineTo(ToFixedPoint(xLine),ToFixedPoint(yLine2));
  3206. }
  3207. this.Canvas.stroke();
  3208. this.Canvas.restore();
  3209. }
  3210. }
  3211. function ChartDrawNumber()
  3212. {
  3213. this.newMethod=ChartDrawText; //派生
  3214. this.newMethod();
  3215. delete this.newMethod;
  3216. this.ClassName='ChartDrawNumber'; //类名
  3217. this.ReloadResource=function(resource)
  3218. {
  3219. this.TextSize=
  3220. {
  3221. Max: g_JSChartResource.DRAWNUMBER.MaxSize, Min:g_JSChartResource.DRAWNUMBER.MinSize, //字体的最大最小值
  3222. Zoom:{ Type:g_JSChartResource.DRAWNUMBER.Zoom.Type , Value:g_JSChartResource.DRAWNUMBER.Zoom.Value }, //放大倍数
  3223. FontName:g_JSChartResource.DRAWNUMBER.FontName
  3224. }
  3225. }
  3226. }
  3227. //线段
  3228. function ChartLine()
  3229. {
  3230. this.newMethod = IChartPainting; //派生
  3231. this.newMethod();
  3232. delete this.newMethod;
  3233. this.ClassName ='ChartLine';
  3234. this.Color = "rgb(255,193,37)"; //线段颜色
  3235. this.LineWidth; //线段宽度
  3236. this.DrawType = 0; //画图方式 0=无效数平滑 1=无效数不画断开
  3237. this.IsDotLine = false; //虚线
  3238. this.LineDash=g_JSChartResource.DOTLINE.LineDash;
  3239. this.Draw = function ()
  3240. {
  3241. if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
  3242. if (this.IsHideScriptIndex()) return;
  3243. if (this.NotSupportMessage)
  3244. {
  3245. this.DrawNotSupportmessage();
  3246. return;
  3247. }
  3248. if (!this.Data || !this.Data.Data) return;
  3249. switch (this.DrawType)
  3250. {
  3251. case 0:
  3252. return this.DrawLine();
  3253. case 1:
  3254. return this.DrawStraightLine();
  3255. }
  3256. }
  3257. this.DrawLine = function ()
  3258. {
  3259. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3260. var dataWidth = this.ChartFrame.DataWidth;
  3261. var distanceWidth = this.ChartFrame.DistanceWidth;
  3262. var chartright = this.ChartBorder.GetRight();
  3263. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  3264. var xPointCount = this.ChartFrame.XPointCount;
  3265. this.Canvas.save();
  3266. if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
  3267. var bFirstPoint = true;
  3268. var drawCount = 0;
  3269. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3270. {
  3271. var value = this.Data.Data[i];
  3272. if (value == null) continue;
  3273. var x = this.ChartFrame.GetXFromIndex(j);
  3274. var y = this.GetYFromData(value);
  3275. if (x > chartright) break;
  3276. if (bFirstPoint)
  3277. {
  3278. this.Canvas.strokeStyle = this.Color;
  3279. this.Canvas.beginPath();
  3280. if (bHScreen) this.Canvas.moveTo(y, x); //横屏坐标轴对调
  3281. else this.Canvas.moveTo(x, y);
  3282. bFirstPoint = false;
  3283. }
  3284. else
  3285. {
  3286. if (bHScreen) this.Canvas.lineTo(y, x);
  3287. else this.Canvas.lineTo(x, y);
  3288. }
  3289. ++drawCount;
  3290. }
  3291. if (drawCount > 0) this.Canvas.stroke();
  3292. this.Canvas.restore();
  3293. }
  3294. //无效数不画
  3295. this.DrawStraightLine = function ()
  3296. {
  3297. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3298. var isMinute=this.IsMinuteFrame();
  3299. var dataWidth = this.ChartFrame.DataWidth;
  3300. var distanceWidth = this.ChartFrame.DistanceWidth;
  3301. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  3302. var chartright = this.ChartBorder.GetRight();
  3303. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  3304. if (bHScreen) xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  3305. var xPointCount = this.ChartFrame.XPointCount;
  3306. this.Canvas.save();
  3307. if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
  3308. this.Canvas.strokeStyle = this.Color;
  3309. if (this.IsDotLine) this.Canvas.setLineDash(this.LineDash); //画虚线
  3310. var bFirstPoint = true;
  3311. var drawCount = 0;
  3312. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  3313. //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3314. {
  3315. var value = this.Data.Data[i];
  3316. if (value == null)
  3317. {
  3318. if (drawCount > 0) this.Canvas.stroke();
  3319. bFirstPoint = true;
  3320. drawCount = 0;
  3321. continue;
  3322. }
  3323. if (isMinute)
  3324. {
  3325. var x = this.ChartFrame.GetXFromIndex(j);
  3326. }
  3327. else
  3328. {
  3329. var left=xOffset;
  3330. var right=xOffset+dataWidth;
  3331. if (right>chartright) break;
  3332. var x=left+(right-left)/2;
  3333. }
  3334. var y = this.GetYFromData(value);
  3335. if (x > chartright) break;
  3336. if (bFirstPoint)
  3337. {
  3338. this.Canvas.beginPath();
  3339. if (bHScreen) this.Canvas.moveTo(y, x); //横屏坐标轴对调
  3340. else this.Canvas.moveTo(x, y);
  3341. bFirstPoint = false;
  3342. }
  3343. else
  3344. {
  3345. if (bHScreen) this.Canvas.lineTo(y, x);
  3346. else this.Canvas.lineTo(x, y);
  3347. }
  3348. ++drawCount;
  3349. }
  3350. if (drawCount > 0) this.Canvas.stroke();
  3351. this.Canvas.restore();
  3352. }
  3353. this.GetYFromData = function (value)
  3354. {
  3355. return this.ChartFrame.GetYFromData(value);
  3356. }
  3357. }
  3358. //独立线段
  3359. //独立线段
  3360. function ChartSingleLine()
  3361. {
  3362. this.newMethod=ChartLine; //派生
  3363. this.newMethod();
  3364. delete this.newMethod;
  3365. this.ClassName='ChartSingleLine'; //类名
  3366. this.MaxMin=null; //当前的显示范围
  3367. this.Draw=function()
  3368. {
  3369. this.MaxMin=null;
  3370. if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
  3371. if (this.IsHideScriptIndex()) return;
  3372. if (!this.Data || !this.Data.Data) return;
  3373. this.MaxMin=this.GetCurrentMaxMin();
  3374. if (!this.MaxMin) return;
  3375. if (!IFrameSplitOperator.IsNumber(this.MaxMin.Max) || !IFrameSplitOperator.IsNumber(this.MaxMin.Min)) return;
  3376. switch(this.DrawType)
  3377. {
  3378. default:
  3379. return this.DrawStraightLine();
  3380. }
  3381. }
  3382. //获取当前页的最大最小值
  3383. this.GetCurrentMaxMin=function()
  3384. {
  3385. var xPointCount=this.ChartFrame.XPointCount;
  3386. var range={ Max:null, Min:null };
  3387. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
  3388. {
  3389. var value=this.Data.Data[i];
  3390. if (!IFrameSplitOperator.IsNumber(value)) continue;
  3391. if (range.Max==null) range.Max=value;
  3392. if (range.Min==null) range.Min=value;
  3393. if (range.Max<value) range.Max=value;
  3394. if (range.Min>value) range.Min=value;
  3395. }
  3396. return range;
  3397. }
  3398. this.GetMaxMin=function()
  3399. {
  3400. return { Max:null, Min:null };
  3401. }
  3402. this.GetYFromData=function(value)
  3403. {
  3404. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3405. if (bHScreen)
  3406. {
  3407. if (value <= this.MaxMin.Min) return this.ChartBorder.GetLeftEx();
  3408. if (value >= this.MaxMin.Max) return this.ChartBorder.GetRightEx();
  3409. var width = this.ChartBorder.GetWidthEx() * (value - this.MaxMin.Min) / (this.MaxMin.Max - this.MaxMin.Min);
  3410. return this.ChartBorder.GetLeftEx() + width;
  3411. }
  3412. else
  3413. {
  3414. if(value<=this.MaxMin.Min) return this.ChartBorder.GetBottomEx();
  3415. if(value>=this.MaxMin.Max) return this.ChartBorder.GetTopEx();
  3416. var height=this.ChartBorder.GetHeightEx()*(value-this.MaxMin.Min)/(this.MaxMin.Max-this.MaxMin.Min);
  3417. return this.ChartBorder.GetBottomEx()-height;
  3418. }
  3419. }
  3420. }
  3421. //面积图 支持横屏
  3422. function ChartArea()
  3423. {
  3424. this.newMethod=IChartPainting; //派生
  3425. this.newMethod();
  3426. delete this.newMethod;
  3427. this.ClassName='ChartArea'; //类名
  3428. this.Color="rgb(255,193,37)"; //线段颜色
  3429. this.AreaColor; //面积颜色
  3430. this.LineWidth; //线段宽度
  3431. this.LineDash; //虚线
  3432. this.AreaDirection=0 //0=向下 1=向上
  3433. this.DrawSelectedStatus=this.DrawLinePoint;
  3434. this.PtInChart=this.PtInLine;
  3435. this.ExportData=this.ExportArrayData;
  3436. this.GetItemData=this.GetArrayItemData;
  3437. this.Draw=function()
  3438. {
  3439. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  3440. if (this.NotSupportMessage)
  3441. {
  3442. this.DrawNotSupportmessage();
  3443. return;
  3444. }
  3445. if (!this.Data || !this.Data.Data) return;
  3446. this.DrawArea();
  3447. }
  3448. //无效数不画
  3449. this.DrawArea=function()
  3450. {
  3451. var bHScreen=(this.ChartFrame.IsHScreen===true);
  3452. var isMinute=this.IsMinuteFrame();
  3453. var dataWidth=this.ChartFrame.DataWidth;
  3454. var distanceWidth=this.ChartFrame.DistanceWidth;
  3455. var xPointCount=this.ChartFrame.XPointCount;
  3456. if (bHScreen)
  3457. {
  3458. var border=this.ChartBorder.GetHScreenBorder();
  3459. var chartright=border.BottomEx;
  3460. var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  3461. }
  3462. else
  3463. {
  3464. var border=this.ChartBorder.GetBorder();
  3465. var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  3466. var chartright=border.RightEx;
  3467. }
  3468. var lockRect=this.GetLockRect();
  3469. if (lockRect)
  3470. {
  3471. if (bHScreen) chartright=lockRect.Top;
  3472. else chartright=lockRect.Left;
  3473. }
  3474. this.Canvas.save();
  3475. if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
  3476. this.Canvas.strokeStyle=this.Color;
  3477. if (this.AreaColor) this.Canvas.fillStyle=this.AreaColor;
  3478. else this.Canvas.fillStyle=ColorToRGBA(this.Color,0.6);
  3479. if (IFrameSplitOperator.IsNonEmptyArray(this.LineDash)) this.Canvas.setLineDash(this.LineDas); //画虚线
  3480. var bFirstPoint=true;
  3481. var ptFirst=null, ptEnd=null //起始结束点
  3482. var drawCount=0;
  3483. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  3484. {
  3485. var value=this.Data.Data[i];
  3486. if (!IFrameSplitOperator.IsNumber(value))
  3487. {
  3488. if (drawCount>0) this.Canvas.stroke();
  3489. if (ptFirst && ptEnd)
  3490. {
  3491. if (bHScreen)
  3492. {
  3493. if (this.AreaDirection==1)
  3494. {
  3495. this.Canvas.lineTo(border.RightEx,ptEnd.X);
  3496. this.Canvas.lineTo(border.RightEx,ptFirst.X);
  3497. }
  3498. else
  3499. {
  3500. this.Canvas.lineTo(border.LeftEx,ptEnd.X);
  3501. this.Canvas.lineTo(border.LeftEx,ptFirst.X);
  3502. }
  3503. this.Canvas.closePath();
  3504. this.Canvas.fill();
  3505. }
  3506. else
  3507. {
  3508. if (this.AreaDirection==1)
  3509. {
  3510. this.Canvas.lineTo(ptEnd.X, border.TopEx);
  3511. this.Canvas.lineTo(ptFirst.X, border.TopEx);
  3512. }
  3513. else
  3514. {
  3515. this.Canvas.lineTo(ptEnd.X, border.BottomEx);
  3516. this.Canvas.lineTo(ptFirst.X, border.BottomEx);
  3517. }
  3518. this.Canvas.closePath();
  3519. this.Canvas.fill();
  3520. }
  3521. }
  3522. bFirstPoint=true;
  3523. drawCount=0;
  3524. ptFirst=null;
  3525. ptEnd=null;
  3526. continue;
  3527. }
  3528. if (isMinute)
  3529. {
  3530. var x=this.ChartFrame.GetXFromIndex(j);
  3531. }
  3532. else
  3533. {
  3534. var left=xOffset;
  3535. var right=xOffset+dataWidth;
  3536. if (right>chartright) break;
  3537. var x=left+(right-left)/2;
  3538. }
  3539. var y=this.GetYFromData(value,false);
  3540. if (x>chartright) break;
  3541. if (bFirstPoint)
  3542. {
  3543. this.Canvas.beginPath();
  3544. if (bHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
  3545. else this.Canvas.moveTo(x,y);
  3546. bFirstPoint=false;
  3547. ptFirst={ X:x, Y:y };
  3548. }
  3549. else
  3550. {
  3551. if (bHScreen) this.Canvas.lineTo(y,x);
  3552. else this.Canvas.lineTo(x,y);
  3553. ptEnd={ X:x, Y:y };
  3554. }
  3555. ++drawCount;
  3556. }
  3557. if (drawCount>0)
  3558. {
  3559. if (drawCount==1 && ptFirst) //如果只有1个点, 画一个像素的横线
  3560. {
  3561. if (bHScreen) this.Canvas.lineTo(ptFirst.Y,ptFirst.X+1*GetDevicePixelRatio());
  3562. else this.Canvas.lineTo(ptFirst.X+1*GetDevicePixelRatio(),ptFirst.Y);
  3563. }
  3564. this.Canvas.stroke();
  3565. if (ptFirst && ptEnd)
  3566. {
  3567. if (bHScreen)
  3568. {
  3569. if (this.AreaDirection==1)
  3570. {
  3571. this.Canvas.lineTo(border.RightEx,ptEnd.X);
  3572. this.Canvas.lineTo(border.RightEx,ptFirst.X);
  3573. }
  3574. else
  3575. {
  3576. this.Canvas.lineTo(border.LeftEx,ptEnd.X);
  3577. this.Canvas.lineTo(border.LeftEx,ptFirst.X);
  3578. }
  3579. this.Canvas.closePath();
  3580. this.Canvas.fill();
  3581. }
  3582. else
  3583. {
  3584. if (this.AreaDirection==1)
  3585. {
  3586. this.Canvas.lineTo(ptEnd.X, border.TopEx);
  3587. this.Canvas.lineTo(ptFirst.X, border.TopEx);
  3588. }
  3589. else
  3590. {
  3591. this.Canvas.lineTo(ptEnd.X, border.BottomEx);
  3592. this.Canvas.lineTo(ptFirst.X, border.BottomEx);
  3593. }
  3594. this.Canvas.closePath();
  3595. this.Canvas.fill();
  3596. }
  3597. }
  3598. }
  3599. this.Canvas.restore();
  3600. }
  3601. }
  3602. //子线段
  3603. function ChartSubLine()
  3604. {
  3605. this.newMethod = ChartLine; //派生
  3606. this.newMethod();
  3607. delete this.newMethod;
  3608. this.ClassName = 'ChartSubLine'; //类名
  3609. this.Color = "rgb(255,193,37)"; //线段颜色
  3610. this.LineWidth; //线段宽度
  3611. this.DrawType = 0; //画图方式 0=无效数平滑 1=无效数不画断开
  3612. this.IsDotLine = false; //虚线
  3613. this.SubFrame = { Max: null, Min: null };
  3614. this.Draw = function ()
  3615. {
  3616. if (!this.IsShow) return;
  3617. if (!this.Data || !this.Data.Data) return;
  3618. this.CalculateDataMaxMin();
  3619. switch (this.DrawType)
  3620. {
  3621. case 0:
  3622. return this.DrawLine();
  3623. case 1:
  3624. return this.DrawStraightLine();
  3625. }
  3626. }
  3627. this.GetYFromData = function (value)
  3628. {
  3629. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3630. if (bHScreen)
  3631. {
  3632. if (value <= this.SubFrame.Min) return this.ChartBorder.GetLeftEx();
  3633. if (value >= this.SubFrame.Max) return this.ChartBorder.GetRightEx();
  3634. var width = this.ChartBorder.GetWidthEx() * (value - this.SubFrame.Min) / (this.SubFrame.Max - this.SubFrame.Min);
  3635. return this.ChartBorder.GetLeftEx() + width;
  3636. }
  3637. else
  3638. {
  3639. if (value <= this.SubFrame.Min) return this.ChartBorder.GetBottomEx();
  3640. if (value >= this.SubFrame.Max) return this.ChartBorder.GetTopEx();
  3641. var height = this.ChartBorder.GetHeightEx() * (value - this.SubFrame.Min) / (this.SubFrame.Max - this.SubFrame.Min);
  3642. return this.ChartBorder.GetBottomEx() - height;
  3643. }
  3644. }
  3645. this.CalculateDataMaxMin = function ()
  3646. {
  3647. this.SubFrame = { Max: null, Min: null };
  3648. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3649. var chartright = this.ChartBorder.GetRight();
  3650. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  3651. var xPointCount = this.ChartFrame.XPointCount;
  3652. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3653. {
  3654. var value = this.Data.Data[i];
  3655. if (value == null) continue;
  3656. var x = this.ChartFrame.GetXFromIndex(j);
  3657. if (x > chartright) break;
  3658. if (this.SubFrame.Min == null || this.SubFrame.Min > value) this.SubFrame.Min = value;
  3659. if (this.SubFrame.Max == null || this.SubFrame.Max < value) this.SubFrame.Max = value;
  3660. }
  3661. }
  3662. this.GetMaxMin = function () //数据不参与坐标轴最大最小值计算
  3663. {
  3664. var range = { Min: null, Max: null };
  3665. return range;
  3666. }
  3667. }
  3668. //POINTDOT 圆点 支持横屏
  3669. function ChartPointDot()
  3670. {
  3671. this.newMethod = IChartPainting; //派生
  3672. this.newMethod();
  3673. delete this.newMethod;
  3674. this.Color = "rgb(255,193,37)"; //线段颜色
  3675. this.Radius = 1; //点半径
  3676. this.ClassName = 'ChartPointDot';
  3677. this.EnableUpDownColor=false; //是否是红绿点
  3678. this.HistoryData;
  3679. this.Draw = function ()
  3680. {
  3681. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  3682. if (this.NotSupportMessage)
  3683. {
  3684. this.DrawNotSupportmessage();
  3685. return;
  3686. }
  3687. if (!this.Data || !this.Data.Data) return;
  3688. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3689. var dataWidth = this.ChartFrame.DataWidth;
  3690. var distanceWidth = this.ChartFrame.DistanceWidth;
  3691. var chartright = this.ChartBorder.GetRight();
  3692. if (bHScreen === true) chartright = this.ChartBorder.GetBottom();
  3693. var xPointCount = this.ChartFrame.XPointCount;
  3694. this.Canvas.save();
  3695. this.Canvas.fillStyle = this.Color;
  3696. var colorDot;
  3697. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3698. {
  3699. var value = this.Data.Data[i];
  3700. if (value == null) continue;
  3701. var x = this.ChartFrame.GetXFromIndex(j);
  3702. var y = this.ChartFrame.GetYFromData(value);
  3703. if (x > chartright) break;
  3704. if (this.EnableUpDownColor)
  3705. {
  3706. var kItem=this.HistoryData.Data[i];
  3707. if (kItem.Close>value) colorDot="rgb(255,61,61)";
  3708. else colorDot='rgb(0,199,65)';
  3709. this.Canvas.fillStyle=colorDot;
  3710. }
  3711. this.Canvas.beginPath();
  3712. if (bHScreen) this.Canvas.arc(y, x, this.Radius, 0, Math.PI * 2, true);
  3713. else this.Canvas.arc(x, y, this.Radius, 0, Math.PI * 2, true);
  3714. this.Canvas.closePath();
  3715. this.Canvas.fill();
  3716. }
  3717. this.Canvas.restore();
  3718. }
  3719. }
  3720. //通达信语法 STICK 支持横屏
  3721. function ChartStick()
  3722. {
  3723. this.newMethod = IChartPainting; //派生
  3724. this.newMethod();
  3725. delete this.newMethod;
  3726. this.Color = "rgb(255,193,37)"; //线段颜色
  3727. this.LineWidth; //线段宽度
  3728. this.ClassName = 'ChartStick';
  3729. this.DrawLine = function ()
  3730. {
  3731. if (this.ChartFrame.IsMinSize) return;
  3732. if (this.IsHideScriptIndex()) return;
  3733. if (!this.Data || !this.Data.Data) return;
  3734. var isHScreen = (this.ChartFrame.IsHScreen === true);
  3735. var dataWidth = this.ChartFrame.DataWidth;
  3736. var distanceWidth = this.ChartFrame.DistanceWidth;
  3737. var chartright = this.ChartBorder.GetRight();
  3738. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  3739. var xPointCount = this.ChartFrame.XPointCount;
  3740. this.Canvas.save();
  3741. if (this.LineWidth > 0) this.Canvas.lineWidth = this.LineWidth;
  3742. var bFirstPoint = true;
  3743. var drawCount = 0;
  3744. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3745. {
  3746. var value = this.Data.Data[i];
  3747. if (value == null) continue;
  3748. var x = this.ChartFrame.GetXFromIndex(j);
  3749. var y = this.ChartFrame.GetYFromData(value);
  3750. if (x > chartright) break;
  3751. if (bFirstPoint)
  3752. {
  3753. this.Canvas.strokeStyle = this.Color;
  3754. this.Canvas.beginPath();
  3755. if (isHScreen) this.Canvas.moveTo(y, x);
  3756. else this.Canvas.moveTo(x, y);
  3757. bFirstPoint = false;
  3758. }
  3759. else
  3760. {
  3761. if (isHScreen) this.Canvas.lineTo(y, x);
  3762. else this.Canvas.lineTo(x, y);
  3763. }
  3764. ++drawCount;
  3765. }
  3766. if (drawCount > 0) this.Canvas.stroke();
  3767. this.Canvas.restore();
  3768. }
  3769. this.DrawStick = function ()
  3770. {
  3771. if (!this.Data || !this.Data.Data) return;
  3772. var bHScreen = (this.ChartFrame.IsHScreen === true);
  3773. var chartright = this.ChartBorder.GetRight();
  3774. if (bHScreen) chartright = this.ChartBorder.GetBottom();
  3775. var xPointCount = this.ChartFrame.XPointCount;
  3776. var yBottom = this.ChartBorder.GetBottom();
  3777. var xLeft = this.ChartBorder.GetLeft();
  3778. this.Canvas.save();
  3779. this.Canvas.strokeStyle = this.Color;
  3780. if (this.LineWidth) this.Canvas.lineWidth = this.LineWidth;
  3781. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  3782. {
  3783. var value = this.Data.Data[i];
  3784. if (value == null) continue;
  3785. var x = this.ChartFrame.GetXFromIndex(j);
  3786. var y = this.ChartFrame.GetYFromData(value);
  3787. if (x > chartright) break;
  3788. this.Canvas.beginPath();
  3789. if (bHScreen)
  3790. {
  3791. this.Canvas.moveTo(xLeft, x);
  3792. this.Canvas.lineTo(y, x);
  3793. this.Canvas.stroke();
  3794. }
  3795. else
  3796. {
  3797. var xFix = parseInt(x.toString()) + 0.5;
  3798. this.Canvas.moveTo(xFix, y);
  3799. this.Canvas.lineTo(xFix, yBottom);
  3800. }
  3801. this.Canvas.stroke();
  3802. }
  3803. this.Canvas.restore();
  3804. }
  3805. this.Draw = function ()
  3806. {
  3807. if (!this.IsShow) return;
  3808. if (this.NotSupportMessage)
  3809. {
  3810. this.DrawNotSupportmessage();
  3811. return;
  3812. }
  3813. this.DrawStick();
  3814. }
  3815. }
  3816. //通达信语法 LINESTICK 支持横屏
  3817. function ChartLineStick()
  3818. {
  3819. this.newMethod = ChartStick; //派生
  3820. this.newMethod();
  3821. delete this.newMethod;
  3822. this.ClassName = 'ChartLineStick';
  3823. this.Draw = function ()
  3824. {
  3825. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  3826. if (this.IsHideScriptIndex()) return;
  3827. if (this.NotSupportMessage)
  3828. {
  3829. this.DrawNotSupportmessage();
  3830. return;
  3831. }
  3832. this.DrawStick();
  3833. this.DrawLine();
  3834. }
  3835. }
  3836. //柱子 支持横屏
  3837. function ChartStickLine()
  3838. {
  3839. this.newMethod = IChartPainting; //派生
  3840. this.newMethod();
  3841. delete this.newMethod;
  3842. this.ClassName ='ChartStickLine';
  3843. this.Color = "rgb(255,193,37)"; //线段颜色
  3844. this.BarType = 0; //柱子类型 0=实心 1=空心 -1=画虚线空心柱
  3845. this.LineDotted=[3,3]; //虚线设置
  3846. this.Width=0; //柱子宽度 0=1 3,50=k线宽度 101=K线宽度+间距宽度
  3847. this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
  3848. this.SetEmptyBar=function() //设置空心柱子
  3849. {
  3850. if (this.BarType!=1 && this.BarType!=-1) return false;
  3851. this.Canvas.lineWidth=1;
  3852. this.Canvas.strokeStyle=this.Color;
  3853. var emptyBGColor=g_JSChartResource.EmptyBarBGColor;
  3854. if (emptyBGColor) this.Canvas.fillStyle=emptyBGColor;
  3855. if (this.BarType==-1) //虚线
  3856. {
  3857. this.Canvas.setLineDash(this.LineDotted); //虚线
  3858. }
  3859. return true;
  3860. }
  3861. this.IsEmptyBar=function()
  3862. {
  3863. return (this.BarType==1 || this.BarType==-1);
  3864. }
  3865. this.Draw = function ()
  3866. {
  3867. if (this.ChartFrame.IsMinSize) return;
  3868. if (this.NotSupportMessage)
  3869. {
  3870. this.DrawNotSupportmessage();
  3871. return;
  3872. }
  3873. if (!this.Data || !this.Data.Data) return;
  3874. var isHScreen = (this.ChartFrame.IsHScreen === true);
  3875. var dataWidth = this.ChartFrame.DataWidth;
  3876. var distanceWidth = this.ChartFrame.DistanceWidth;
  3877. var chartright = this.ChartBorder.GetRight();
  3878. var xPointCount = this.ChartFrame.XPointCount;
  3879. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
  3880. var isMinute=this.IsMinuteFrame();
  3881. if (isHScreen)
  3882. {
  3883. chartright = this.ChartBorder.GetBottom();
  3884. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + g_JSChartResource.FrameLeftMargin;
  3885. }
  3886. this.Canvas.save();
  3887. var bFillBar = false;
  3888. var bFillKLine = false;
  3889. var emptyBGColor=g_JSChartResource.EmptyBarBGColor;
  3890. if (isMinute)
  3891. {
  3892. if (this.Width>1) this.Canvas.lineWidth=2;
  3893. else this.Canvas.lineWidth=1;
  3894. this.Canvas.strokeStyle=this.Color;
  3895. }
  3896. else if(this.Width==0)
  3897. {
  3898. this.SetEmptyBar();
  3899. this.Canvas.lineWidth=1;
  3900. this.Canvas.strokeStyle=this.Color;
  3901. }
  3902. else if (this.Width==50 || this.Width==3)
  3903. {
  3904. if (dataWidth >= this.MinBarWidth)
  3905. {
  3906. bFillKLine = true;
  3907. this.SetEmptyBar();
  3908. if (!this.IsEmptyBar()) this.Canvas.fillStyle = this.Color;
  3909. this.Canvas.strokeStyle = this.Color;
  3910. }
  3911. else //太细了 画竖线
  3912. {
  3913. this.Canvas.lineWidth = 1;
  3914. this.Canvas.strokeStyle = this.Color;
  3915. }
  3916. }
  3917. else if (this.Width==101)
  3918. {
  3919. var lineWidth=dataWidth+distanceWidth+1;
  3920. this.Canvas.lineWidth=lineWidth;
  3921. this.Canvas.strokeStyle=this.Color;
  3922. }
  3923. else if (this.Width <=3 )
  3924. {
  3925. var minWidth=2;
  3926. var barWidth=dataWidth*(this.Width/3);
  3927. if (barWidth<minWidth) barWidth=minWidth;
  3928. this.SetEmptyBar();
  3929. if (!this.IsEmptyBar()) this.Canvas.fillStyle=this.Color;
  3930. bFillBar=true;
  3931. }
  3932. else
  3933. {
  3934. var barWidth=this.Width;
  3935. this.SetEmptyBar();
  3936. if (!this.IsEmptyBar()) this.Canvas.fillStyle=this.Color;
  3937. bFillBar=true;
  3938. }
  3939. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  3940. {
  3941. var value = this.Data.Data[i];
  3942. if (value == null) continue;
  3943. var price = value.Value;
  3944. var price2 = value.Value2;
  3945. if (price2 == null) price2 = 0;
  3946. if (isMinute)
  3947. {
  3948. var x=this.ChartFrame.GetXFromIndex(j);
  3949. }
  3950. else
  3951. {
  3952. var left=xOffset;
  3953. var right=xOffset+dataWidth;
  3954. var x=left+(right-left)/2;
  3955. }
  3956. var y = this.ChartFrame.GetYFromData(price);
  3957. var y2 = this.ChartFrame.GetYFromData(price2);
  3958. if (x > chartright) break;
  3959. if (bFillBar)
  3960. {
  3961. if (isHScreen)
  3962. {
  3963. var left=x-barWidth/2;
  3964. var width=barWidth;
  3965. if (this.IsEmptyBar()) //空心
  3966. {
  3967. this.Canvas.beginPath();
  3968. this.Canvas.rect(ToFixedPoint(Math.min(y,y2)),ToFixedPoint(left),ToFixedRect(Math.abs(y-y2)),ToFixedRect(width));
  3969. this.Canvas.stroke();
  3970. }
  3971. else
  3972. {
  3973. this.Canvas.fillRect(ToFixedRect(Math.min(y,y2)),ToFixedRect(left),ToFixedRect(Math.abs(y-y2)),ToFixedRect(width));
  3974. }
  3975. }
  3976. else
  3977. {
  3978. var left=x-barWidth/2;
  3979. var width=barWidth;
  3980. if (left+width>chartright) width=chartright-left; //不要超过右边框子
  3981. if (this.IsEmptyBar()) //空心
  3982. {
  3983. if (emptyBGColor)
  3984. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,y2)),ToFixedRect(width),ToFixedRect(Math.abs(y-y2)));
  3985. this.Canvas.beginPath();
  3986. this.Canvas.rect(ToFixedPoint(left),ToFixedPoint(Math.min(y,y2)),ToFixedRect(width),ToFixedRect(Math.abs(y-y2)));
  3987. this.Canvas.stroke();
  3988. }
  3989. else
  3990. {
  3991. this.Canvas.fillRect(ToFixedRect(left),ToFixedRect(Math.min(y,y2)),ToFixedRect(width),ToFixedRect(Math.abs(y-y2)));
  3992. }
  3993. }
  3994. }
  3995. else if (bFillKLine)
  3996. {
  3997. if (this.BarType == 1) //实心
  3998. {
  3999. if (isHScreen)
  4000. {
  4001. this.Canvas.beginPath();
  4002. this.Canvas.fillRect(ToFixedRect(Math.min(y, y2)), ToFixedRect(xOffset), ToFixedRect(Math.abs(y - y2)), ToFixedRect(dataWidth));
  4003. this.Canvas.stroke();
  4004. }
  4005. else
  4006. {
  4007. this.Canvas.beginPath();
  4008. this.Canvas.rect(ToFixedRect(xOffset), ToFixedRect(Math.min(y, y2)), ToFixedRect(dataWidth), ToFixedRect(Math.abs(y - y2)));
  4009. this.Canvas.stroke();
  4010. }
  4011. }
  4012. else
  4013. {
  4014. if (isHScreen)
  4015. this.Canvas.fillRect(ToFixedRect(Math.min(y, y2)), ToFixedRect(xOffset), ToFixedRect(Math.abs(y - y2)), ToFixedRect(dataWidth));
  4016. else
  4017. this.Canvas.fillRect(ToFixedRect(xOffset), ToFixedRect(Math.min(y, y2)), ToFixedRect(dataWidth), ToFixedRect(Math.abs(y - y2)));
  4018. }
  4019. }
  4020. else
  4021. {
  4022. if (isHScreen)
  4023. {
  4024. this.Canvas.beginPath();
  4025. this.Canvas.moveTo(y, ToFixedPoint(x));
  4026. this.Canvas.lineTo(y2, ToFixedPoint(x));
  4027. this.Canvas.stroke();
  4028. }
  4029. else
  4030. {
  4031. var xFix = parseInt(x.toString()) + 0.5;
  4032. this.Canvas.beginPath();
  4033. this.Canvas.moveTo(xFix, y);
  4034. this.Canvas.lineTo(xFix, y2);
  4035. this.Canvas.stroke();
  4036. }
  4037. }
  4038. }
  4039. this.Canvas.restore();
  4040. }
  4041. this.GetMaxMin = function ()
  4042. {
  4043. var xPointCount = this.ChartFrame.XPointCount;
  4044. var range = {};
  4045. range.Min = null;
  4046. range.Max = null;
  4047. if (!this.Data || !this.Data.Data) return range;
  4048. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  4049. {
  4050. var data = this.Data.Data[i];
  4051. if (data == null) continue;
  4052. var value2 = data.Value2;
  4053. if (value2 == null) value2 = 0;
  4054. if (data == null || isNaN(data.Value) || isNaN(value2)) continue;
  4055. var valueMax = Math.max(data.Value, value2);
  4056. var valueMin = Math.min(data.Value, value2);
  4057. if (range.Max == null) range.Max = valueMax;
  4058. if (range.Min == null) range.Min = valueMin;
  4059. if (range.Max < valueMax) range.Max = valueMax;
  4060. if (range.Min > valueMin) range.Min = valueMin;
  4061. }
  4062. return range;
  4063. }
  4064. }
  4065. //画矩形
  4066. function ChartRectangle()
  4067. {
  4068. this.newMethod = IChartPainting; //派生
  4069. this.newMethod();
  4070. delete this.newMethod;
  4071. this.ClassName ='ChartRectangle';
  4072. this.Color = [];
  4073. this.Rect;
  4074. this.BorderColor = g_JSChartResource.FrameBorderPen;
  4075. this.Draw = function ()
  4076. {
  4077. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  4078. if (!this.Color || !this.Rect) return;
  4079. if (this.Color.length <= 0) return;
  4080. this.Canvas.strokeStyle = this.BorderColor;
  4081. var bFill = false;
  4082. if (this.Color.length == 2)
  4083. {
  4084. /* TODO
  4085. if (this.ColorAngle==0)
  4086. {
  4087. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  4088. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
  4089. }
  4090. else
  4091. {
  4092. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  4093. var ptEnd={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
  4094. }
  4095. let gradient = this.Canvas.createLinearGradient(ptStart.X,ptStart.Y, ptEnd.X,ptEnd.Y);
  4096. gradient.addColorStop(0, this.Color[0]);
  4097. gradient.addColorStop(1, this.Color[1]);
  4098. this.Canvas.fillStyle=gradient;
  4099. */
  4100. this.Canvas.fillStyle = this.Color[0];
  4101. bFill = true;
  4102. }
  4103. else if (this.Color.length == 1)
  4104. {
  4105. if (this.Color[0])
  4106. {
  4107. this.Canvas.fillStyle = this.Color[0];
  4108. bFill = true;
  4109. }
  4110. }
  4111. else
  4112. {
  4113. return;
  4114. }
  4115. var chartWidth = this.ChartBorder.GetWidth();
  4116. var chartHeight = this.ChartBorder.GetHeightEx();
  4117. var left = this.Rect.Left / 1000 * chartWidth;
  4118. var top = this.Rect.Top / 1000 * chartHeight;
  4119. var right = this.Rect.Right / 1000 * chartWidth;
  4120. var bottom = this.Rect.Bottom / 1000 * chartHeight;
  4121. left = this.ChartBorder.GetLeft() + left
  4122. top = this.ChartBorder.GetTopEx() + top;
  4123. right = this.ChartBorder.GetLeft() + right;
  4124. bottom = this.ChartBorder.GetTopEx() + bottom;
  4125. var width = Math.abs(left - right);
  4126. var height = Math.abs(top - bottom);
  4127. if (bFill) this.Canvas.fillRect(left, top, width, height);
  4128. this.Canvas.beginPath();
  4129. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(top), ToFixedRect(width), ToFixedRect(height));
  4130. this.Canvas.stroke();
  4131. }
  4132. }
  4133. //K线叠加
  4134. function ChartOverlayKLine()
  4135. {
  4136. this.newMethod = IChartPainting; //派生
  4137. this.newMethod();
  4138. delete this.newMethod;
  4139. this.Color = "rgb(65,105,225)";
  4140. this.MainData; //主图K线数据
  4141. this.SourceData; //叠加的原始数据
  4142. this.Name = "ChartOverlayKLine";
  4143. this.Title;
  4144. this.DrawType = 0;
  4145. this.ClassName ='ChartOverlayKLine';
  4146. this.CustomDrawType = null; //图形类型
  4147. this.Status=OVERLAY_STATUS_ID.STATUS_NONE_ID;
  4148. this.ShowRange={ }; //K线显示范围 { Start:, End:, DataCount:, ShowCount: }
  4149. this.DrawKRange={ Start:null, End:null }; //当前屏K线的索引{ Start: , End:}
  4150. this.YInfoType=4;
  4151. this.SetOption = function (option)
  4152. {
  4153. if (!option) return;
  4154. if (IFrameSplitOperator.IsNumber(option.DrawType)) this.CustomDrawType = option.DrawType;
  4155. if (IFrameSplitOperator.IsNumber(option.YInfoType)) this.YInfoType=option.YInfoType;
  4156. }
  4157. this.DrawKBar = function (firstOpen) //firstOpen 当前屏第1个显示数据
  4158. {
  4159. var isHScreen = (this.ChartFrame.IsHScreen === true);
  4160. var dataWidth = this.ChartFrame.DataWidth;
  4161. var distanceWidth = this.ChartFrame.DistanceWidth;
  4162. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  4163. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  4164. var chartright = this.ChartBorder.GetRight();
  4165. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  4166. var xPointCount = this.ChartFrame.XPointCount;
  4167. var isFristDraw = true;
  4168. var firstOverlayOpen = null;
  4169. this.ShowRange.Start=this.Data.DataOffset;
  4170. this.ShowRange.End=this.ShowRange.Start;
  4171. this.ShowRange.DataCount=0;
  4172. this.ShowRange.ShowCount=xPointCount;
  4173. this.ShowRange.FirstOpen=firstOpen;
  4174. this.DrawKRange.Start=this.Data.DataOffset;
  4175. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
  4176. {
  4177. var data = this.Data.Data[i];
  4178. if (!data || data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  4179. if (firstOverlayOpen == null)
  4180. {
  4181. firstOverlayOpen = data.Open;
  4182. this.ShowRange.FirstOverlayOpen=data.Open;
  4183. }
  4184. if (isFristDraw)
  4185. {
  4186. this.Canvas.strokeStyle = this.Color;
  4187. this.Canvas.fillStyle = this.Color;
  4188. this.Canvas.beginPath();
  4189. isFristDraw = false;
  4190. }
  4191. var left = xOffset;
  4192. var right = xOffset + dataWidth;
  4193. if (right > chartright) break;
  4194. var x = left + (right - left) / 2;
  4195. var yLow = this.ChartFrame.GetYFromData(data.Low / firstOverlayOpen * firstOpen);
  4196. var yHigh = this.ChartFrame.GetYFromData(data.High / firstOverlayOpen * firstOpen);
  4197. var yOpen = this.ChartFrame.GetYFromData(data.Open / firstOverlayOpen * firstOpen);
  4198. var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
  4199. var y = yHigh;
  4200. this.DrawKRange.End=i;
  4201. if (data.Open < data.Close) //阳线
  4202. {
  4203. if (dataWidth >= 4)
  4204. {
  4205. if (data.High > data.Close) //上影线
  4206. {
  4207. if (isHScreen)
  4208. {
  4209. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  4210. this.Canvas.lineTo(ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : yClose), ToFixedPoint(x));
  4211. }
  4212. else
  4213. {
  4214. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  4215. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : yClose));
  4216. }
  4217. y = yClose;
  4218. }
  4219. else
  4220. {
  4221. y = yClose;
  4222. }
  4223. if (isHScreen) {
  4224. if (Math.abs(yOpen - y) < 1)
  4225. {
  4226. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  4227. }
  4228. else
  4229. {
  4230. if (this.DrawType == 3) this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth)); //空心柱
  4231. else this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yOpen - y), ToFixedRect(dataWidth));
  4232. }
  4233. }
  4234. else
  4235. {
  4236. if (Math.abs(yOpen - y) < 1)
  4237. {
  4238. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  4239. }
  4240. else
  4241. {
  4242. if (this.DrawType == 3) this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y)); //空心柱
  4243. else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yOpen - y));
  4244. }
  4245. }
  4246. if (data.Open > data.Low)
  4247. {
  4248. if (isHScreen)
  4249. {
  4250. this.Canvas.moveTo(ToFixedPoint(this.DrawType == 3 ? Math.min(yClose, yOpen) : y), ToFixedPoint(x));
  4251. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  4252. }
  4253. else
  4254. {
  4255. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(this.DrawType == 3 ? Math.max(yClose, yOpen) : y));
  4256. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  4257. }
  4258. }
  4259. }
  4260. else
  4261. {
  4262. if (isHScreen)
  4263. {
  4264. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  4265. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  4266. }
  4267. else
  4268. {
  4269. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  4270. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  4271. }
  4272. }
  4273. }
  4274. else if (data.Open > data.Close) //阴线
  4275. {
  4276. if (dataWidth >= 4)
  4277. {
  4278. if (data.High > data.Close) //上影线
  4279. {
  4280. if (isHScreen)
  4281. {
  4282. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  4283. this.Canvas.lineTo(ToFixedPoint(yOpen), ToFixedPoint(x));
  4284. }
  4285. else
  4286. {
  4287. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  4288. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yOpen));
  4289. }
  4290. y = yOpen;
  4291. }
  4292. else
  4293. {
  4294. y = yOpen
  4295. }
  4296. if (isHScreen)
  4297. {
  4298. if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), 1, ToFixedRect(dataWidth)); //高度小于1,统一使用高度1
  4299. else this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(left), ToFixedRect(yClose - y), ToFixedRect(dataWidth));
  4300. }
  4301. else
  4302. {
  4303. if (Math.abs(yClose - y) < 1) this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), 1); //高度小于1,统一使用高度1
  4304. else this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(y), ToFixedRect(dataWidth), ToFixedRect(yClose - y));
  4305. }
  4306. if (data.Open > data.Low) //下影线
  4307. {
  4308. if (isHScreen)
  4309. {
  4310. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  4311. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  4312. }
  4313. else
  4314. {
  4315. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  4316. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  4317. }
  4318. }
  4319. }
  4320. else
  4321. {
  4322. if (isHScreen)
  4323. {
  4324. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  4325. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  4326. }
  4327. else
  4328. {
  4329. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  4330. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  4331. }
  4332. }
  4333. }
  4334. else // 平线
  4335. {
  4336. if (dataWidth >= 4)
  4337. {
  4338. if (data.High > data.Close) //上影线
  4339. {
  4340. if (isHScreen)
  4341. {
  4342. this.Canvas.moveTo(y, ToFixedPoint(x));
  4343. this.Canvas.lineTo(yOpen, ToFixedPoint(x));
  4344. }
  4345. else
  4346. {
  4347. this.Canvas.moveTo(ToFixedPoint(x), y);
  4348. this.Canvas.lineTo(ToFixedPoint(x), yOpen);
  4349. }
  4350. y = yOpen;
  4351. }
  4352. else
  4353. {
  4354. y = yOpen;
  4355. }
  4356. if (isHScreen)
  4357. {
  4358. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(left));
  4359. this.Canvas.lineTo(ToFixedPoint(y), ToFixedPoint(right));
  4360. }
  4361. else
  4362. {
  4363. this.Canvas.moveTo(ToFixedPoint(left), ToFixedPoint(y));
  4364. this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(y));
  4365. }
  4366. if (data.Open > data.Low) //下影线
  4367. {
  4368. if (isHScreen)
  4369. {
  4370. this.Canvas.moveTo(ToFixedPoint(y), ToFixedPoint(x));
  4371. this.Canvas.lineTo(ToFixedPoint(yLow), ToFixedPoint(x));
  4372. }
  4373. else
  4374. {
  4375. this.Canvas.moveTo(ToFixedPoint(x), ToFixedPoint(y));
  4376. this.Canvas.lineTo(ToFixedPoint(x), ToFixedPoint(yLow));
  4377. }
  4378. }
  4379. }
  4380. else
  4381. {
  4382. if (isHScreen)
  4383. {
  4384. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  4385. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  4386. }
  4387. else
  4388. {
  4389. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  4390. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  4391. }
  4392. }
  4393. }
  4394. }
  4395. if (isFristDraw == false) this.Canvas.stroke();
  4396. }
  4397. this.DrawAKLine = function (firstOpen) //美国线
  4398. {
  4399. var isHScreen = (this.ChartFrame.IsHScreen === true);
  4400. var dataWidth = this.ChartFrame.DataWidth;
  4401. var distanceWidth = this.ChartFrame.DistanceWidth;
  4402. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  4403. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  4404. var chartright = this.ChartBorder.GetRight();
  4405. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  4406. var xPointCount = this.ChartFrame.XPointCount;
  4407. var firstOverlayOpen = null;
  4408. this.Canvas.strokeStyle = this.Color;
  4409. this.ShowRange.Start=this.Data.DataOffset;
  4410. this.ShowRange.End=this.ShowRange.Start;
  4411. this.ShowRange.DataCount=0;
  4412. this.ShowRange.ShowCount=xPointCount;
  4413. this.ShowRange.FirstOpen=firstOpen;
  4414. this.DrawKRange.Start=this.Data.DataOffset;
  4415. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
  4416. {
  4417. var data = this.Data.Data[i];
  4418. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  4419. if (firstOverlayOpen == null)
  4420. {
  4421. firstOverlayOpen = data.Open;
  4422. this.ShowRange.FirstOverlayOpen=data.Open;
  4423. }
  4424. var left = xOffset;
  4425. var right = xOffset + dataWidth;
  4426. if (right > chartright) break;
  4427. var x = left + (right - left) / 2;
  4428. var yLow = this.ChartFrame.GetYFromData(data.Low / firstOverlayOpen * firstOpen);
  4429. var yHigh = this.ChartFrame.GetYFromData(data.High / firstOverlayOpen * firstOpen);
  4430. var yOpen = this.ChartFrame.GetYFromData(data.Open / firstOverlayOpen * firstOpen);
  4431. var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
  4432. this.DrawKRange.End=i;
  4433. this.Canvas.beginPath(); //最高-最低
  4434. if (isHScreen)
  4435. {
  4436. this.Canvas.moveTo(yHigh, ToFixedPoint(x));
  4437. this.Canvas.lineTo(yLow, ToFixedPoint(x));
  4438. }
  4439. else
  4440. {
  4441. this.Canvas.moveTo(ToFixedPoint(x), yHigh);
  4442. this.Canvas.lineTo(ToFixedPoint(x), yLow);
  4443. }
  4444. this.Canvas.stroke();
  4445. if (dataWidth >= 4)
  4446. {
  4447. this.Canvas.beginPath(); //开盘
  4448. if (isHScreen)
  4449. {
  4450. this.Canvas.moveTo(ToFixedPoint(yOpen), left);
  4451. this.Canvas.lineTo(ToFixedPoint(yOpen), x);
  4452. }
  4453. else
  4454. {
  4455. this.Canvas.moveTo(left, ToFixedPoint(yOpen));
  4456. this.Canvas.lineTo(x, ToFixedPoint(yOpen));
  4457. }
  4458. this.Canvas.stroke();
  4459. this.Canvas.beginPath(); //收盘
  4460. if (isHScreen)
  4461. {
  4462. this.Canvas.moveTo(ToFixedPoint(yClose), right);
  4463. this.Canvas.lineTo(ToFixedPoint(yClose), x);
  4464. }
  4465. else
  4466. {
  4467. this.Canvas.moveTo(right, ToFixedPoint(yClose));
  4468. this.Canvas.lineTo(x, ToFixedPoint(yClose));
  4469. }
  4470. this.Canvas.stroke();
  4471. }
  4472. }
  4473. }
  4474. this.DrawCloseLine = function (firstOpen) //收盘价线
  4475. {
  4476. var isHScreen = (this.ChartFrame.IsHScreen === true);
  4477. var dataWidth = this.ChartFrame.DataWidth;
  4478. var distanceWidth = this.ChartFrame.DistanceWidth;
  4479. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  4480. if (isHScreen) xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  4481. var chartright = this.ChartBorder.GetRight();
  4482. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  4483. var xPointCount = this.ChartFrame.XPointCount;
  4484. var firstOverlayOpen = null;
  4485. var bFirstPoint = true;
  4486. this.ShowRange.Start=this.Data.DataOffset;
  4487. this.ShowRange.End=this.ShowRange.Start;
  4488. this.ShowRange.DataCount=0;
  4489. this.ShowRange.ShowCount=xPointCount;
  4490. this.ShowRange.FirstOpen=firstOpen;
  4491. this.DrawKRange.Start=this.Data.DataOffset;
  4492. this.Canvas.strokeStyle = this.Color;
  4493. this.Canvas.beginPath();
  4494. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth),++this.ShowRange.DataCount)
  4495. {
  4496. var data = this.Data.Data[i];
  4497. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  4498. if (firstOverlayOpen == null)
  4499. {
  4500. firstOverlayOpen = data.Open;
  4501. this.ShowRange.FirstOverlayOpen=data.Open;
  4502. }
  4503. var left = xOffset;
  4504. var right = xOffset + dataWidth;
  4505. if (right > chartright) break;
  4506. var x = left + (right - left) / 2;
  4507. var yClose = this.ChartFrame.GetYFromData(data.Close / firstOverlayOpen * firstOpen);
  4508. this.DrawKRange.End=i;
  4509. if (bFirstPoint)
  4510. {
  4511. if (isHScreen) this.Canvas.moveTo(yClose, x);
  4512. else this.Canvas.moveTo(x, yClose);
  4513. bFirstPoint = false;
  4514. }
  4515. else
  4516. {
  4517. if (isHScreen) this.Canvas.lineTo(yClose, x);
  4518. else this.Canvas.lineTo(x, yClose);
  4519. }
  4520. }
  4521. if (bFirstPoint == false) this.Canvas.stroke();
  4522. }
  4523. this.Draw = function ()
  4524. {
  4525. this.TooltipRect = [];
  4526. this.DrawKRange={ Start:null, End:null };
  4527. if (!this.MainData || !this.Data) return;
  4528. var xPointCount = this.ChartFrame.XPointCount;
  4529. var firstOpen = null; //主线数据第1个开盘价
  4530. for (var i = this.Data.DataOffset, j = 0; i < this.MainData.Data.length && j < xPointCount; ++i, ++j)
  4531. {
  4532. var data = this.MainData.Data[i];
  4533. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  4534. firstOpen = data.Open;
  4535. break;
  4536. }
  4537. if (firstOpen == null) return;
  4538. var drawTypeBackup = this.DrawType; //备份下线段类型
  4539. if (this.CustomDrawType != null) this.DrawType = this.CustomDrawType;
  4540. if (this.DrawType == 1) this.DrawCloseLine(firstOpen);
  4541. else if (this.DrawType == 2) this.DrawAKLine(firstOpen);
  4542. else this.DrawKBar(firstOpen);
  4543. this.DrawType = drawTypeBackup; //还原线段类型
  4544. }
  4545. this.GetMaxMin = function ()
  4546. {
  4547. var xPointCount = this.ChartFrame.XPointCount;
  4548. var range = {};
  4549. range.Max = null;
  4550. range.Min = null;
  4551. if (!this.MainData || !this.Data) return range;
  4552. var firstOpen = null; //主线数据第1个收盘价
  4553. for (var i = this.Data.DataOffset, j = 0; i < this.MainData.Data.length && j < xPointCount; ++i, ++j)
  4554. {
  4555. var data = this.MainData.Data[i];
  4556. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  4557. firstOpen = data.Close;
  4558. break;
  4559. }
  4560. if (firstOpen == null) return range;
  4561. var firstOverlayOpen = null;
  4562. var high, low;
  4563. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  4564. {
  4565. var data = this.Data.Data[i];
  4566. if (!data || data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  4567. if (firstOverlayOpen == null) firstOverlayOpen = data.Open;
  4568. high = data.High / firstOverlayOpen * firstOpen;
  4569. low = data.Low / firstOverlayOpen * firstOpen;
  4570. if (range.Max == null) range.Max = high;
  4571. if (range.Min == null) range.Min = low;
  4572. if (range.Max < high) range.Max = high;
  4573. if (range.Min > low) range.Min = low;
  4574. }
  4575. return range;
  4576. }
  4577. }
  4578. // 多文本集合 支持横屏
  4579. function ChartMultiText()
  4580. {
  4581. this.newMethod = IChartPainting; //派生
  4582. this.newMethod();
  4583. delete this.newMethod;
  4584. this.ClassName ='ChartMultiText';
  4585. this.Texts = []; //[ {Index:, Value:, Text:, Color:, Font: , Baseline:, Line:{ Color:, Dash:[虚线点], KData:"H/L", Offset:[5,10], Width:线粗细 } } ]
  4586. this.Font = g_JSChartResource.DefaultTextFont;
  4587. this.Color = g_JSChartResource.DefaultTextColor;
  4588. this.IsHScreen = false; //是否横屏
  4589. this.BuildKey=function(item)
  4590. {
  4591. if (IFrameSplitOperator.IsNumber(item.Time))
  4592. {
  4593. var key=`${item.Date}-${item.Time}`;
  4594. }
  4595. else
  4596. {
  4597. var key=`${item.Date}`;
  4598. }
  4599. return key;
  4600. }
  4601. this.GetShowTextData=function()
  4602. {
  4603. var xPointCount=this.ChartFrame.XPointCount;
  4604. var offset=this.Data.DataOffset;
  4605. var mapText=new Map(); //key='date-time' value={ Data:[] }
  4606. for(var i=0; i<this.Texts.length; ++i)
  4607. {
  4608. var item=this.Texts[i];
  4609. if (!item.Text) continue;
  4610. if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
  4611. var index=item.Index-offset;
  4612. if (index>=0 && index<xPointCount)
  4613. {
  4614. var key=this.BuildKey(item);
  4615. if (mapText.has(key))
  4616. {
  4617. var textItem=mapText.get(key);
  4618. textItem.Data.push(item);
  4619. }
  4620. else
  4621. {
  4622. var textItem={ Data:[item] };
  4623. mapText.set(key, textItem);
  4624. }
  4625. }
  4626. }
  4627. return mapText;
  4628. }
  4629. this.Draw = function ()
  4630. {
  4631. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  4632. if (!this.Data || this.Data.length <= 0) return;
  4633. if (!this.Texts) return;
  4634. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  4635. var mapText=this.GetShowTextData();
  4636. if (mapText.size<=0) return;
  4637. this.Canvas.save();
  4638. this.DrawAllText(mapText);
  4639. this.Canvas.restore();
  4640. }
  4641. this.DrawAllText=function(mapText)
  4642. {
  4643. var bHScreen=(this.ChartFrame.IsHScreen===true);
  4644. var isMinute=this.IsMinuteFrame();
  4645. var dataWidth=this.ChartFrame.DataWidth;
  4646. var distanceWidth=this.ChartFrame.DistanceWidth;
  4647. var xPointCount=this.ChartFrame.XPointCount;
  4648. if (bHScreen)
  4649. {
  4650. var border=this.ChartBorder.GetHScreenBorder();
  4651. var chartright=border.BottomEx;
  4652. var chartleft=border.TopEx;
  4653. var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  4654. var left=this.ChartBorder.GetTop();
  4655. var right=this.ChartBorder.GetBottom();
  4656. var top=border.RightEx;
  4657. var bottom=border.LeftEx;
  4658. }
  4659. else
  4660. {
  4661. var border=this.ChartBorder.GetBorder();
  4662. var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  4663. var chartright=border.RightEx;
  4664. var chartleft=border.LeftEx;
  4665. var left=this.ChartBorder.GetLeft();
  4666. var right=this.ChartBorder.GetRight();
  4667. var top=border.TopEx;
  4668. var bottom=border.BottomEx;
  4669. }
  4670. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  4671. {
  4672. var kItem=this.Data.Data[i];
  4673. if (!kItem) continue;
  4674. var key=this.BuildKey(kItem);
  4675. if (!mapText.has(key)) continue;
  4676. var left=xOffset;
  4677. var right=xOffset+dataWidth;
  4678. if (right>chartright) break;
  4679. var x=left+(right-left)/2;
  4680. var textItem=mapText.get(key);
  4681. for(var k=0;k<textItem.Data.length;++k)
  4682. {
  4683. var item=textItem.Data[k];
  4684. var y=top;
  4685. if (item.Value=="TOP") y=top;
  4686. else if (item.Value=="BOTTOM") y=bottom;
  4687. else y=this.ChartFrame.GetYFromData(item.Value, false);
  4688. if (item.Color) this.Canvas.fillStyle = item.Color;
  4689. else this.Canvas.fillStyle = this.Color;
  4690. if (item.Font) this.Canvas.font = item.Font;
  4691. else this.Canvas.font=this.Font;
  4692. var textWidth=this.Canvas.measureText(item.Text).width;
  4693. this.Canvas.textAlign='center';
  4694. if (x+textWidth/2>=chartright)
  4695. {
  4696. this.Canvas.textAlign='right';
  4697. x=chartright;
  4698. }
  4699. else if (x-textWidth/2<chartleft)
  4700. {
  4701. this.Canvas.textAlign = 'left';
  4702. x=chartleft;
  4703. }
  4704. if (item.Baseline==1) this.Canvas.textBaseline='top';
  4705. else if (item.Baseline==2) this.Canvas.textBaseline='bottom';
  4706. else this.Canvas.textBaseline = 'middle';
  4707. if (this.IsHScreen)
  4708. {
  4709. this.Canvas.save();
  4710. this.Canvas.translate(y, x);
  4711. this.Canvas.rotate(90 * Math.PI / 180);
  4712. this.Canvas.fillText(item.Text,0,0);
  4713. this.Canvas.restore();
  4714. }
  4715. else
  4716. {
  4717. if (IFrameSplitOperator.IsNumber(item.YMove)) y+=item.YMove;
  4718. this.Canvas.fillText(item.Text, x, y);
  4719. }
  4720. if (item.Line)
  4721. {
  4722. var kItem=this.Data.Data[item.Index];
  4723. var price=item.Line.KData=="H"? kItem.High:kItem.Low;
  4724. var yPrice=this.ChartFrame.GetYFromData(price, false);
  4725. var yText=y;
  4726. if (Array.isArray(item.Line.Offset) && item.Line.Offset.length==2)
  4727. {
  4728. if (yText>yPrice) //文字在下方
  4729. {
  4730. yText-=item.Line.Offset[1];
  4731. yPrice+=item.Line.Offset[0]
  4732. }
  4733. else if (yText<yPrice)
  4734. {
  4735. yText+=item.Line.Offset[1];
  4736. yPrice-=item.Line.Offset[0]
  4737. }
  4738. }
  4739. this.Canvas.save();
  4740. if (item.Line.Dash) this.Canvas.setLineDash(item.Line.Dash); //虚线
  4741. if (item.Line.Width>0) this.Canvas.lineWidth=item.Line.Width; //线宽
  4742. this.Canvas.strokeStyle = item.Line.Color;
  4743. this.Canvas.beginPath();
  4744. if (this.IsHScreen)
  4745. {
  4746. this.Canvas.moveTo(yText, ToFixedPoint(x));
  4747. this.Canvas.lineTo(yPrice,ToFixedPoint(x));
  4748. }
  4749. else
  4750. {
  4751. this.Canvas.moveTo(ToFixedPoint(x),yText);
  4752. this.Canvas.lineTo(ToFixedPoint(x),yPrice);
  4753. }
  4754. this.Canvas.stroke();
  4755. this.Canvas.restore();
  4756. }
  4757. }
  4758. }
  4759. }
  4760. this.GetMaxMin = function ()
  4761. {
  4762. var range = { Min: null, Max: null };
  4763. if (!this.Texts) return range;
  4764. var xPointCount = this.ChartFrame.XPointCount;
  4765. var start = this.Data.DataOffset;
  4766. var end = start + xPointCount;
  4767. for (var i in this.Texts)
  4768. {
  4769. var item = this.Texts[i];
  4770. if (item.Index >= start && item.Index < end)
  4771. {
  4772. if (range.Max == null) range.Max = item.Value;
  4773. else if (range.Max < item.Value) range.Max = item.Value;
  4774. if (range.Min == null) range.Min = item.Value;
  4775. else if (range.Min > item.Value) range.Min = item.Value;
  4776. }
  4777. }
  4778. return range;
  4779. }
  4780. }
  4781. // 多dom节点
  4782. function ChartMultiHtmlDom()
  4783. {
  4784. this.newMethod=IChartPainting; //派生
  4785. this.newMethod();
  4786. delete this.newMethod;
  4787. this.ClassName="ChartMultiHtmlDom";
  4788. this.Texts=[]; //[ {Index:, Value:, Text: ] Text=dom内容
  4789. this.IsHScreen=false; //是否横屏
  4790. this.DrawCallback; //function(op, obj) op:1=开始 2=结束 3=绘制单个数据 4=销毁
  4791. this.DrawItem=[];
  4792. this.IsDestroy=false; //是否已销毁
  4793. this.Draw=function()
  4794. {
  4795. this.DrawItem=[];
  4796. if (this.DrawCallback) this.DrawCallback(1, {Self:this} );
  4797. this.DrawDom();
  4798. if (this.DrawCallback) this.DrawCallback(2, { Self:this, Draw:this.DrawItem } );
  4799. }
  4800. this.OnDestroy=function()
  4801. {
  4802. this.IsDestroy=true;
  4803. if (this.DrawCallback) this.DrawCallback(4, { Self:this } );
  4804. }
  4805. this.DrawDom=function()
  4806. {
  4807. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  4808. if (!this.Data || this.Data.length<=0) return;
  4809. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  4810. var xPointCount=this.ChartFrame.XPointCount;
  4811. var offset=this.Data.DataOffset;
  4812. for(var i in this.Texts)
  4813. {
  4814. var item=this.Texts[i];
  4815. if (!item.Text) continue;
  4816. if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
  4817. var index=item.Index-offset;
  4818. var kItem=this.Data.Data[item.Index]; //K线数据
  4819. var obj={ KData:kItem, Item:item, IsShow:false, Self:this };
  4820. if (index>=0 && index<xPointCount)
  4821. {
  4822. var x=this.ChartFrame.GetXFromIndex(index);
  4823. var y=this.ChartFrame.GetYFromData(item.Value);
  4824. obj.X=x;
  4825. obj.Y=y;
  4826. obj.IsShow=true;
  4827. }
  4828. this.DrawItem.push(obj);
  4829. if (this.DrawCallback) this.DrawCallback(3, obj);
  4830. }
  4831. }
  4832. this.GetMaxMin=function()
  4833. {
  4834. var range={ Min:null, Max:null };
  4835. var xPointCount=this.ChartFrame.XPointCount;
  4836. var start=this.Data.DataOffset;
  4837. var end=start+xPointCount;
  4838. for(var i in this.Texts)
  4839. {
  4840. var item=this.Texts[i];
  4841. if (!IFrameSplitOperator.IsNumber(item.Index)) continue;
  4842. if (item.Index>=start && item.Index<end)
  4843. {
  4844. if (range.Max==null) range.Max=item.Value;
  4845. else if (range.Max<item.Value) range.Max=item.Value;
  4846. if (range.Min==null) range.Min=item.Value;
  4847. else if (range.Min>item.Value) range.Min=item.Value;
  4848. }
  4849. }
  4850. return range;
  4851. }
  4852. }
  4853. // 线段集合 支持横屏
  4854. function ChartMultiLine()
  4855. {
  4856. this.newMethod = IChartPainting; //派生
  4857. this.newMethod();
  4858. delete this.newMethod;
  4859. this.ClassName="ChartMultiLine";
  4860. this.Lines = []; // [ {Point:[ {Index, Value }, ], Color: }, ]
  4861. this.IsHScreen = false;
  4862. this.LineWidth=1;
  4863. this.LineDash;
  4864. //箭头配置
  4865. this.ArrawAngle=35; //三角斜边一直线夹角
  4866. this.ArrawLength=10; //三角斜边长度
  4867. this.ArrawLineWidth=5; //箭头粗细
  4868. this.Arrow={ Start:false, End:false }; //Start=是否绘制开始箭头 <- End=是否绘制结束箭头 ->
  4869. this.Draw = function ()
  4870. {
  4871. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  4872. if (!this.Data || this.Data.length <= 0) return;
  4873. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  4874. var xPointCount = this.ChartFrame.XPointCount;
  4875. var offset = this.Data.DataOffset;
  4876. var drawLines = [];
  4877. var arrowLines=[];
  4878. for (var i=0; i<this.Lines.length; ++i)
  4879. {
  4880. var line = this.Lines[i];
  4881. var drawPoints = { Point: [], Color: line.Color };
  4882. var drawArrowPoints={ Start:[], End:[] };
  4883. if (line.BGColor) drawPoints.BGColor=line.BGColor;
  4884. for (var j=0;j<line.Point.length; ++j)
  4885. {
  4886. var point = line.Point[j];
  4887. if (!IFrameSplitOperator.IsNumber(point.Index)) continue;
  4888. var index = point.Index - offset;
  4889. if (index >= 0 && index < xPointCount)
  4890. {
  4891. var x = this.ChartFrame.GetXFromIndex(index);
  4892. var y = this.ChartFrame.GetYFromData(point.Value);
  4893. var pointItem={X:x, Y:y, End:false };
  4894. drawPoints.Point.push({ X: x, Y: y });
  4895. if (j==0 || j==1) drawArrowPoints.Start.push(pointItem); //起始点
  4896. if (j==line.Point.length-1 || j==line.Point.length-2) drawArrowPoints.End.push(pointItem); //结束点
  4897. }
  4898. else
  4899. {
  4900. if (drawPoints.Point.length>0) drawPoints.Point[drawPoints.Point.length-1].End=true; //点断开
  4901. }
  4902. }
  4903. if (drawPoints.Point.length >= 2)
  4904. {
  4905. drawLines.push(drawPoints);
  4906. arrowLines.push(drawArrowPoints);
  4907. }
  4908. }
  4909. this.Canvas.save();
  4910. for (var i=0; i<drawLines.length; ++i)
  4911. {
  4912. if (this.LineDash) this.Canvas.setLineDash(this.LineDash);
  4913. if (IFrameSplitOperator.IsPlusNumber(this.LineWidth)) this.Canvas.lineWidth=this.LineWidth;
  4914. else this.Canvas.lineWidth=1;
  4915. var item = drawLines[i];
  4916. this.DrawLine(item, arrowLines[i]);
  4917. }
  4918. this.Canvas.restore();
  4919. }
  4920. this.DrawLine = function (line, arrow)
  4921. {
  4922. if (line.BGColor) //背景色
  4923. {
  4924. this.Canvas.fillStyle=line.BGColor;
  4925. for(var i=0; i<line.Point.length; ++i)
  4926. {
  4927. var item=line.Point[i];
  4928. if (i==0)
  4929. {
  4930. this.Canvas.beginPath();
  4931. if (this.IsHScreen) this.Canvas.moveTo(item.Y,item.X);
  4932. else this.Canvas.moveTo(item.X,item.Y);
  4933. }
  4934. else
  4935. {
  4936. if (this.IsHScreen) this.Canvas.lineTo(item.Y,item.X);
  4937. else this.Canvas.lineTo(item.X,item.Y);
  4938. }
  4939. }
  4940. this.Canvas.closePath();
  4941. this.Canvas.fill();
  4942. }
  4943. this.Canvas.strokeStyle = line.Color;
  4944. var drawCount=0;
  4945. for (var i=0; i<line.Point.length; ++i)
  4946. {
  4947. var item = line.Point[i];
  4948. if (drawCount==0)
  4949. {
  4950. this.Canvas.beginPath();
  4951. if (this.IsHScreen) this.Canvas.moveTo(item.Y, item.X);
  4952. else this.Canvas.moveTo(item.X, item.Y);
  4953. ++drawCount;
  4954. }
  4955. else
  4956. {
  4957. if (this.IsHScreen) this.Canvas.lineTo(item.Y, item.X);
  4958. else this.Canvas.lineTo(item.X, item.Y);
  4959. ++drawCount;
  4960. }
  4961. if (item.End==true) //点断了 要重新画
  4962. {
  4963. if (drawCount>0) this.Canvas.stroke();
  4964. drawCount=0;
  4965. }
  4966. }
  4967. if (drawCount>0) this.Canvas.stroke();
  4968. //绘制箭头
  4969. if (arrow.End.length==2 && this.Arrow.End==true)
  4970. this.DrawArrow(arrow.End[0],arrow.End[1]);
  4971. if (arrow.Start.length==2 && this.Arrow.Start==true)
  4972. this.DrawArrow(arrow.Start[1],arrow.Start[0]);
  4973. }
  4974. this.DrawArrow=function(ptStart,ptEnd)
  4975. {
  4976. //计算箭头
  4977. var theta=this.ArrawAngle; //三角斜边一直线夹角
  4978. var headlen=this.ArrawLength; //三角斜边长度
  4979. var angle = Math.atan2(ptStart.Y - ptEnd.Y, ptStart.X - ptEnd.X) * 180 / Math.PI,
  4980. angle1 = (angle + theta) * Math.PI / 180,
  4981. angle2 = (angle - theta) * Math.PI / 180,
  4982. topX = headlen * Math.cos(angle1),
  4983. topY = headlen * Math.sin(angle1),
  4984. botX = headlen * Math.cos(angle2),
  4985. botY = headlen * Math.sin(angle2);
  4986. this.Canvas.beginPath();
  4987. var arrowX = ptEnd.X + topX;
  4988. var arrowY = ptEnd.Y + topY;
  4989. this.Canvas.moveTo(arrowX,arrowY);
  4990. this.Canvas.lineTo(ptEnd.X, ptEnd.Y);
  4991. arrowX = ptEnd.X + botX;
  4992. arrowY = ptEnd.Y + botY;
  4993. this.Canvas.lineTo(arrowX,arrowY);
  4994. this.Canvas.setLineDash([]);
  4995. this.Canvas.lineWidth=this.ArrawLineWidth;
  4996. this.Canvas.stroke();
  4997. }
  4998. this.GetMaxMin = function ()
  4999. {
  5000. var range = { Min: null, Max: null };
  5001. var xPointCount = this.ChartFrame.XPointCount;
  5002. var start = this.Data.DataOffset;
  5003. var end = start + xPointCount;
  5004. for (var i in this.Lines)
  5005. {
  5006. var line = this.Lines[i];
  5007. for (var j in line.Point)
  5008. {
  5009. var point = line.Point[j];
  5010. if (point.Index >= start && point.Index < end)
  5011. {
  5012. if (range.Max == null) range.Max = point.Value;
  5013. else if (range.Max < point.Value) range.Max = point.Value;
  5014. if (range.Min == null) range.Min = point.Value;
  5015. else if (range.Min > point.Value) range.Min = point.Value;
  5016. }
  5017. }
  5018. }
  5019. return range;
  5020. }
  5021. }
  5022. // 线段集合 支持横屏
  5023. function ChartMultiPoint()
  5024. {
  5025. this.newMethod=IChartPainting; //派生
  5026. this.newMethod();
  5027. delete this.newMethod;
  5028. this.ClassName="ChartMultiPoint";
  5029. this.PointGroup=[]; // [ {Point:[ {Index, Value }, ], Color: }, ]
  5030. this.IsHScreen=false;
  5031. this.LineWidth=1;
  5032. this.PointRadius=5;
  5033. this.Draw=function()
  5034. {
  5035. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  5036. if (!this.Data || this.Data.length<=0) return;
  5037. if (!IFrameSplitOperator.IsNonEmptyArray(this.PointGroup)) return;
  5038. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  5039. var xPointCount=this.ChartFrame.XPointCount;
  5040. var offset=this.Data.DataOffset;
  5041. this.Canvas.save();
  5042. for(var i=0; i<this.PointGroup.length; ++i)
  5043. {
  5044. var item=this.PointGroup[i];
  5045. var color=item.Color;
  5046. var bgColor=item.BGColor;
  5047. var lineWidth=this.LineWidth;
  5048. var radius=this.PointRadius;
  5049. if (IFrameSplitOperator.IsNumber(item.LineWidth)) lineWidth=item.LineWidth;
  5050. if (IFrameSplitOperator.IsNumber(item.PointRadius)) radius=item.PointRadius;
  5051. this.Canvas.lineWidth=lineWidth;
  5052. if (bgColor) this.Canvas.fillStyle=bgColor; //背景填充颜色
  5053. if (color) this.Canvas.strokeStyle=color;
  5054. for(var j=0; j<item.Point.length; ++j)
  5055. {
  5056. var point=item.Point[j];
  5057. if (!IFrameSplitOperator.IsNumber(point.Index)) continue;
  5058. var index=point.Index-offset;
  5059. if (index>=0 && index<xPointCount)
  5060. {
  5061. var x=this.ChartFrame.GetXFromIndex(index);
  5062. var y=this.ChartFrame.GetYFromData(point.Value);
  5063. this.Canvas.beginPath();
  5064. if (this.IsHScreen)
  5065. this.Canvas.arc(y,x,radius,0,360,false);
  5066. else
  5067. this.Canvas.arc(x,y,radius,0,360,false);
  5068. if (bgColor) this.Canvas.fill();
  5069. if (color) this.Canvas.stroke();
  5070. }
  5071. }
  5072. }
  5073. this.Canvas.restore();
  5074. }
  5075. this.GetMaxMin=function()
  5076. {
  5077. var range={ Min:null, Max:null };
  5078. var xPointCount=this.ChartFrame.XPointCount;
  5079. var start=this.Data.DataOffset;
  5080. var end=start+xPointCount;
  5081. for(var i=0; i<this.PointGroup.length; ++i)
  5082. {
  5083. var item=this.PointGroup[i];
  5084. if (!IFrameSplitOperator.IsNonEmptyArray(item.Point)) continue;
  5085. for(var j=0; j<item.Point.length; ++j)
  5086. {
  5087. var point=item.Point[j];
  5088. if (point.Index>=start && point.Index<end)
  5089. {
  5090. if (range.Max==null) range.Max=point.Value;
  5091. else if (range.Max<point.Value) range.Max=point.Value;
  5092. if (range.Min==null) range.Min=point.Value;
  5093. else if (range.Min>point.Value) range.Min=point.Value;
  5094. }
  5095. }
  5096. }
  5097. return range;
  5098. }
  5099. }
  5100. // 柱子集合 支持横屏
  5101. function ChartMultiBar()
  5102. {
  5103. this.newMethod = IChartPainting; //派生
  5104. this.newMethod();
  5105. delete this.newMethod;
  5106. this.Bars = []; // [ {Point:[ {Index, Value, Value2 }, ], Color:, Width: , Type: 0 实心 1 空心 }, ]
  5107. this.IsHScreen = false;
  5108. this.Draw = function ()
  5109. {
  5110. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  5111. if (!this.Data || this.Data.length <= 0) return;
  5112. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  5113. var xPointCount = this.ChartFrame.XPointCount;
  5114. var offset = this.Data.DataOffset;
  5115. var dataWidth = this.ChartFrame.DataWidth;
  5116. var drawBars = [];
  5117. for (var i in this.Bars)
  5118. {
  5119. var item = this.Bars[i];
  5120. var drawPoints = { Point: [], Color: item.Color, Width: dataWidth, Type: 0 };
  5121. if (item.Type > 0) drawPoints.Type = item.Type;
  5122. if (item.Width > 0)
  5123. {
  5124. drawPoints.Width = item.Width;
  5125. if (drawPoints.Width > dataWidth) drawPoints.Width = dataWidth;
  5126. }
  5127. else
  5128. {
  5129. if (drawPoints.Width < 4) drawPoints.Width = 1;
  5130. }
  5131. for (var j in item.Point)
  5132. {
  5133. var point = item.Point[j];
  5134. if (!IFrameSplitOperator.IsNumber(point.Index)) continue;
  5135. var index = point.Index - offset;
  5136. if (index >= 0 && index < xPointCount)
  5137. {
  5138. var x = this.ChartFrame.GetXFromIndex(index);
  5139. var y = this.ChartFrame.GetYFromData(point.Value);
  5140. var y2 = this.ChartFrame.GetYFromData(point.Value2);
  5141. drawPoints.Point.push({ X: x, Y: y, Y2: y2 });
  5142. }
  5143. }
  5144. if (drawPoints.Point.length > 0) drawBars.push(drawPoints)
  5145. }
  5146. for (var i in drawBars)
  5147. {
  5148. var item = drawBars[i];
  5149. if (item.Width >= 4)
  5150. {
  5151. if (item.Type == 1) this.DrawHollowBar(item);
  5152. else this.DrawFillBar(item);
  5153. }
  5154. else
  5155. {
  5156. this.DrawLineBar(item);
  5157. }
  5158. }
  5159. }
  5160. this.DrawLineBar = function (bar)
  5161. {
  5162. this.Canvas.strokeStyle = bar.Color;
  5163. var backupLineWidth = this.Canvas.lineWidth;
  5164. this.Canvas.lineWidth = bar.Width;
  5165. for (var i in bar.Point)
  5166. {
  5167. var item = bar.Point[i];
  5168. this.Canvas.beginPath();
  5169. if (this.IsHScreen)
  5170. {
  5171. this.Canvas.moveTo(ToFixedPoint(item.Y), ToFixedPoint(item.X));
  5172. this.Canvas.lineTo(ToFixedPoint(item.Y2), ToFixedPoint(item.X));
  5173. }
  5174. else
  5175. {
  5176. this.Canvas.moveTo(ToFixedPoint(item.X), ToFixedPoint(item.Y));
  5177. this.Canvas.lineTo(ToFixedPoint(item.X), ToFixedPoint(item.Y2));
  5178. }
  5179. this.Canvas.stroke();
  5180. }
  5181. this.Canvas.lineWidth = backupLineWidth;
  5182. }
  5183. this.DrawFillBar = function (bar)
  5184. {
  5185. this.Canvas.fillStyle = bar.Color;
  5186. for (var i in bar.Point)
  5187. {
  5188. var item = bar.Point[i];
  5189. var x = item.X - (bar.Width / 2);
  5190. var y = Math.min(item.Y, item.Y2);
  5191. var barWidth = bar.Width;
  5192. var barHeight = Math.abs(item.Y - item.Y2);
  5193. if (this.IsHScreen)
  5194. this.Canvas.fillRect(ToFixedRect(y), ToFixedRect(x), ToFixedRect(barHeight), ToFixedRect(barWidth));
  5195. else
  5196. this.Canvas.fillRect(ToFixedRect(x), ToFixedRect(y), ToFixedRect(barWidth), ToFixedRect(barHeight));
  5197. }
  5198. }
  5199. this.DrawHollowBar = function (bar) //空心柱子
  5200. {
  5201. this.Canvas.strokeStyle = bar.Color;
  5202. var backupLineWidth = 1;
  5203. for (var i in bar.Point)
  5204. {
  5205. var item = bar.Point[i];
  5206. var x = item.X - (bar.Width / 2);
  5207. var y = Math.min(item.Y, item.Y2);
  5208. var barWidth = bar.Width;
  5209. var barHeight = Math.abs(item.Y - item.Y2);
  5210. this.Canvas.beginPath();
  5211. if (this.IsHScreen)
  5212. this.Canvas.rect(ToFixedPoint(y), ToFixedPoint(x), ToFixedRect(barHeight), ToFixedRect(barWidth));
  5213. else
  5214. this.Canvas.rect(ToFixedPoint(x), ToFixedPoint(y), ToFixedRect(barWidth), ToFixedRect(barHeight));
  5215. this.Canvas.stroke();
  5216. }
  5217. this.Canvas.lineWidth = backupLineWidth;
  5218. }
  5219. this.GetMaxMin = function ()
  5220. {
  5221. var range = { Min: null, Max: null };
  5222. var xPointCount = this.ChartFrame.XPointCount;
  5223. var start = this.Data.DataOffset;
  5224. var end = start + xPointCount;
  5225. for (var i in this.Bars)
  5226. {
  5227. var item = this.Bars[i];
  5228. for (var j in item.Point)
  5229. {
  5230. var point = item.Point[j];
  5231. if (point.Index >= start && point.Index < end)
  5232. {
  5233. var minValue = Math.min(point.Value, point.Value2);
  5234. var maxValue = Math.max(point.Value, point.Value2);
  5235. if (range.Max == null) range.Max = maxValue;
  5236. else if (range.Max < maxValue) range.Max = maxValue;
  5237. if (range.Min == null) range.Min = minValue;
  5238. else if (range.Min > minValue) range.Min = minValue;
  5239. }
  5240. }
  5241. }
  5242. return range;
  5243. }
  5244. }
  5245. //分钟信息地雷 支持横屏
  5246. function ChartMinuteInfo()
  5247. {
  5248. this.newMethod = IChartPainting; //派生
  5249. this.newMethod();
  5250. delete this.newMethod;
  5251. this.ClassName = "ChartMinuteInfo";
  5252. this.Data = new Map() //Map key=date-time, value=[{Date, Time, Title, Type, ID:}]
  5253. this.SourceData;
  5254. this.ChartMinutePrice;
  5255. this.YClose;
  5256. this.TextColor = g_JSChartResource.MinuteInfo.TextColor;
  5257. this.Font = g_JSChartResource.MinuteInfo.Font;
  5258. this.PointColor = g_JSChartResource.MinuteInfo.PointColor;
  5259. this.PointRadius=g_JSChartResource.MinuteInfo.PointRadius;
  5260. this.LineColor = g_JSChartResource.MinuteInfo.LineColor;
  5261. this.TextBGColor = g_JSChartResource.MinuteInfo.TextBGColor;
  5262. this.TextHeight = 18;
  5263. this.TextRectCache = [];
  5264. this.InfoDrawCache = [];
  5265. this.FrameBottom;
  5266. this.FrameTop;
  5267. this.FrameLeft;
  5268. this.FrameRight;
  5269. this.YOffset = 5;
  5270. this.IsHScreen = false;
  5271. this.SetOption = function (option)
  5272. {
  5273. if (option.TextColor) this.TextColor = option.TextColor;
  5274. if (option.TextBGColor) this.TextBGColor = option.TextBGColor;
  5275. if (option.Font) this.Font = option.Font;
  5276. if (option.PointColor) this.PointColor = option.PointColor;
  5277. if (option.LineColor) this.LineColor = option.LineColor;
  5278. if (option.TextHeight > 0) this.TextHeight = option.TextHeight;
  5279. }
  5280. this.Draw = function ()
  5281. {
  5282. if (!this.ChartMinutePrice) return;
  5283. if (!this.Data || this.Data.size <= 0) return;
  5284. this.TextRectCache = [];
  5285. this.InfoDrawCache = [];
  5286. this.IsHScreen = (this.ChartFrame.IsHScreen === true);
  5287. var xPointCount = this.ChartFrame.XPointCount;
  5288. var minuteCount = this.ChartFrame.MinuteCount;
  5289. this.FrameBottom = this.ChartBorder.GetBottom();
  5290. this.FrameTop = this.ChartBorder.GetTop();
  5291. this.FrameLeft = this.ChartBorder.GetLeft();
  5292. this.FrameRight = this.ChartBorder.GetRight();
  5293. if (this.IsHScreen)
  5294. {
  5295. this.FrameRight = this.ChartBorder.GetBottom();
  5296. this.FrameLeft = this.ChartBorder.GetTop();
  5297. this.FrameBottom = this.ChartBorder.GetLeft();
  5298. this.FrameTop = this.ChartBorder.GetRight();
  5299. }
  5300. this.YClose = this.ChartMinutePrice.YClose;
  5301. var data = this.ChartMinutePrice.Data;
  5302. var isBeforeData = false;
  5303. if (this.ChartMinutePrice.SourceData)
  5304. {
  5305. data = this.ChartMinutePrice.SourceData;
  5306. isBeforeData = true;
  5307. }
  5308. this.Canvas.font = this.Font;
  5309. for (var i = data.DataOffset, j = 0; i < data.Data.length && j < xPointCount; ++i, ++j)
  5310. {
  5311. var item = this.SourceData.Data[i];
  5312. if (isBeforeData && item.Before) continue;
  5313. if (!item) continue;
  5314. var dateTime = item.DateTime;
  5315. if (!this.Data.has(dateTime)) continue;
  5316. if (this.IsHScreen)
  5317. this.CalcuateInfoHScreenPosition(this.Data.get(dateTime), j, item);
  5318. else
  5319. this.CalcuateInfoPosition(this.Data.get(dateTime), j, item);
  5320. }
  5321. for (var i in this.InfoDrawCache)
  5322. {
  5323. var item = this.InfoDrawCache[i];
  5324. this.DrawInfoLines(item);
  5325. }
  5326. for (var i in this.InfoDrawCache)
  5327. {
  5328. var item = this.InfoDrawCache[i];
  5329. this.DrawInfoText(item);
  5330. }
  5331. this.TextRectCache = [];
  5332. this.InfoDrawCache = [];
  5333. }
  5334. this.CalcuateInfoPosition = function (infoItem, index, minuteItem)
  5335. {
  5336. if (!infoItem || !infoItem.Data || infoItem.Data.length <= 0) return;
  5337. var showItem = infoItem.Data[0];
  5338. var textWidth = this.Canvas.measureText(showItem.Title).width + 4;
  5339. var textHeight = this.TextHeight;
  5340. var x = this.ChartFrame.GetXFromIndex(index);
  5341. var y = this.ChartFrame.GetYFromData(minuteItem.Close);
  5342. x = ToFixedPoint(x);
  5343. var isDrawLeft = x < (this.FrameLeft + Math.abs(this.FrameLeft - this.FrameRight) / 2);
  5344. var ARRAY_OFFSET = [2, 4, 3, 2, 3, 3, 2];
  5345. var offset = textHeight + ARRAY_OFFSET[index % ARRAY_OFFSET.length];
  5346. var yData =
  5347. {
  5348. Y:
  5349. [
  5350. { Value: y + (textHeight + this.YOffset), Offset: offset },
  5351. { Value: y - (2 * textHeight + this.YOffset), Offset: -offset }
  5352. ]
  5353. };
  5354. if (minuteItem.Close < this.YClose)
  5355. yData.Y = yData.Y.reverse();
  5356. var rtBorder = { X: x, Y: null, Width: textWidth, Height: textHeight };
  5357. if (!isDrawLeft) rtBorder.X -= rtBorder.Width;
  5358. this.FixTextRect(rtBorder, yData);
  5359. var InfoDrawItem = { Border: rtBorder, Start: { X: x, Y: y }, IsLeft: isDrawLeft, Title: showItem.Title };
  5360. if (showItem.Content) InfoDrawItem.Content=showItem.Content;
  5361. if (showItem.Link) InfoDrawItem.Link=showItem.Link;
  5362. if (showItem.Color) InfoDrawItem.Color=showItem.Color;
  5363. if (showItem.BGColor) InfoDrawItem.BGColor=showItem.BGColor;
  5364. this.InfoDrawCache.push(InfoDrawItem);
  5365. this.TextRectCache.push(rtBorder);
  5366. }
  5367. this.CalcuateInfoHScreenPosition = function (infoItem, index, minuteItem)
  5368. {
  5369. if (!infoItem || !infoItem.Data || infoItem.Data.length <= 0) return;
  5370. var showItem = infoItem.Data[0];
  5371. var textHeight = this.Canvas.measureText(showItem.Title).width + 4;
  5372. var textWidth = this.TextHeight;
  5373. var y = this.ChartFrame.GetXFromIndex(index);
  5374. var x = this.ChartFrame.GetYFromData(minuteItem.Close);
  5375. y = ToFixedPoint(y);
  5376. var isDrawLeft = y < (this.FrameLeft + Math.abs(this.FrameLeft - this.FrameRight) / 2);
  5377. var ARRAY_OFFSET = [2, 4, 3, 2, 3, 3, 2];
  5378. var offset = textWidth + ARRAY_OFFSET[index % ARRAY_OFFSET.length];
  5379. var xData =
  5380. {
  5381. X:
  5382. [
  5383. { Value: x + (textWidth + this.YOffset), Offset: offset },
  5384. { Value: x - (2 * textWidth + this.YOffset), Offset: -offset }
  5385. ]
  5386. };
  5387. if (minuteItem.Close > this.YClose)
  5388. xData.X = xData.X.reverse();
  5389. var rtBorder = { X: null, Y: y, Width: textWidth, Height: textHeight };
  5390. if (!isDrawLeft) rtBorder.Y -= rtBorder.Height;
  5391. this.FixHScreenTextRect(rtBorder, xData);
  5392. var InfoDrawItem = { Border: rtBorder, Start: { X: x, Y: y }, IsLeft: isDrawLeft, Title: showItem.Title };
  5393. if (showItem.Content) InfoDrawItem.Content=showItem.Content;
  5394. if (showItem.Link) InfoDrawItem.Link=showItem.Link;
  5395. if (showItem.Color) InfoDrawItem.Color=showItem.Color;
  5396. if (showItem.BGColor) InfoDrawItem.BGColor=showItem.BGColor;
  5397. this.InfoDrawCache.push(InfoDrawItem);
  5398. this.TextRectCache.push(rtBorder);
  5399. }
  5400. this.DrawInfoLines = function (item)
  5401. {
  5402. var rtBorder = item.Border;
  5403. var isDrawLeft = item.IsLeft;
  5404. this.Canvas.strokeStyle = this.LineColor;
  5405. this.Canvas.beginPath();
  5406. this.Canvas.moveTo(item.Start.X, item.Start.Y);
  5407. if (isDrawLeft)
  5408. {
  5409. this.Canvas.lineTo(rtBorder.X, rtBorder.Y);
  5410. }
  5411. else
  5412. {
  5413. if (this.IsHScreen) this.Canvas.lineTo(rtBorder.X, rtBorder.Y + rtBorder.Height);
  5414. else this.Canvas.lineTo(rtBorder.X + rtBorder.Width, rtBorder.Y);
  5415. }
  5416. this.Canvas.stroke();
  5417. this.Canvas.fillStyle = this.PointColor;
  5418. this.Canvas.beginPath();
  5419. this.Canvas.arc(item.Start.X, item.Start.Y, this.PointRadius, 0, 2 * Math.PI);
  5420. this.Canvas.closePath();
  5421. this.Canvas.fill();
  5422. }
  5423. this.DrawInfoText = function (item)
  5424. {
  5425. var rtBorder = item.Border;
  5426. var x = rtBorder.X, y = rtBorder.Y;
  5427. if (item.BGColor) this.Canvas.fillStyle=item.BGColor
  5428. else this.Canvas.fillStyle = this.TextBGColor;
  5429. this.Canvas.fillRect(x, y, rtBorder.Width, rtBorder.Height);
  5430. this.Canvas.strokeStyle = this.LineColor;
  5431. this.Canvas.beginPath();
  5432. this.Canvas.rect(x, y, rtBorder.Width, rtBorder.Height);
  5433. this.Canvas.stroke();
  5434. if (this.IsHScreen)
  5435. {
  5436. this.Canvas.save();
  5437. this.Canvas.translate(rtBorder.X, rtBorder.Y);
  5438. this.Canvas.rotate(90 * Math.PI / 180);
  5439. x = 0; y = 0;
  5440. }
  5441. this.Canvas.textAlign = 'left'
  5442. this.Canvas.textBaseline = 'middle';
  5443. if (item.Color) this.Canvas.fillStyle=item.Color;
  5444. else this.Canvas.fillStyle = this.TextColor;
  5445. this.Canvas.font = this.Font;
  5446. if (this.IsHScreen) this.Canvas.fillText(item.Title, x + 2, y - rtBorder.Width / 2);
  5447. else this.Canvas.fillText(item.Title, x+2, y + rtBorder.Height / 2);
  5448. if (this.IsHScreen) this.Canvas.restore();
  5449. }
  5450. this.FixTextRect = function (rect, yData)
  5451. {
  5452. for (var k in yData.Y)
  5453. {
  5454. var yItem = yData.Y[k];
  5455. rect.Y = yItem.Value;
  5456. var y;
  5457. for (var j = 0; j < 10; ++j)
  5458. {
  5459. var isOverlap = false;
  5460. for (var i in this.TextRectCache)
  5461. {
  5462. var item = this.TextRectCache[i];
  5463. if (this.IsOverlap(item, rect))
  5464. {
  5465. isOverlap = true;
  5466. break;
  5467. }
  5468. }
  5469. if (isOverlap == false) return;
  5470. y = rect.Y;
  5471. y += yItem.Offset;
  5472. if (y + rect.Height > this.FrameBottom || y < this.FrameTop) break;
  5473. rect.Y = y;
  5474. }
  5475. }
  5476. }
  5477. this.FixHScreenTextRect = function (rect, xData)
  5478. {
  5479. for (var k in xData.X)
  5480. {
  5481. var xItem = xData.X[k];
  5482. rect.X = xItem.Value;
  5483. var x;
  5484. for (var j = 0; j < 10; ++j)
  5485. {
  5486. var isOverlap = false;
  5487. for (var i in this.TextRectCache)
  5488. {
  5489. var item = this.TextRectCache[i];
  5490. if (this.IsOverlap(item, rect))
  5491. {
  5492. isOverlap = true;
  5493. break;
  5494. }
  5495. }
  5496. if (isOverlap == false) return;
  5497. x = rect.X;
  5498. x += xItem.Offset;
  5499. if (x + rect.Width < this.FrameBottom || x > this.FrameTop) break;
  5500. rect.X = x;
  5501. }
  5502. }
  5503. }
  5504. this.IsOverlap = function (rc1, rc2)
  5505. {
  5506. if (rc1.X + rc1.Width > rc2.X && rc2.X + rc2.Width > rc1.X && rc1.Y + rc1.Height > rc2.Y && rc2.Y + rc2.Height > rc1.Y)
  5507. return true;
  5508. else
  5509. return false;
  5510. }
  5511. this.GetMaxMin = function ()
  5512. {
  5513. var range = { Min: null, Max: null };
  5514. return range;
  5515. }
  5516. }
  5517. //买卖盘
  5518. function ChartBuySell()
  5519. {
  5520. this.newMethod = ChartSingleText; //派生
  5521. this.newMethod();
  5522. delete this.newMethod;
  5523. this.ClassName = "ChartBuySell";
  5524. this.TextFont = g_JSChartResource.KLineTrain.Font; //"bold 14px arial"; //买卖信息字体
  5525. this.LastDataIcon = g_JSChartResource.KLineTrain.LastDataIcon; //{Color:'rgb(0,0,205)',Text:'↓'};
  5526. this.BuyIcon = g_JSChartResource.KLineTrain.BuyIcon; //{Color:'rgb(0,0,205)',Text:'B'};
  5527. this.SellIcon = g_JSChartResource.KLineTrain.SellIcon; //{Color:'rgb(0,0,205)',Text:'S'};
  5528. this.BuySellData = new Map(); //Key=数据索引index Value:Data:[ { Op: 买/卖 0=buy 1=sell, Date:, Time, Price: Vol:}, ]
  5529. this.LastDataDrawType=0; //0=画在最后一个数据上 1=画在指定索引上
  5530. this.LastDataIndex=-1;
  5531. this.AddTradeItem = function (tradeItem)
  5532. {
  5533. if (this.BuySellData.has(tradeItem.Key))
  5534. {
  5535. var Trade = this.BuySellData.get(tradeItem.Key);
  5536. Trade.Data.push(tradeItem);
  5537. }
  5538. else
  5539. {
  5540. this.BuySellData.set(tradeItem.Key, { Data: [tradeItem] });
  5541. }
  5542. }
  5543. this.ClearTradeData = function ()
  5544. {
  5545. this.BuySellData = new Map();
  5546. }
  5547. this.Draw = function ()
  5548. {
  5549. if (!this.Data || !this.Data.Data) return;
  5550. var isHScreen = (this.ChartFrame.IsHScreen === true);
  5551. var dataWidth = this.ChartFrame.DataWidth;
  5552. var distanceWidth = this.ChartFrame.DistanceWidth;
  5553. var chartright = this.ChartBorder.GetRight();
  5554. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  5555. var xPointCount = this.ChartFrame.XPointCount;
  5556. var bottom = this.ChartBorder.GetBottomEx();
  5557. var top = this.ChartBorder.GetTopEx();
  5558. var height = this.ChartBorder.GetHeightEx();
  5559. if (isHScreen)
  5560. {
  5561. top = this.ChartBorder.GetRightEx();
  5562. bottom = this.ChartBorder.GetLeftEx();
  5563. height = this.ChartBorder.GetWidthEx();
  5564. }
  5565. this.Canvas.font = this.TextFont;
  5566. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  5567. {
  5568. var value = this.Data.Data[i];
  5569. if (value == null) continue;
  5570. if (x > chartright) break;
  5571. var bDrawLastData=false;
  5572. if (this.LastDataDrawType==1)
  5573. {
  5574. if (i==this.LastDataIndex) bDrawLastData=true;
  5575. }
  5576. else
  5577. {
  5578. if (i==this.Data.Data.length-1) bDrawLastData=true;
  5579. }
  5580. if (bDrawLastData)
  5581. {
  5582. var x = this.ChartFrame.GetXFromIndex(j);
  5583. var yHigh = this.ChartFrame.GetYFromData(value.High);
  5584. if (this.LastDataIcon.Text)
  5585. {
  5586. this.Canvas.textAlign = 'center';
  5587. this.Canvas.textBaseline = 'bottom';
  5588. this.Canvas.fillStyle = this.LastDataIcon.Color;
  5589. this.Canvas.font = this.TextFont;
  5590. this.DrawText(this.LastDataIcon.Text, x, yHigh, isHScreen);
  5591. }
  5592. else
  5593. {
  5594. var obj =
  5595. {
  5596. X: x, Top: top, Bottom: bottom, Height: height,
  5597. DataWidth: dataWidth, Color: this.LastDataIcon.Color, IsHScreen: isHScreen,
  5598. };
  5599. this.DrawLastData(obj);
  5600. }
  5601. }
  5602. var key = i;
  5603. if (!this.BuySellData.has(key)) continue;
  5604. var trade = this.BuySellData.get(key);
  5605. var x = this.ChartFrame.GetXFromIndex(j);
  5606. var yHigh = this.ChartFrame.GetYFromData(value.High);
  5607. var yLow = this.ChartFrame.GetYFromData(value.Low);
  5608. var drawInfo = [false, false]; //0=buy 1=sell
  5609. for (var k in trade.Data)
  5610. {
  5611. if (drawInfo[0] == true && drawInfo[1] == true) break; //买卖图标只画一次
  5612. var bsItem = trade.Data[k];
  5613. if (bsItem.Op == 0 && drawInfo[0] == false) //买 标识在最低价上
  5614. {
  5615. this.Canvas.textAlign = 'center';
  5616. this.Canvas.textBaseline = 'top';
  5617. this.Canvas.fillStyle = this.BuyIcon.Color;
  5618. this.DrawText(this.BuyIcon.Text, x, yLow, isHScreen);
  5619. drawInfo[0] = true;
  5620. }
  5621. else if (bsItem.Op == 1 && drawInfo[1] == false) //卖 标识在最高价上
  5622. {
  5623. this.Canvas.textAlign = 'center';
  5624. this.Canvas.textBaseline = 'bottom';
  5625. this.Canvas.fillStyle = this.SellIcon.Color;
  5626. this.DrawText(this.SellIcon.Text, x, yHigh, isHScreen);
  5627. drawInfo[1] = true;
  5628. }
  5629. }
  5630. }
  5631. }
  5632. this.DrawLastData=function(obj)
  5633. {
  5634. this.Canvas.fillStyle = obj.Color;
  5635. var width = obj.DataWidth;
  5636. if (this.LastDataIcon.Width >= 2 && this.LastDataIcon.Width < obj.DataWidth)
  5637. width = this.LastDataIcon.Width;
  5638. var left = obj.X - width / 2;
  5639. if (obj.IsHScreen)
  5640. {
  5641. this.Canvas.fillRect(ToFixedRect(obj.Bottom), ToFixedRect(left), ToFixedRect(obj.Height), ToFixedRect(width));
  5642. }
  5643. else
  5644. {
  5645. var left = obj.X - width/2;
  5646. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(obj.Top), ToFixedRect(width), ToFixedRect(obj.Height));
  5647. }
  5648. }
  5649. }
  5650. //分钟成交量
  5651. function ChartMinuteVolumBar()
  5652. {
  5653. this.newMethod = IChartPainting; //派生
  5654. this.newMethod();
  5655. delete this.newMethod;
  5656. this.UpColor = g_JSChartResource.UpBarColor;
  5657. this.DownColor = g_JSChartResource.DownBarColor;
  5658. this.UnchangeColor=g_JSChartResource.UnchagneBarColor; //平盘
  5659. this.BarColorType=1; //柱子颜色显示类型 0=红绿 1=红绿白
  5660. this.CustomColor=g_JSChartResource.Minute.VolBarColor;
  5661. this.YClose; //前收盘
  5662. this.Draw = function ()
  5663. {
  5664. var isHScreen = (this.ChartFrame.IsHScreen === true)
  5665. var chartright = this.ChartBorder.GetRight();
  5666. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  5667. var xPointCount = this.ChartFrame.XPointCount;
  5668. var yBottom = this.ChartFrame.GetYFromData(0);
  5669. var yPrice = this.YClose; //上一分钟的价格
  5670. if (this.CustomColor) this.Canvas.strokeStyle=this.CustomColor;
  5671. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  5672. {
  5673. var item = this.Data.Data[i];
  5674. if (!item || !item.Vol) continue;
  5675. var y = this.ChartFrame.GetYFromData(item.Vol);
  5676. var x = this.ChartFrame.GetXFromIndex(i);
  5677. if (x > chartright) break;
  5678. //价格>=上一分钟价格 红色 否则绿色
  5679. if (!this.CustomColor) this.Canvas.strokeStyle = this.GetMinuteBarColor(item.Close, yPrice);
  5680. this.Canvas.beginPath();
  5681. if (isHScreen)
  5682. {
  5683. this.Canvas.moveTo(y, ToFixedPoint(x));
  5684. this.Canvas.lineTo(yBottom, ToFixedPoint(x));
  5685. }
  5686. else
  5687. {
  5688. this.Canvas.moveTo(ToFixedPoint(x), y);
  5689. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  5690. }
  5691. this.Canvas.stroke();
  5692. yPrice = item.Close;
  5693. }
  5694. }
  5695. //连续交易成交量柱子颜色
  5696. this.GetMinuteBarColor=function(price, yPrice)
  5697. {
  5698. if (this.BarColorType==1) //通达信模式
  5699. {
  5700. if (price>yPrice) return this.UpColor;
  5701. else if (price<yPrice) return this.DownColor;
  5702. else return this.UnchangeColor;
  5703. }
  5704. else //东方财富模式
  5705. {
  5706. return price >= yPrice ? this.UpColor:this.DownColor;
  5707. }
  5708. }
  5709. this.GetMaxMin = function ()
  5710. {
  5711. var xPointCount = this.ChartFrame.XPointCount;
  5712. var range = {};
  5713. range.Min = 0;
  5714. range.Max = null;
  5715. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  5716. {
  5717. var item = this.Data.Data[i];
  5718. if (!item || !item.Vol) continue;
  5719. if (range.Max == null) range.Max = item.Vol;
  5720. if (range.Max < item.Vol) range.Max = item.Vol;
  5721. }
  5722. return range;
  5723. }
  5724. }
  5725. //MACD森林线 支持横屏
  5726. function ChartMACD()
  5727. {
  5728. this.newMethod = IChartPainting; //派生
  5729. this.newMethod();
  5730. delete this.newMethod;
  5731. this.ClassName ='ChartMACD';
  5732. this.UpColor = g_JSChartResource.UpBarColor;
  5733. this.DownColor = g_JSChartResource.DownBarColor;
  5734. this.LineWidth=1;
  5735. this.Draw = function ()
  5736. {
  5737. if (this.ChartFrame.IsMinSize || !this.IsVisible) return;
  5738. if (this.IsHideScriptIndex()) return;
  5739. if (this.NotSupportMessage)
  5740. {
  5741. this.DrawNotSupportmessage();
  5742. return;
  5743. }
  5744. if (this.ChartFrame.IsHScreen === true)
  5745. {
  5746. this.HScreenDraw();
  5747. return;
  5748. }
  5749. var isMinute=this.IsMinuteFrame();
  5750. var dataWidth = this.ChartFrame.DataWidth;
  5751. var distanceWidth = this.ChartFrame.DistanceWidth;
  5752. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  5753. var chartright = this.ChartBorder.GetRight();
  5754. var xPointCount = this.ChartFrame.XPointCount;
  5755. var lineWidth=this.LineWidth;
  5756. if (this.LineWidth==50) lineWidth=dataWidth;
  5757. else if (lineWidth>dataWidth) lineWidth=dataWidth;
  5758. this.Canvas.save();
  5759. this.Canvas.lineWidth=lineWidth;
  5760. var bFirstPoint = true;
  5761. var drawCount = 0;
  5762. var yBottom = this.ChartFrame.GetYFromData(0);
  5763. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  5764. //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  5765. {
  5766. var value = this.Data.Data[i];
  5767. if (value == null) continue;
  5768. if (isMinute)
  5769. {
  5770. var x = this.ChartFrame.GetXFromIndex(j);
  5771. }
  5772. else
  5773. {
  5774. var left=xOffset;
  5775. var right=xOffset+dataWidth;
  5776. if (right>chartright) break;
  5777. var x=left+(right-left)/2;
  5778. }
  5779. var y = this.ChartFrame.GetYFromData(value);
  5780. if (x > chartright) break;
  5781. var xFix = parseInt(x.toString()) + 0.5; //毛边修正
  5782. this.Canvas.beginPath();
  5783. this.Canvas.moveTo(xFix, yBottom);
  5784. this.Canvas.lineTo(xFix, y);
  5785. if (value >= 0) this.Canvas.strokeStyle = this.UpColor;
  5786. else this.Canvas.strokeStyle = this.DownColor;
  5787. this.Canvas.stroke();
  5788. this.Canvas.closePath();
  5789. }
  5790. this.Canvas.restore();
  5791. }
  5792. this.HScreenDraw = function ()
  5793. {
  5794. var isMinute=this.IsMinuteFrame();
  5795. var dataWidth = this.ChartFrame.DataWidth;
  5796. var distanceWidth = this.ChartFrame.DistanceWidth;
  5797. var xOffset=this.ChartBorder.GetTop()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  5798. var chartright = this.ChartBorder.GetBottom();
  5799. var xPointCount = this.ChartFrame.XPointCount;
  5800. var yBottom = this.ChartFrame.GetYFromData(0);
  5801. var lineWidth=this.LineWidth;
  5802. if (this.LineWidth==50) lineWidth=dataWidth;
  5803. else if (lineWidth>dataWidth) lineWidth=dataWidth;
  5804. this.Canvas.save();
  5805. this.Canvas.lineWidth=lineWidth;
  5806. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  5807. //for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  5808. {
  5809. var value = this.Data.Data[i];
  5810. if (value == null) continue;
  5811. if (isMinute)
  5812. {
  5813. var x = this.ChartFrame.GetXFromIndex(j);
  5814. }
  5815. else
  5816. {
  5817. var left=xOffset;
  5818. var right=xOffset+dataWidth;
  5819. if (right>chartright) break;
  5820. var x=left+(right-left)/2;
  5821. }
  5822. var y = this.ChartFrame.GetYFromData(value);
  5823. if (x > chartright) break;
  5824. this.Canvas.beginPath();
  5825. this.Canvas.moveTo(yBottom, ToFixedPoint(x));
  5826. this.Canvas.lineTo(y, ToFixedPoint(x));
  5827. if (value >= 0) this.Canvas.strokeStyle = this.UpColor;
  5828. else this.Canvas.strokeStyle = this.DownColor;
  5829. this.Canvas.stroke();
  5830. this.Canvas.closePath();
  5831. }
  5832. this.Canvas.restore();
  5833. }
  5834. }
  5835. //堆积柱状图
  5836. function ChartStackedBar()
  5837. {
  5838. this.newMethod=IChartPainting; //派生
  5839. this.newMethod();
  5840. delete this.newMethod;
  5841. this.ClassName="ChartStackedBar";
  5842. this.Data; //{ Data:[ [bar1, bar2], [bar1,bar2 ] ] };
  5843. this.BarName=[];
  5844. this.BarColor=['rgb(255,165,0)',"rgb(95,158,160)"];
  5845. this.LineWidth=1;
  5846. this.BarType=0; //0=线段 1=K线宽度一致
  5847. this.IsHScreen;
  5848. this.Draw=function()
  5849. {
  5850. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  5851. if (!this.Data || !IFrameSplitOperator.IsNonEmptyArray(this.Data.Data)) return;
  5852. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  5853. var dataWidth=this.ChartFrame.DataWidth;
  5854. var distanceWidth=this.ChartFrame.DistanceWidth;
  5855. var xPointCount=this.ChartFrame.XPointCount;
  5856. if (this.IsHScreen)
  5857. {
  5858. var border=this.ChartBorder.GetHScreenBorder();
  5859. var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  5860. var chartright=border.BottomEx;
  5861. var top=border.RightEx;
  5862. var bottom=border.LeftEx;
  5863. }
  5864. else
  5865. {
  5866. var border=this.ChartFrame.GetBorder();
  5867. var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  5868. var chartright=border.RightEx;
  5869. var top=border.TopEx;
  5870. var bottom=border.BottomEx;
  5871. }
  5872. var isMinute=this.IsMinuteFrame();
  5873. this.Canvas.save();
  5874. if (this.BarType==1)
  5875. {
  5876. }
  5877. else
  5878. {
  5879. if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
  5880. var lineWidth=this.Canvas.lineWidth;
  5881. }
  5882. var yZero=this.ChartFrame.GetYFromData(0);
  5883. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  5884. {
  5885. var bars=this.Data.Data[i];
  5886. if (!IFrameSplitOperator.IsNonEmptyArray(bars)) continue;
  5887. if (isMinute)
  5888. {
  5889. var x=this.ChartFrame.GetXFromIndex(j);
  5890. }
  5891. else
  5892. {
  5893. var left=xOffset;
  5894. var right=xOffset+dataWidth;
  5895. if (right>chartright) break;
  5896. var x=left+(right-left)/2;
  5897. }
  5898. if (x>chartright) break;
  5899. if (this.BarType==1)
  5900. {
  5901. if (dataWidth>=4) //柱子太细就直接画竖线
  5902. this.DrawKBarItem(bars, x, left, right, top, bottom, yZero, dataWidth);
  5903. else
  5904. this.DrawBarItem(bars, x, top, bottom, yZero, lineWidth);
  5905. }
  5906. else
  5907. {
  5908. this.DrawBarItem(bars, x, top, bottom, yZero, lineWidth);
  5909. }
  5910. }
  5911. this.Canvas.restore();
  5912. }
  5913. this.DrawKBarItem=function(aryBar, x, left, right, top, bottom,yZero, barWidth)
  5914. {
  5915. var plusValue=0, yPlus=yZero; //正数
  5916. var negativeValue=0, yNegative= yZero; //负数
  5917. for(var i=0;i<aryBar.length;++i)
  5918. {
  5919. var item=aryBar[i];
  5920. if (!IFrameSplitOperator.IsNumber(item)) continue;
  5921. if(item==0) continue;
  5922. this.Canvas.fillStyle=this.BarColor[i];
  5923. if (item>0)
  5924. {
  5925. plusValue+=item;
  5926. var y=this.ChartFrame.GetYFromData(plusValue);
  5927. var rtBar={Left: left, Top:y, Width:barWidth, Height:(yPlus-y)};
  5928. yPlus=y;
  5929. }
  5930. else
  5931. {
  5932. negativeValue+=item;
  5933. var y=this.ChartFrame.GetYFromData(negativeValue);
  5934. var rtBar={Left:left, Top:y, Width:barWidth, Height:(yNegative-y)};
  5935. yNegative=y;
  5936. }
  5937. if (this.IsHScreen)
  5938. this.Canvas.fillRect(rtBar.Top,rtBar.Left, rtBar.Height, rtBar.Width);
  5939. else
  5940. this.Canvas.fillRect(rtBar.Left, rtBar.Top, rtBar.Width, rtBar.Height);
  5941. }
  5942. }
  5943. this.DrawBarItem=function(aryBar,x, top, bottom, yZero, lineWidth)
  5944. {
  5945. var x=ToFixedPoint(x);
  5946. var plusValue=0, yPlus=yZero; //正数
  5947. var negativeValue=0, yNegative=yZero; //负数
  5948. for(var i=0;i<aryBar.length;++i)
  5949. {
  5950. var item=aryBar[i];
  5951. if (!IFrameSplitOperator.IsNumber(item)) continue;
  5952. if(item==0) continue;
  5953. var line={};
  5954. if (item>0)
  5955. {
  5956. plusValue+=item;
  5957. var y=this.ChartFrame.GetYFromData(plusValue);
  5958. var line={X:x, Y:yPlus, X2:x, Y2:y};
  5959. yPlus=y;
  5960. }
  5961. else
  5962. {
  5963. negativeValue+=item;
  5964. var y=this.ChartFrame.GetYFromData(negativeValue);
  5965. var line={X:x, Y:yNegative, X2:x, Y2:y};
  5966. yNegative=y;
  5967. }
  5968. this.Canvas.beginPath();
  5969. if (this.IsHScreen)
  5970. {
  5971. this.Canvas.moveTo(line.Y,line.X);
  5972. this.Canvas.lineTo(line.Y2,line.X2);
  5973. }
  5974. else
  5975. {
  5976. this.Canvas.moveTo(line.X,line.Y);
  5977. this.Canvas.lineTo(line.X2,line.Y2);
  5978. }
  5979. this.Canvas.strokeStyle=this.BarColor[i];
  5980. this.Canvas.stroke();
  5981. }
  5982. }
  5983. this.GetMaxMin=function()
  5984. {
  5985. var xPointCount=this.ChartFrame.XPointCount;
  5986. var range={};
  5987. range.Min=null;
  5988. range.Max=null;
  5989. if(!this.Data || !this.Data.Data) return range;
  5990. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
  5991. {
  5992. var bars=this.Data.Data[i];
  5993. if (!bars || !IFrameSplitOperator.IsNonEmptyArray(bars)) continue;
  5994. var plusValue=0; //正数
  5995. var negativeValue=0; //负数
  5996. for(var k=0;k<bars.length;++k)
  5997. {
  5998. var barValue=bars[k];
  5999. if (!IFrameSplitOperator.IsNumber(barValue)) continue;
  6000. if (barValue==0) continue;
  6001. if (barValue>0) plusValue+=barValue;
  6002. else if (barValue<0) negativeValue+=barValue;
  6003. }
  6004. if (range.Max==null)
  6005. {
  6006. range.Max=plusValue;
  6007. range.Min=negativeValue;
  6008. }
  6009. if (range.Max<plusValue) range.Max=plusValue;
  6010. if (range.Min>negativeValue) range.Min=negativeValue;
  6011. }
  6012. return range;
  6013. }
  6014. }
  6015. function ChartStepLine()
  6016. {
  6017. this.newMethod=IChartPainting; //派生
  6018. this.newMethod();
  6019. delete this.newMethod;
  6020. this.ClassName='ChartStepLine'; //类名
  6021. this.LineWidth=1; //线段宽度
  6022. this.DotLine;
  6023. this.IsHScreen;
  6024. this.IsDotLine=false; //虚线
  6025. this.Draw=function()
  6026. {
  6027. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  6028. if (this.NotSupportMessage)
  6029. {
  6030. this.DrawNotSupportmessage();
  6031. return;
  6032. }
  6033. if (!this.Data || !this.Data.Data) return;
  6034. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  6035. this.Canvas.save();
  6036. this.DrawLine();
  6037. this.Canvas.restore();
  6038. }
  6039. this.DrawLine=function()
  6040. {
  6041. var isMinute=this.IsMinuteFrame();
  6042. var dataWidth=this.ChartFrame.DataWidth;
  6043. var distanceWidth=this.ChartFrame.DistanceWidth;
  6044. var xPointCount=this.ChartFrame.XPointCount;
  6045. var lockRect=this.GetLockRect();
  6046. if (this.IsHScreen)
  6047. {
  6048. var border=this.ChartBorder.GetHScreenBorder();
  6049. var chartright=border.BottomEx;
  6050. var xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  6051. if (lockRect) chartright=lockRect.Top;
  6052. }
  6053. else
  6054. {
  6055. var border=this.ChartBorder.GetBorder();
  6056. var xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  6057. var chartright=border.RightEx;
  6058. if (lockRect) chartright=lockRect.Left;
  6059. }
  6060. if (this.LineWidth>0) this.Canvas.lineWidth=this.LineWidth;
  6061. if (this.IsDotLine) this.Canvas.setLineDash(g_JSChartResource.DOTLINE.LineDash); //画虚线
  6062. if (this.DotLine) this.Canvas.setLineDash(this.DotLine); //画虚线
  6063. this.Canvas.strokeStyle=this.Color;
  6064. var bFirstPoint=true;
  6065. var drawCount=0;
  6066. var prePoint={ X:null, Y:null };
  6067. for(var i=this.Data.DataOffset; i>=0; --i)
  6068. {
  6069. var value=this.Data.Data[i];
  6070. if (!IFrameSplitOperator.IsNumber(value)) continue;
  6071. var y=this.GetYFromData(value,false);
  6072. var x=null;
  6073. if (isMinute) x=this.ChartFrame.GetXFromIndex(0);
  6074. else x=xOffset;
  6075. this.Canvas.beginPath();
  6076. if (this.IsHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
  6077. else this.Canvas.moveTo(x,y);
  6078. bFirstPoint=false;
  6079. prePoint.Y=y;
  6080. prePoint.X=x;
  6081. }
  6082. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  6083. {
  6084. if (isMinute)
  6085. {
  6086. var x=this.ChartFrame.GetXFromIndex(j);
  6087. }
  6088. else
  6089. {
  6090. var left=xOffset;
  6091. var right=xOffset+dataWidth;
  6092. if (right>chartright) break;
  6093. var x=left+(right-left)/2;
  6094. }
  6095. if (x>chartright) break;
  6096. var value=this.Data.Data[i];
  6097. if (!IFrameSplitOperator.IsNumber(value)) continue;
  6098. var y=this.GetYFromData(value,false);
  6099. if (bFirstPoint)
  6100. {
  6101. this.Canvas.beginPath();
  6102. if (this.IsHScreen) this.Canvas.moveTo(y,x); //横屏坐标轴对调
  6103. else this.Canvas.moveTo(x,y);
  6104. bFirstPoint=false;
  6105. prePoint.X=x;
  6106. prePoint.Y=y;
  6107. }
  6108. else
  6109. {
  6110. if (this.IsHScreen)
  6111. {
  6112. this.Canvas.lineTo(prePoint.Y,x)
  6113. this.Canvas.lineTo(y,x);
  6114. }
  6115. else
  6116. {
  6117. this.Canvas.lineTo(x,prePoint.Y)
  6118. this.Canvas.lineTo(x,y);
  6119. }
  6120. prePoint.X=x;
  6121. prePoint.Y=y;
  6122. }
  6123. ++drawCount;
  6124. }
  6125. if (drawCount>0) this.Canvas.stroke();
  6126. }
  6127. }
  6128. ////////////////////////////////////////////////////////////////////////////////
  6129. // 等待提示
  6130. function ChartSplashPaint()
  6131. {
  6132. this.newMethod = IChartPainting; //派生
  6133. this.newMethod();
  6134. delete this.newMethod;
  6135. this.Font = g_JSChartResource.DefaultTextFont; //字体
  6136. this.TextColor = g_JSChartResource.DefaultTextColor; //文本颜色
  6137. this.IsEnableSplash = false;
  6138. this.SplashTitle = '数据加载中.....';
  6139. this.HQChart;
  6140. this.EnableSplash=function(bEnable)
  6141. {
  6142. this.IsEnableSplash=bEnable;
  6143. if (this.HQChart)
  6144. {
  6145. var event=this.HQChart.GetEnableSplashEvent();
  6146. if (event)
  6147. {
  6148. var data={ Enable:bEnable };
  6149. event.Callback(event,data,this);
  6150. }
  6151. }
  6152. }
  6153. this.SetTitle=function(title)
  6154. {
  6155. this.SplashTitle=title;
  6156. }
  6157. this.Draw = function ()
  6158. {
  6159. if (!this.IsEnableSplash) return;
  6160. if (this.Frame.IsHScreen === true)
  6161. {
  6162. this.HScreenDraw();
  6163. return;
  6164. }
  6165. var xCenter = (this.Frame.ChartBorder.GetLeft() + this.Frame.ChartBorder.GetRight()) / 2;
  6166. var yCenter = (this.Frame.ChartBorder.GetTop() + this.Frame.ChartBorder.GetBottom()) / 2;
  6167. this.Canvas.textAlign = 'center';
  6168. this.Canvas.textBaseline = 'middle';
  6169. this.Canvas.fillStyle = this.TextColor;
  6170. this.Canvas.font = this.Font;
  6171. this.Canvas.fillText(this.SplashTitle, xCenter, yCenter);
  6172. }
  6173. this.HScreenDraw = function () //横屏
  6174. {
  6175. var xCenter = (this.Frame.ChartBorder.GetLeft() + this.Frame.ChartBorder.GetRight()) / 2;
  6176. var yCenter = (this.Frame.ChartBorder.GetTop() + this.Frame.ChartBorder.GetBottom()) / 2;
  6177. this.Canvas.save();
  6178. this.Canvas.translate(xCenter, yCenter);
  6179. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  6180. this.Canvas.textAlign = 'center';
  6181. this.Canvas.textBaseline = 'middle';
  6182. this.Canvas.fillStyle = this.TextColor;
  6183. this.Canvas.font = this.Font;
  6184. this.Canvas.fillText(this.SplashTitle, 0, 0);
  6185. this.Canvas.restore();
  6186. }
  6187. }
  6188. //填充背景 支持横屏
  6189. function ChartBackground()
  6190. {
  6191. this.newMethod=IChartPainting; //派生
  6192. this.newMethod();
  6193. delete this.newMethod;
  6194. this.ClassName="ChartBackground";
  6195. this.Color=null;
  6196. this.ColorAngle=0; //0 竖向 1 横向
  6197. this.IsDrawFirst = true; //面积图在K线前面画,否则回挡住K线的
  6198. this.IsHScreen=false;
  6199. this.Draw=function()
  6200. {
  6201. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  6202. if (!this.Color) return;
  6203. if (this.Color.length<=0) return;
  6204. this.IsHScreen=(this.ChartFrame.IsHScreen===true);
  6205. if (this.Color.length==2)
  6206. {
  6207. if (this.IsHScreen)
  6208. {
  6209. if (this.ColorAngle==0)
  6210. {
  6211. var ptStart={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
  6212. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  6213. }
  6214. else
  6215. {
  6216. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  6217. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
  6218. }
  6219. }
  6220. else
  6221. {
  6222. if (this.ColorAngle==0)
  6223. {
  6224. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  6225. var ptEnd={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetBottomEx() };
  6226. }
  6227. else
  6228. {
  6229. var ptStart={ X:this.ChartBorder.GetLeft(), Y:this.ChartBorder.GetTopEx() };
  6230. var ptEnd={ X:this.ChartBorder.GetRight(), Y:this.ChartBorder.GetTopEx() };
  6231. }
  6232. }
  6233. let gradient = this.Canvas.createLinearGradient(ptStart.X,ptStart.Y, ptEnd.X,ptEnd.Y);
  6234. gradient.addColorStop(0, this.Color[0]);
  6235. gradient.addColorStop(1, this.Color[1]);
  6236. this.Canvas.fillStyle=gradient;
  6237. }
  6238. else if (this.Color.length==1)
  6239. {
  6240. this.Canvas.fillStyle=this.Color[0];
  6241. }
  6242. else
  6243. {
  6244. return;
  6245. }
  6246. if (this.Name=="DRAWGBK2" || this.Name=="KLINE_BG")
  6247. {
  6248. this.DrawRegion();
  6249. return;
  6250. }
  6251. if (this.IsHScreen)
  6252. {
  6253. var left=this.ChartBorder.GetLeftEx();
  6254. var top=this.ChartBorder.GetTop();
  6255. var width=this.ChartBorder.GetWidthEx();
  6256. var height=this.ChartBorder.GetHeight();
  6257. }
  6258. else
  6259. {
  6260. var left=this.ChartBorder.GetLeft();
  6261. var top=this.ChartBorder.GetTopEx();
  6262. var width=this.ChartBorder.GetWidth();
  6263. var height=this.ChartBorder.GetHeightEx();
  6264. }
  6265. this.Canvas.fillRect(left, top,width, height);
  6266. }
  6267. this.DrawRegion=function()
  6268. {
  6269. var xPointCount=this.ChartFrame.XPointCount;
  6270. var xOffset=this.ChartBorder.GetLeft()+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  6271. var dataWidth=this.ChartFrame.DataWidth;
  6272. var distanceWidth=this.ChartFrame.DistanceWidth;
  6273. var top=this.ChartBorder.GetTopEx();
  6274. var bottom=this.ChartBorder.GetBottomEx();
  6275. if (this.IsHScreen)
  6276. {
  6277. top=this.ChartBorder.GetRightEx();
  6278. bottom=this.ChartBorder.GetLeftEx();
  6279. }
  6280. var aryPoint=[]; //点坐标
  6281. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  6282. {
  6283. var value=this.Data.Data[i];
  6284. aryPoint[i]=null;
  6285. if (!IFrameSplitOperator.IsNumber(value) || value<=0) continue;
  6286. var x=this.ChartFrame.GetXFromIndex(j);
  6287. var y=this.ChartFrame.GetYFromData(value.Value);
  6288. if (this.IsHScreen)
  6289. aryPoint[i]={ Line:{ X:bottom, Y:x }, Line2:{ X:top, Y:x } };
  6290. else
  6291. aryPoint[i]={ Line:{ X:x, Y:top }, Line2:{ X:x, Y:bottom } };
  6292. }
  6293. this.DrawBG(aryPoint);
  6294. }
  6295. this.DrawBG=function(aryPoint)
  6296. {
  6297. var dataWidth=this.ChartFrame.DataWidth;
  6298. var distanceWidth=this.ChartFrame.DistanceWidth;
  6299. var halfWidth=(distanceWidth+dataWidth)/2;
  6300. var firstPoint=true;
  6301. var pointCount=0;
  6302. var aryLine2=[];
  6303. var color=null;
  6304. for(var i in aryPoint)
  6305. {
  6306. var item=aryPoint[i];
  6307. if (!item || (color && item.Color!=color) )
  6308. {
  6309. if (pointCount>0)
  6310. {
  6311. for(var j=aryLine2.length-1; j>=0; --j)
  6312. {
  6313. var item2=aryLine2[j];
  6314. if (this.IsHScreen)
  6315. {
  6316. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y+halfWidth);
  6317. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y-halfWidth);
  6318. }
  6319. else
  6320. {
  6321. this.Canvas.lineTo(item2.Line2.X+halfWidth, item2.Line2.Y);
  6322. this.Canvas.lineTo(item2.Line2.X-halfWidth, item2.Line2.Y);
  6323. }
  6324. }
  6325. this.Canvas.closePath();
  6326. this.Canvas.fill();
  6327. }
  6328. firstPoint=true;
  6329. pointCount=0;
  6330. aryLine2=[];
  6331. color=null;
  6332. }
  6333. if (!item) continue;
  6334. if (firstPoint)
  6335. {
  6336. this.Canvas.beginPath();
  6337. if (this.IsHScreen)
  6338. {
  6339. this.Canvas.moveTo(item.Line.X, item.Line.Y-halfWidth);
  6340. this.Canvas.lineTo(item.Line.X, item.Line.Y+halfWidth);
  6341. }
  6342. else
  6343. {
  6344. this.Canvas.moveTo(item.Line.X-halfWidth, item.Line.Y);
  6345. this.Canvas.lineTo(item.Line.X+halfWidth, item.Line.Y);
  6346. }
  6347. firstPoint=false;
  6348. color=item.Color;
  6349. }
  6350. else
  6351. {
  6352. if (this.IsHScreen)
  6353. {
  6354. this.Canvas.lineTo(item.Line.X, item.Line.Y-halfWidth);
  6355. this.Canvas.lineTo(item.Line.X, item.Line.Y+halfWidth);
  6356. }
  6357. else
  6358. {
  6359. this.Canvas.lineTo(item.Line.X-halfWidth, item.Line.Y);
  6360. this.Canvas.lineTo(item.Line.X+halfWidth, item.Line.Y);
  6361. }
  6362. }
  6363. aryLine2.push(item);
  6364. ++pointCount;
  6365. }
  6366. if (pointCount>0)
  6367. {
  6368. for(var j=aryLine2.length-1; j>=0; --j)
  6369. {
  6370. var item2=aryLine2[j];
  6371. if (this.IsHScreen)
  6372. {
  6373. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y+halfWidth);
  6374. this.Canvas.lineTo(item2.Line2.X, item2.Line2.Y-halfWidth);
  6375. }
  6376. else
  6377. {
  6378. this.Canvas.lineTo(item2.Line2.X+halfWidth, item2.Line2.Y);
  6379. this.Canvas.lineTo(item2.Line2.X-halfWidth, item2.Line2.Y);
  6380. }
  6381. }
  6382. this.Canvas.closePath();
  6383. this.Canvas.fill();
  6384. }
  6385. }
  6386. this.GetMaxMin=function()
  6387. {
  6388. return { Min:null, Max:null };
  6389. }
  6390. }
  6391. //填充部分背景 支持横屏
  6392. function ChartBackgroundDiv()
  6393. {
  6394. this.newMethod=IChartPainting; //派生
  6395. this.newMethod();
  6396. delete this.newMethod;
  6397. this.ClassName="ChartBackgroundDiv";
  6398. this.AryColor;
  6399. this.ColorType=0;
  6400. this.Draw=function()
  6401. {
  6402. if (!this.IsShow || this.ChartFrame.IsMinSize) return;
  6403. if (!IFrameSplitOperator.IsNonEmptyArray(this.AryColor)) return;
  6404. if (!this.Data || !this.Data.Data) return;
  6405. var bHScreen=(this.ChartFrame.IsHScreen===true);
  6406. var dataWidth=this.ChartFrame.DataWidth;
  6407. var distanceWidth=this.ChartFrame.DistanceWidth;
  6408. var xPointCount=this.ChartFrame.XPointCount;
  6409. var border,xOffset, chartright, yTop, yBottom;
  6410. if (bHScreen)
  6411. {
  6412. border=this.ChartBorder.GetHScreenBorder();
  6413. xOffset=border.TopEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  6414. chartright=border.BottomEx;
  6415. yTop=border.LeftEx;
  6416. yBottom=border.RightEx;
  6417. }
  6418. else
  6419. {
  6420. border=this.ChartBorder.GetBorder();
  6421. xOffset=border.LeftEx+distanceWidth/2.0+g_JSChartResource.FrameLeftMargin;
  6422. chartright=border.RightEx;
  6423. yTop=border.TopEx;
  6424. yBottom=border.BottomEx;
  6425. }
  6426. var rtBG=null //{ Left:null, Top:null, Right:null, Bottom:null };
  6427. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j,xOffset+=(dataWidth+distanceWidth))
  6428. {
  6429. var item=this.Data.Data[i];
  6430. var left=xOffset;
  6431. var right=xOffset+dataWidth;
  6432. if (right>chartright) break;
  6433. if (!item)
  6434. {
  6435. if (rtBG) this.DrawDiv(rtBG,bHScreen);
  6436. rtBG=null;
  6437. }
  6438. else
  6439. {
  6440. var y=yTop;
  6441. var y2=yBottom;
  6442. if (IFrameSplitOperator.IsNonEmptyArray(item.AryValue))
  6443. {
  6444. var value=this.ChartFrame.GetYFromData(item.AryValue[0]);
  6445. var value2=this.ChartFrame.GetYFromData(item.AryValue[1]);
  6446. y=Math.min(value, value2);
  6447. y2=Math.max(value, value2);
  6448. }
  6449. if (bHScreen)
  6450. {
  6451. if (!rtBG)
  6452. {
  6453. rtBG={ Left:y, Right:y2, Top:left, Bottom:right };
  6454. }
  6455. else
  6456. {
  6457. rtBG.Bottom=right;
  6458. if (rtBG.Left>y) rtBG.Left=y;
  6459. if (rtBG.Right<y2) rtBG.Right=y2;
  6460. }
  6461. }
  6462. else
  6463. {
  6464. if (!rtBG)
  6465. {
  6466. rtBG={ Left:left, Right:right, Top:y, Bottom:y2 };
  6467. }
  6468. else
  6469. {
  6470. rtBG.Right=right;
  6471. if (rtBG.Top>y) rtBG.Top=y;
  6472. if (rtBG.Bottom<y2) rtBG.Bottom=y2;
  6473. }
  6474. }
  6475. }
  6476. }
  6477. }
  6478. this.DrawDiv=function(rtBG, bHScreen)
  6479. {
  6480. if (this.ColorType==2) //2=用COLOR1画框线
  6481. {
  6482. this.Canvas.strokeStyle = this.AryColor[0];
  6483. this.Canvas.strokeRect(ToFixedPoint(rtBG.Left),ToFixedPoint(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
  6484. }
  6485. else if (this.ColorType==3) //3=用COLOR1画框线,用COLOR2填充
  6486. {
  6487. this.Canvas.fillStyle=this.AryColor[1];
  6488. this.Canvas.fillRect(ToFixedRect(rtBG.Left),ToFixedRect(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
  6489. this.Canvas.strokeStyle = this.AryColor[0];
  6490. this.Canvas.strokeRect(ToFixedPoint(rtBG.Left),ToFixedPoint(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
  6491. }
  6492. else if (this.ColorType==0 || this.ColorType==1) //0=上下渐进 1=左右渐进
  6493. {
  6494. var gradient=null;
  6495. if (bHScreen)
  6496. {
  6497. if (this.ColorType==0)
  6498. gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Right,rtBG.Top);
  6499. else
  6500. gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Left,rtBG.Bottom);
  6501. }
  6502. else
  6503. {
  6504. if (this.ColorType==0)
  6505. gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Left,rtBG.Bottom);
  6506. else
  6507. gradient = this.Canvas.createLinearGradient(rtBG.Left,rtBG.Top, rtBG.Right,rtBG.Top);
  6508. }
  6509. gradient.addColorStop(0.5, this.AryColor[0]);
  6510. gradient.addColorStop(1, this.AryColor[1]);
  6511. this.Canvas.fillStyle=gradient;
  6512. this.Canvas.fillRect(ToFixedRect(rtBG.Left),ToFixedRect(rtBG.Top),ToFixedRect(rtBG.Right-rtBG.Left),ToFixedRect(rtBG.Bottom-rtBG.Top));
  6513. }
  6514. else
  6515. {
  6516. return;
  6517. }
  6518. }
  6519. }
  6520. //锁 支持横屏
  6521. function ChartLock()
  6522. {
  6523. this.newMethod = IChartPainting; //派生
  6524. this.newMethod();
  6525. delete this.newMethod;
  6526. this.WidthDiv = 0.2; // 框子宽度占比
  6527. this.LockCount = 10; // 锁最新的几个数据
  6528. this.BGColor = g_JSChartResource.LockBGColor;
  6529. this.TextColor = g_JSChartResource.LockTextColor;
  6530. this.Font = g_JSChartResource.DefaultTextFont;
  6531. this.Title = '🔒开通权限';
  6532. this.LockRect = null; //上锁区域
  6533. this.LockID; //锁ID
  6534. this.Callback; //回调
  6535. this.IndexName; //指标名字
  6536. this.Draw = function ()
  6537. {
  6538. this.LockRect = null;
  6539. if (this.ChartFrame.IsMinSize) return;
  6540. if (this.NotSupportMessage)
  6541. {
  6542. this.DrawNotSupportmessage();
  6543. return;
  6544. }
  6545. if (this.ChartFrame.IsHScreen === true)
  6546. {
  6547. this.HScreenDraw();
  6548. return;
  6549. }
  6550. var xOffset = this.ChartBorder.GetRight();
  6551. var lOffsetWidth = 0;
  6552. if (this.ChartFrame.Data != null)
  6553. {
  6554. var dataWidth = this.ChartFrame.DataWidth;
  6555. var distanceWidth = this.ChartFrame.DistanceWidth;
  6556. xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  6557. var chartright = this.ChartBorder.GetRight();
  6558. var xPointCount = this.ChartFrame.XPointCount;
  6559. for (var i = this.ChartFrame.Data.DataOffset, j = 0; i < this.ChartFrame.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  6560. {
  6561. var data = this.ChartFrame.Data.Data[i];
  6562. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  6563. var left = xOffset;
  6564. var right = xOffset + dataWidth;
  6565. if (right > chartright) break;
  6566. }
  6567. lOffsetWidth = (dataWidth + distanceWidth) * this.LockCount;
  6568. }
  6569. if (lOffsetWidth == 0)
  6570. {
  6571. lOffsetWidth = (xOffset - this.ChartBorder.GetLeft()) * this.WidthDiv;
  6572. }
  6573. var lLeft = xOffset - lOffsetWidth;
  6574. if (lLeft < this.ChartBorder.GetLeft())
  6575. lLeft = this.ChartBorder.GetLeft();
  6576. var lHeight = this.ChartBorder.GetBottom() - this.ChartBorder.GetTop();
  6577. var lWidth = this.ChartBorder.GetRight() - lLeft;
  6578. this.Canvas.fillStyle = this.BGColor;
  6579. this.Canvas.fillRect(lLeft, this.ChartBorder.GetTop(), lWidth, lHeight);
  6580. var xCenter = lLeft + lWidth / 2;
  6581. var yCenter = this.ChartBorder.GetTop() + lHeight / 2;
  6582. this.Canvas.textAlign = 'center';
  6583. this.Canvas.textBaseline = 'middle';
  6584. this.Canvas.fillStyle = this.TextColor;
  6585. this.Canvas.font = this.Font;
  6586. this.Canvas.fillText(this.Title, xCenter, yCenter);
  6587. this.LockRect = { Left: lLeft, Top: this.ChartBorder.GetTop(), Width: lWidth, Heigh: lHeight }; //保存上锁区域
  6588. }
  6589. this.HScreenDraw = function ()
  6590. {
  6591. var xOffset = this.ChartBorder.GetBottom();
  6592. var lOffsetWidth = 0;
  6593. if (this.ChartFrame.Data != null)
  6594. {
  6595. var dataWidth = this.ChartFrame.DataWidth;
  6596. var distanceWidth = this.ChartFrame.DistanceWidth;
  6597. xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  6598. var chartright = this.ChartBorder.GetBottom();
  6599. var xPointCount = this.ChartFrame.XPointCount;
  6600. //求最后1个数据的位置
  6601. for (var i = this.ChartFrame.Data.DataOffset, j = 0; i < this.ChartFrame.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  6602. {
  6603. var data = this.ChartFrame.Data.Data[i];
  6604. if (data.Open == null || data.High == null || data.Low == null || data.Close == null) continue;
  6605. var left = xOffset;
  6606. var right = xOffset + dataWidth;
  6607. if (right > chartright) break;
  6608. }
  6609. lOffsetWidth = (dataWidth + distanceWidth) * this.LockCount;
  6610. }
  6611. if (lOffsetWidth == 0)
  6612. {
  6613. lOffsetWidth = (xOffset - this.ChartBorder.GetTop()) * this.WidthDiv;
  6614. }
  6615. var lLeft = xOffset - lOffsetWidth;
  6616. if (lLeft < this.ChartBorder.GetTop()) lLeft = this.ChartBorder.GetTop();
  6617. var lHeight = this.ChartBorder.GetRight() - this.ChartBorder.GetLeft();
  6618. var lWidth = this.ChartBorder.GetBottom() - lLeft;
  6619. this.Canvas.fillStyle = this.BGColor;
  6620. this.Canvas.fillRect(this.ChartBorder.GetLeft(), lLeft, lHeight, lWidth);
  6621. var xCenter = this.ChartBorder.GetLeft() + lHeight / 2;
  6622. var yCenter = lLeft + lWidth / 2;
  6623. this.Canvas.save();
  6624. this.Canvas.translate(xCenter, yCenter);
  6625. this.Canvas.rotate(90 * Math.PI / 180);
  6626. this.Canvas.textAlign = 'center';
  6627. this.Canvas.textBaseline = 'middle';
  6628. this.Canvas.fillStyle = this.TextColor;
  6629. this.Canvas.font = this.Font;
  6630. this.Canvas.fillText(this.Title, 0, 0);
  6631. this.Canvas.restore();
  6632. this.LockRect = { Left: this.ChartBorder.GetLeft(), Top: lLeft, Width: lHeight, Heigh: lWidth }; //保存上锁区域
  6633. }
  6634. //x,y是否在上锁区域
  6635. this.GetTooltipData = function (x, y, tooltip)
  6636. {
  6637. if (this.LockRect == null) return false;
  6638. if (this.IsPointInRect(x, y, this.LockRect.Left, this.LockRect.Top, this.LockRect.Width, this.LockRect.Heigh))
  6639. {
  6640. tooltip.Data = { ID: this.LockID, Callback: this.Callback, IndexName: this.IndexName };
  6641. tooltip.ChartPaint = this;
  6642. return true;
  6643. }
  6644. return false;
  6645. }
  6646. this.IsPointInRect = function (x, y, left, top, width, heigh)
  6647. {
  6648. if (x > left && x < left + width && y > top && y < top + heigh) return true;
  6649. return false;
  6650. }
  6651. }
  6652. //通达信语法 VOLSTICK 支持横屏
  6653. function ChartVolStick()
  6654. {
  6655. this.newMethod = IChartPainting; //派生
  6656. this.newMethod();
  6657. delete this.newMethod;
  6658. this.UpColor = g_JSChartResource.UpBarColor;
  6659. this.DownColor = g_JSChartResource.DownBarColor;
  6660. this.HistoryData; //历史数据
  6661. this.KLineDrawType = 0;
  6662. this.BarType; //柱子状态 1=实心 0=空心 2=涨实跌空 如果设置了这个属性, 属性KLineDrawType无效
  6663. this.ClassName = 'ChartVolStick';
  6664. this.MinBarWidth=g_JSChartResource.MinKLineBarWidth; //最小的柱子宽度
  6665. this.Draw = function ()
  6666. {
  6667. if (!this.IsShow || this.ChartFrame.IsMinSize || !this.IsVisible) return;
  6668. if (this.IsHideScriptIndex()) return;
  6669. if (this.ChartFrame.IsHScreen === true)
  6670. {
  6671. this.HScreenDraw();
  6672. return;
  6673. }
  6674. var dataWidth = this.ChartFrame.DataWidth;
  6675. var distanceWidth = this.ChartFrame.DistanceWidth;
  6676. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  6677. var chartright = this.ChartBorder.GetRight();
  6678. var xPointCount = this.ChartFrame.XPointCount;
  6679. var yBottom = this.ChartFrame.GetYFromData(0);
  6680. var isMinute=this.IsMinuteFrame();
  6681. this.Canvas.save();
  6682. if (dataWidth >= this.MinBarWidth)
  6683. { //只有K线, 分时图dataWidth=1
  6684. yBottom = ToFixedRect(yBottom);
  6685. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  6686. {
  6687. var value = this.Data.Data[i];
  6688. var kItem = this.HistoryData.Data[i];
  6689. if (value == null || kItem == null) continue;
  6690. var left = xOffset;
  6691. var right = xOffset + dataWidth;
  6692. if (right > chartright) break;
  6693. var y = this.ChartFrame.GetYFromData(value);
  6694. var barColor=this.GetBarColor(kItem);
  6695. var bUp = barColor.IsUp;
  6696. //高度调整为整数
  6697. var height = ToFixedRect(Math.abs(yBottom - y)>=1 ? yBottom - y : 1);
  6698. y = yBottom - height;
  6699. var bSolidBar=this.IsSolidBar(bUp); //实心柱子
  6700. if (bSolidBar)
  6701. {
  6702. this.Canvas.fillStyle=barColor.Color;
  6703. this.Canvas.fillRect(ToFixedRect(left), y, ToFixedRect(dataWidth), height);
  6704. }
  6705. else
  6706. {
  6707. this.Canvas.strokeStyle=barColor.Color;
  6708. this.Canvas.beginPath();
  6709. this.Canvas.rect(ToFixedPoint(left), ToFixedPoint(y), ToFixedRect(dataWidth), height);
  6710. this.Canvas.stroke();
  6711. }
  6712. }
  6713. }
  6714. else //太细了直接话线
  6715. {
  6716. var preKItem=null;
  6717. var barColor=null;
  6718. this.Canvas.lineWidth=1;
  6719. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  6720. {
  6721. var value = this.Data.Data[i];
  6722. var kItem = this.HistoryData.Data[i];
  6723. if (value == null || kItem == null) continue;
  6724. var y = this.ChartFrame.GetYFromData(value);
  6725. if (isMinute)
  6726. {
  6727. var x=this.ChartFrame.GetXFromIndex(j);
  6728. }
  6729. else
  6730. {
  6731. var left=xOffset;
  6732. var right=xOffset+dataWidth;
  6733. var x=left+(right-left)/2;
  6734. }
  6735. if (x > chartright) break;
  6736. if (isMinute) barColor=this.GetMinuteBarColor(kItem,preKItem); //分时图颜色单独计算
  6737. else barColor=this.GetBarColor(kItem);
  6738. this.Canvas.strokeStyle=barColor.Color;
  6739. //var x = this.ChartFrame.GetXFromIndex(j);
  6740. this.Canvas.beginPath();
  6741. this.Canvas.moveTo(ToFixedPoint(x), y);
  6742. this.Canvas.lineTo(ToFixedPoint(x), yBottom);
  6743. this.Canvas.stroke();
  6744. preKItem=kItem;
  6745. }
  6746. }
  6747. this.Canvas.restore();
  6748. }
  6749. this.GetBarColor=function(kItem)
  6750. {
  6751. if (kItem.Close>=kItem.Open) return { Color:this.UpColor, IsUp:true }; //颜色, 是否是上涨
  6752. else return { Color:this.DownColor, IsUp:false };
  6753. }
  6754. this.GetMinuteBarColor=function(kItem, preItem)
  6755. {
  6756. var prePrice=kItem.YClose;
  6757. if (preItem) prePrice=preItem.Close;
  6758. if (kItem.Close>=prePrice) return { Color:this.UpColor, IsUp:true }; //颜色, 是否是上涨
  6759. else return { Color:this.DownColor, IsUp:false };
  6760. }
  6761. //true=实心 false=空心
  6762. this.IsSolidBar=function(bUp)
  6763. {
  6764. var bSolidBar=true; //实心柱子
  6765. if (this.BarType===0 || this.BarType===1 || this.BarType===2)
  6766. {
  6767. if (this.BarType===0) //空心
  6768. bSolidBar=false;
  6769. else if (this.BarType===2) //涨实跌空
  6770. bSolidBar=bUp;
  6771. }
  6772. else
  6773. {
  6774. if (this.KLineDrawType==6) //完全空心柱
  6775. bSolidBar=false;
  6776. else if (bUp && (this.KLineDrawType==1 || this.KLineDrawType==2 || this.KLineDrawType==3)) //空心柱子
  6777. bSolidBar=false;
  6778. }
  6779. return bSolidBar;
  6780. }
  6781. this.HScreenDraw = function () //横屏画法
  6782. {
  6783. var dataWidth = this.ChartFrame.DataWidth;
  6784. var distanceWidth = this.ChartFrame.DistanceWidth;
  6785. var xOffset = this.ChartBorder.GetTop() + distanceWidth / 2.0 + 2.0;
  6786. var chartBottom = this.ChartBorder.GetBottom();
  6787. var xPointCount = this.ChartFrame.XPointCount;
  6788. var isMinute=this.IsMinuteFrame();
  6789. var yBottom = this.ChartFrame.GetYFromData(0);
  6790. if (dataWidth >= this.MinBarWidth)
  6791. {
  6792. yBottom = ToFixedRect(yBottom);
  6793. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  6794. {
  6795. var value = this.Data.Data[i];
  6796. var kItem = this.HistoryData.Data[i];
  6797. if (value == null || kItem == null) continue;
  6798. var left = xOffset;
  6799. var right = xOffset + dataWidth;
  6800. if (right > chartBottom) break;
  6801. var y = this.ChartFrame.GetYFromData(value);
  6802. var barColor=this.GetBarColor(kItem);
  6803. var bUp=barColor.IsUp;
  6804. //高度调整为整数
  6805. var height = ToFixedRect(y - yBottom);
  6806. var bSolidBar=this.IsSolidBar(bUp); //实心柱子
  6807. if (bSolidBar)
  6808. {
  6809. this.Canvas.fillStyle=barColor.Color;
  6810. this.Canvas.fillRect(yBottom, ToFixedRect(left), height, ToFixedRect(dataWidth));
  6811. }
  6812. else
  6813. {
  6814. this.Canvas.strokeStyle=barColor.Color;
  6815. this.Canvas.beginPath();
  6816. this.Canvas.rect(ToFixedPoint(yBottom), ToFixedPoint(left), height, ToFixedRect(dataWidth));
  6817. this.Canvas.stroke();
  6818. }
  6819. }
  6820. }
  6821. else //太细了直接话线
  6822. {
  6823. var preKItem=null;
  6824. var barColor=null;
  6825. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  6826. {
  6827. var value = this.Data.Data[i];
  6828. var kItem = this.HistoryData.Data[i];
  6829. if (value == null || kItem == null) continue;
  6830. var y = this.ChartFrame.GetYFromData(value);
  6831. if (isMinute)
  6832. {
  6833. var x=this.ChartFrame.GetXFromIndex(j);
  6834. }
  6835. else
  6836. {
  6837. var left=xOffset;
  6838. var right=xOffset+dataWidth;
  6839. var x=left+(right-left)/2;
  6840. }
  6841. if (x > chartBottom) break;
  6842. if (isMinute) barColor=this.GetMinuteBarColor(kItem,preKItem); //分时图颜色单独计算
  6843. else barColor=this.GetBarColor(kItem);
  6844. this.Canvas.strokeStyle=barColor.Color;
  6845. //var x = this.ChartFrame.GetXFromIndex(j);
  6846. this.Canvas.beginPath();
  6847. this.Canvas.moveTo(y, ToFixedPoint(x));
  6848. this.Canvas.lineTo(yBottom, ToFixedPoint(x));
  6849. this.Canvas.stroke();
  6850. preKItem=kItem;
  6851. }
  6852. }
  6853. }
  6854. this.GetMaxMin = function ()
  6855. {
  6856. var xPointCount = this.ChartFrame.XPointCount;
  6857. var range = { Min:null, Max:null };
  6858. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  6859. {
  6860. var value = this.Data.Data[i];
  6861. if (!IFrameSplitOperator.IsNumber(range.Max) || range.Max<value) range.Max=value;
  6862. if (!IFrameSplitOperator.IsNumber(range.Min) || range.Min>value) range.Min=value
  6863. }
  6864. if (range.Max>0 && range.Min>0) range.Min=0;
  6865. else if (range.Max<0 && range.Min<0) range.Max=0;
  6866. return range;
  6867. }
  6868. }
  6869. function ChartText()
  6870. {
  6871. this.newMethod = IChartPainting; //派生
  6872. this.newMethod();
  6873. delete this.newMethod;
  6874. this.TextFont = "14px 微软雅黑";
  6875. this.Draw = function ()
  6876. {
  6877. if (this.ChartFrame.IsMinSize) return;
  6878. if (this.NotSupportMessage)
  6879. {
  6880. this.DrawNotSupportmessage();
  6881. return;
  6882. }
  6883. if (!this.Data || !this.Data.Data) return;
  6884. var dataWidth = this.ChartFrame.DataWidth;
  6885. var distanceWidth = this.ChartFrame.DistanceWidth;
  6886. var chartright = this.ChartBorder.GetRight();
  6887. var xPointCount = this.ChartFrame.XPointCount;
  6888. for (var i in this.Data.Data)
  6889. {
  6890. var value = this.Data.Data[i];
  6891. if (value == null) continue;
  6892. var price = value.Value;
  6893. var position = value.Position;
  6894. if (position == 'Left') {
  6895. var x = this.ChartFrame.GetXFromIndex(0);
  6896. var y = this.ChartFrame.GetYFromData(price);
  6897. if (x > chartright) continue;
  6898. this.Canvas.textAlign = 'left';
  6899. this.Canvas.textBaseline = 'middle';
  6900. this.Canvas.fillStyle = value.Color;
  6901. this.Canvas.font = this.TextFont;
  6902. this.Canvas.fillText(value.Message, x, y);
  6903. }
  6904. }
  6905. }
  6906. this.GetMaxMin = function ()
  6907. {
  6908. var xPointCount = this.ChartFrame.XPointCount;
  6909. var range = {};
  6910. range.Min = null;
  6911. range.Max = null;
  6912. if (!this.Data || !this.Data.Data) return range;
  6913. for (var i in this.Data.Data)
  6914. {
  6915. var data = this.Data.Data[i];
  6916. if (data == null || isNaN(data.Value)) continue;
  6917. var value = data.Value;
  6918. if (range.Max == null) range.Max = value;
  6919. if (range.Min == null) range.Min = value;
  6920. if (range.Max < value) range.Max = value;
  6921. if (range.Min > value) range.Min = value;
  6922. }
  6923. return range;
  6924. }
  6925. }
  6926. /* 1
  6927. Data 数据结构
  6928. Value, Value2 区间最大最小值
  6929. Color=面积的颜色
  6930. Title=标题 TitleColor=标题颜色
  6931. 支持横屏
  6932. */
  6933. function ChartStraightArea()
  6934. {
  6935. this.newMethod = IChartPainting; //派生
  6936. this.newMethod();
  6937. delete this.newMethod;
  6938. this.Color = "rgb(255,193,37)"; //线段颜色
  6939. this.Font = '11px 微软雅黑';
  6940. this.Draw = function ()
  6941. {
  6942. if (this.ChartFrame.IsMinSize) return;
  6943. if (this.NotSupportMessage)
  6944. {
  6945. this.DrawNotSupportmessage();
  6946. return;
  6947. }
  6948. if (!this.Data || !this.Data.Data) return;
  6949. if (this.ChartFrame.IsHScreen === true)
  6950. {
  6951. this.HScreenDraw();
  6952. return;
  6953. }
  6954. var dataWidth = this.ChartFrame.DataWidth;
  6955. var distanceWidth = this.ChartFrame.DistanceWidth;
  6956. var chartright = this.ChartBorder.GetRight();
  6957. var bottom = this.ChartBorder.GetBottom();
  6958. var left = this.ChartBorder.GetLeft();
  6959. var xPointCount = this.ChartFrame.XPointCount;
  6960. var xRight = this.ChartFrame.GetXFromIndex(xPointCount - 1);
  6961. //画背景
  6962. for (let i in this.Data.Data)
  6963. {
  6964. let item = this.Data.Data[i];
  6965. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  6966. if (item.Color == null) continue;
  6967. let valueMax = Math.max(item.Value, item.Value2);
  6968. let valueMin = Math.min(item.Value, item.Value2);
  6969. let yTop = this.ChartFrame.GetYFromData(valueMax);
  6970. let yBottom = this.ChartFrame.GetYFromData(valueMin);
  6971. this.Canvas.fillStyle = item.Color;
  6972. this.Canvas.fillRect(ToFixedRect(left), ToFixedRect(yTop), ToFixedRect(xRight - left), ToFixedRect(yBottom - yTop));
  6973. }
  6974. for (let i in this.Data.Data)
  6975. {
  6976. let item = this.Data.Data[i];
  6977. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  6978. if (item.Color == null) continue;
  6979. let valueMax = Math.max(item.Value, item.Value2);
  6980. let valueMin = Math.min(item.Value, item.Value2);
  6981. let yTop = this.ChartFrame.GetYFromData(valueMax);
  6982. let yBottom = this.ChartFrame.GetYFromData(valueMin);
  6983. if (item.Title && item.TitleColor)
  6984. {
  6985. let x = xRight;
  6986. if (item.Align == 'left')
  6987. {
  6988. this.Canvas.textAlign = 'left';
  6989. x = left;
  6990. }
  6991. else
  6992. {
  6993. this.Canvas.textAlign = 'right';
  6994. x = xRight;
  6995. }
  6996. this.Canvas.textBaseline = 'middle';
  6997. this.Canvas.fillStyle = item.TitleColor;
  6998. this.Canvas.font = this.Font;
  6999. let y = yTop + (yBottom - yTop) / 2;
  7000. this.Canvas.fillText(item.Title, x, y);
  7001. }
  7002. }
  7003. }
  7004. this.HScreenDraw = function ()
  7005. {
  7006. var bottom = this.ChartBorder.GetBottom();
  7007. var top = this.ChartBorder.GetTop();
  7008. var height = this.ChartBorder.GetHeight();
  7009. for (let i in this.Data.Data)
  7010. {
  7011. let item = this.Data.Data[i];
  7012. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  7013. if (item.Color == null) continue;
  7014. let valueMax = Math.max(item.Value, item.Value2);
  7015. let valueMin = Math.min(item.Value, item.Value2);
  7016. var yTop = this.ChartFrame.GetYFromData(valueMax);
  7017. var yBottom = this.ChartFrame.GetYFromData(valueMin);
  7018. this.Canvas.fillStyle = item.Color;
  7019. this.Canvas.fillRect(ToFixedRect(yBottom), ToFixedRect(top), ToFixedRect(yTop - yBottom), ToFixedRect(height));
  7020. if (item.Title && item.TitleColor)
  7021. {
  7022. var xText = yTop + (yBottom - yTop) / 2;
  7023. var yText = bottom;
  7024. this.Canvas.save();
  7025. this.Canvas.translate(xText, yText);
  7026. this.Canvas.rotate(90 * Math.PI / 180);
  7027. this.Canvas.textAlign = 'right';
  7028. this.Canvas.textBaseline = 'middle';
  7029. this.Canvas.fillStyle = item.TitleColor;
  7030. this.Canvas.font = this.Font;
  7031. this.Canvas.fillText(item.Title, 0, -2);
  7032. this.Canvas.restore();
  7033. }
  7034. }
  7035. }
  7036. this.GetMaxMin = function ()
  7037. {
  7038. var xPointCount = this.ChartFrame.XPointCount;
  7039. var range = {};
  7040. range.Min = null;
  7041. range.Max = null;
  7042. if (!this.Data || !this.Data.Data) return range;
  7043. for (let i in this.Data.Data)
  7044. {
  7045. let item = this.Data.Data[i];
  7046. if (item == null || isNaN(item.Value) || isNaN(item.Value2)) continue;
  7047. let valueMax = Math.max(item.Value, item.Value2);
  7048. let valueMin = Math.min(item.Value, item.Value2);
  7049. if (range.Max == null) range.Max = valueMax;
  7050. if (range.Min == null) range.Min = valueMin;
  7051. if (range.Max < valueMax) range.Max = valueMax;
  7052. if (range.Min > valueMin) range.Min = valueMin;
  7053. }
  7054. return range;
  7055. }
  7056. }
  7057. // DRAWBAND 面积图 支持横屏
  7058. function ChartBand()
  7059. {
  7060. this.newMethod = IChartPainting; //派生
  7061. this.newMethod();
  7062. delete this.newMethod;
  7063. this.IsDrawFirst = true;
  7064. this.ClassName="ChartBand";
  7065. this.FirstColor = g_JSChartResource.Index.LineColor[0];
  7066. this.SecondColor = g_JSChartResource.Index.LineColor[1];
  7067. this.Draw = function ()
  7068. {
  7069. if (this.ChartFrame.IsMinSize) return;
  7070. if (this.NotSupportMessage)
  7071. {
  7072. this.DrawNotSupportmessage();
  7073. return;
  7074. }
  7075. var isHScreen=this.ChartFrame.IsHScreen;
  7076. var dataWidth = this.ChartFrame.DataWidth;
  7077. var distanceWidth = this.ChartFrame.DistanceWidth;
  7078. var xPointCount = this.ChartFrame.XPointCount;
  7079. var xOffset = this.ChartBorder.GetLeft() + distanceWidth / 2.0 + 2.0;
  7080. var x = 0;
  7081. var y = 0;
  7082. var y2 = 0;
  7083. var firstlinePoints = [];
  7084. var secondlinePoints = [];
  7085. var lIndex = 0;
  7086. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j, xOffset += (dataWidth + distanceWidth))
  7087. {
  7088. var value = this.Data.Data[i];
  7089. if (value == null || value.Value == null || value.Value2 == null) continue;
  7090. x = this.ChartFrame.GetXFromIndex(j);
  7091. y = this.ChartFrame.GetYFromData(value.Value);
  7092. y2 = this.ChartFrame.GetYFromData(value.Value2);
  7093. if (isHScreen)
  7094. {
  7095. firstlinePoints[lIndex] = { x: y, y: x };
  7096. secondlinePoints[lIndex] = { x: y2, y: x };
  7097. }
  7098. else
  7099. {
  7100. firstlinePoints[lIndex] = { x: x, y: y };
  7101. secondlinePoints[lIndex] = { x: x, y: y2 };
  7102. }
  7103. lIndex++;
  7104. }
  7105. if (firstlinePoints.length>1 && secondlinePoints.length>1)
  7106. {
  7107. this.DrawBand(firstlinePoints, secondlinePoints);
  7108. }
  7109. }
  7110. this.ClipTop=function(aryFrist)
  7111. {
  7112. var isHScreen=this.ChartFrame.IsHScreen;
  7113. this.Canvas.beginPath();
  7114. for(var i=0;i<aryFrist.length;++i)
  7115. {
  7116. if (i == 0)
  7117. this.Canvas.moveTo(aryFrist[i].x, aryFrist[i].y);
  7118. else
  7119. this.Canvas.lineTo(aryFrist[i].x, aryFrist[i].y);
  7120. }
  7121. var ptStart=aryFrist[0];
  7122. var ptEnd=aryFrist[aryFrist.length-1];
  7123. if (isHScreen)
  7124. {
  7125. var xLeft=this.ChartBorder.GetRightEx();
  7126. this.Canvas.lineTo(xLeft, ptEnd.y);
  7127. this.Canvas.lineTo(xLeft, ptStart.y);
  7128. }
  7129. else
  7130. {
  7131. var yTop=this.ChartBorder.GetTopEx();
  7132. this.Canvas.lineTo(ptEnd.x, yTop);
  7133. this.Canvas.lineTo(ptStart.x, yTop);
  7134. }
  7135. this.Canvas.closePath();
  7136. this.Canvas.clip();
  7137. }
  7138. this.ClipBottom=function(aryFrist)
  7139. {
  7140. var isHScreen=this.ChartFrame.IsHScreen;
  7141. this.Canvas.beginPath();
  7142. for(var i=0;i<aryFrist.length;++i)
  7143. {
  7144. if (i == 0)
  7145. this.Canvas.moveTo(aryFrist[i].x, aryFrist[i].y);
  7146. else
  7147. this.Canvas.lineTo(aryFrist[i].x, aryFrist[i].y);
  7148. }
  7149. var ptStart=aryFrist[0];
  7150. var ptEnd=aryFrist[aryFrist.length-1];
  7151. if (isHScreen)
  7152. {
  7153. var xLeft=this.ChartBorder.GetLeftEx();
  7154. this.Canvas.lineTo(xLeft, ptEnd.y);
  7155. this.Canvas.lineTo(xLeft, ptStart.y);
  7156. }
  7157. else
  7158. {
  7159. var yBottom=this.ChartBorder.GetBottomEx();
  7160. this.Canvas.lineTo(ptEnd.x, yBottom);
  7161. this.Canvas.lineTo(ptStart.x, yBottom);
  7162. }
  7163. this.Canvas.closePath();
  7164. //this.Canvas.fillStyle = "rgb(255,0,0)";
  7165. //this.Canvas.fill();
  7166. this.Canvas.clip();
  7167. }
  7168. this.DrawArea=function(aryFrist, arySecond, clrArea)
  7169. {
  7170. this.Canvas.beginPath();
  7171. for(var i=0;i<aryFrist.length;++i)
  7172. {
  7173. if (i == 0)
  7174. this.Canvas.moveTo(aryFrist[i].x, aryFrist[i].y);
  7175. else
  7176. this.Canvas.lineTo(aryFrist[i].x, aryFrist[i].y);
  7177. }
  7178. for (var i = arySecond.length-1; i >= 0; --i)
  7179. {
  7180. this.Canvas.lineTo(arySecond[i].x, arySecond[i].y);
  7181. }
  7182. this.Canvas.closePath();
  7183. this.Canvas.fillStyle = clrArea;
  7184. this.Canvas.fill();
  7185. }
  7186. this.DrawBand=function(aryFrist, arySecond)
  7187. {
  7188. if (this.FirstColor)
  7189. {
  7190. this.Canvas.save();
  7191. this.ClipTop(aryFrist);
  7192. this.DrawArea(aryFrist, arySecond, this.FirstColor);
  7193. this.Canvas.restore();
  7194. }
  7195. if (this.SecondColor)
  7196. {
  7197. this.Canvas.save();
  7198. this.ClipBottom(aryFrist);
  7199. this.DrawArea(aryFrist, arySecond, this.SecondColor);
  7200. this.Canvas.restore();
  7201. }
  7202. }
  7203. this.GetMaxMin = function ()
  7204. {
  7205. var xPointCount = this.ChartFrame.XPointCount;
  7206. var range = {};
  7207. range.Min = null;
  7208. range.Max = null;
  7209. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  7210. {
  7211. var value = this.Data.Data[i];
  7212. if (value == null || value.Value == null || value.Value2 == null) continue;
  7213. var maxData = value.Value > value.Value2 ? value.Value : value.Value2;
  7214. var minData = value.Value < value.Value2 ? value.Value : value.Value2;
  7215. if (range.Max == null)
  7216. range.Max = maxData;
  7217. else if (range.Max < maxData)
  7218. range.Max = maxData;
  7219. if (range.Min == null)
  7220. range.Min = minData;
  7221. else if (range.Min > minData)
  7222. range.Min = minData;
  7223. }
  7224. return range;
  7225. }
  7226. }
  7227. //分钟线叠加 支持横屏
  7228. function ChartOverlayMinutePriceLine()
  7229. {
  7230. this.newMethod = IChartPainting; //派生
  7231. this.newMethod();
  7232. delete this.newMethod;
  7233. this.Color = "rgb(65,105,225)";
  7234. this.MainData; //主图数据
  7235. this.Name = "ChartOverlayMinutePriceLine";
  7236. this.Title;
  7237. this.Symbol; //叠加的股票代码
  7238. this.YClose; //叠加的股票前收盘
  7239. this.Status=OVERLAY_STATUS_ID.STATUS_NONE_ID;
  7240. this.OverlayType=0; //叠加方式 0=百分比叠加 1=绝对叠加
  7241. this.Draw = function ()
  7242. {
  7243. if (this.NotSupportMessage)
  7244. {
  7245. this.DrawNotSupportmessage();
  7246. return;
  7247. }
  7248. var isHScreen = (this.ChartFrame.IsHScreen === true);
  7249. var dataWidth = this.ChartFrame.DataWidth;
  7250. var distanceWidth = this.ChartFrame.DistanceWidth;
  7251. var chartright = this.ChartBorder.GetRight();
  7252. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  7253. var xPointCount = this.ChartFrame.XPointCount;
  7254. var minuteCount = this.ChartFrame.MinuteCount;
  7255. var yClose=null, mainYClose=null;
  7256. var bFirstPoint = true;
  7257. var drawCount = 0, showValue=0, pointCount=0;
  7258. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  7259. {
  7260. var item=this.Data.Data[i];
  7261. if (item && IFrameSplitOperator.IsNumber(item.Close))
  7262. {
  7263. if (bFirstPoint) //百分比使用每天的昨收计算
  7264. {
  7265. yClose=item.YClose;
  7266. var minItem=this.MainData.Data[i];
  7267. mainYClose=minItem.YClose;
  7268. }
  7269. var value=item.Close;
  7270. showValue=value; //绝对叠加
  7271. if (this.OverlayType==0) showValue=value/yClose*mainYClose; //百分比
  7272. var x = this.ChartFrame.GetXFromIndex(j);
  7273. var y = this.ChartFrame.GetYFromData(showValue, false);
  7274. if (bFirstPoint)
  7275. {
  7276. this.Canvas.strokeStyle = this.Color;
  7277. this.Canvas.beginPath();
  7278. if (isHScreen) this.Canvas.moveTo(y, x);
  7279. else this.Canvas.moveTo(x, y);
  7280. bFirstPoint = false;
  7281. }
  7282. else
  7283. {
  7284. if (isHScreen) this.Canvas.lineTo(y, x);
  7285. else this.Canvas.lineTo(x, y);
  7286. }
  7287. ++drawCount;
  7288. }
  7289. ++pointCount;
  7290. if (pointCount>=minuteCount) //上一天的数据和这天地数据线段要断开
  7291. {
  7292. bFirstPoint=true;
  7293. pointCount=0;
  7294. if (drawCount>0) this.Canvas.stroke();
  7295. drawCount=0;
  7296. }
  7297. }
  7298. if (drawCount > 0) this.Canvas.stroke();
  7299. }
  7300. this.GetMaxMin = function ()
  7301. {
  7302. var xPointCount = this.ChartFrame.XPointCount;
  7303. var range={ Min:null, Max:null };
  7304. var minuteCount=this.ChartFrame.MinuteCount;
  7305. var yClose=null, mainYClose=null;
  7306. var bFirstPoint=true;
  7307. var pointCount=0;
  7308. for(var i=this.Data.DataOffset,j=0;i<this.Data.Data.length && j<xPointCount;++i,++j)
  7309. {
  7310. var item=this.Data.Data[i];
  7311. if (!item || !IFrameSplitOperator.IsNumber(item.Close))
  7312. {
  7313. ++pointCount;
  7314. continue;
  7315. }
  7316. if (bFirstPoint)
  7317. {
  7318. yClose=item.YClose;
  7319. var minItem=this.MainData.Data[i];
  7320. mainYClose=minItem.YClose;
  7321. bFirstPoint=false;
  7322. }
  7323. var value=item.Close;
  7324. if (this.OverlayType==0) value=value/yClose*mainYClose;
  7325. if (range.Max==null) range.Max=value;
  7326. if (range.Min==null) range.Min=value;
  7327. if (range.Max<value) range.Max=value;
  7328. if (range.Min>value) range.Min=value;
  7329. ++pointCount;
  7330. if (pointCount>=minuteCount)
  7331. {
  7332. bFirstPoint=true;
  7333. pointCount=0;
  7334. }
  7335. }
  7336. return range;
  7337. }
  7338. }
  7339. //线段 多数据(一个X点有多条Y数据) 支持横屏
  7340. function ChartLineMultiData()
  7341. {
  7342. this.newMethod = IChartPainting; //派生
  7343. this.newMethod();
  7344. delete this.newMethod;
  7345. this.Color = "rgb(255,193,37)"; //线段颜色
  7346. this.Draw = function ()
  7347. {
  7348. if (this.NotSupportMessage)
  7349. {
  7350. this.DrawNotSupportmessage();
  7351. return;
  7352. }
  7353. if (!this.Data || !this.Data.Data) return;
  7354. var isHScreen = (this.ChartFrame.IsHScreen === true);
  7355. var dataWidth = this.ChartFrame.DataWidth;
  7356. var distanceWidth = this.ChartFrame.DistanceWidth;
  7357. var chartright = this.ChartBorder.GetRight();
  7358. if (isHScreen) chartright = this.ChartBorder.GetBottom();
  7359. var xPointCount = this.ChartFrame.XPointCount;
  7360. var bFirstPoint = true;
  7361. var drawCount = 0;
  7362. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  7363. {
  7364. var aryValue = this.Data.Data[i];
  7365. if (aryValue == null) continue;
  7366. var x = this.ChartFrame.GetXFromIndex(j);
  7367. if (x > chartright) break;
  7368. for (var index in aryValue)
  7369. {
  7370. var value = aryValue[index].Value;
  7371. var y = this.ChartFrame.GetYFromData(value);
  7372. if (bFirstPoint)
  7373. {
  7374. this.Canvas.strokeStyle = this.Color;
  7375. this.Canvas.beginPath();
  7376. if (isHScreen) this.Canvas.moveTo(y, x);
  7377. else this.Canvas.moveTo(x, y);
  7378. bFirstPoint = false;
  7379. }
  7380. else
  7381. {
  7382. if (isHScreen) this.Canvas.lineTo(y, x);
  7383. else this.Canvas.lineTo(x, y);
  7384. }
  7385. ++drawCount;
  7386. }
  7387. }
  7388. if (drawCount > 0) this.Canvas.stroke();
  7389. }
  7390. this.GetMaxMin = function ()
  7391. {
  7392. var xPointCount = this.ChartFrame.XPointCount;
  7393. var range = {};
  7394. range.Min = null;
  7395. range.Max = null;
  7396. if (!this.Data || !this.Data.Data) return range;
  7397. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  7398. {
  7399. var aryValue = this.Data.Data[i];
  7400. if (aryValue == null) continue;
  7401. for (var index in aryValue)
  7402. {
  7403. var value = aryValue[index].Value;
  7404. if (range.Max == null) range.Max = value;
  7405. if (range.Min == null) range.Min = value;
  7406. if (range.Max < value) range.Max = value;
  7407. if (range.Min > value) range.Min = value;
  7408. }
  7409. }
  7410. return range;
  7411. }
  7412. }
  7413. //直线 水平直线 只有1个数据 支持横屏
  7414. function ChartStraightLine()
  7415. {
  7416. this.newMethod = IChartPainting; //派生
  7417. this.newMethod();
  7418. delete this.newMethod;
  7419. this.Color = "rgb(255,193,37)"; //线段颜色
  7420. this.Draw = function ()
  7421. {
  7422. if (!this.Data || !this.Data.Data) return;
  7423. if (this.Data.Data.length != 1) return;
  7424. var isHScreen = this.ChartFrame.IsHScreen;
  7425. var dataWidth = this.ChartFrame.DataWidth;
  7426. var distanceWidth = this.ChartFrame.DistanceWidth;
  7427. var chartright = this.ChartBorder.GetRight();
  7428. if (isHScreen) chartright = this.ChartBorder.GetTop();
  7429. var xPointCount = this.ChartFrame.XPointCount;
  7430. var yValue = this.Data.Data[0];
  7431. var y = this.ChartFrame.GetYFromData(yValue);
  7432. var xLeft = this.ChartFrame.GetXFromIndex(0);
  7433. var xRight = this.ChartFrame.GetXFromIndex(xPointCount - 1);
  7434. var yFix = parseInt(y.toString()) + 0.5;
  7435. this.Canvas.beginPath();
  7436. if (isHScreen)
  7437. {
  7438. this.Canvas.moveTo(yFix, xLeft);
  7439. this.Canvas.lineTo(yFix, xRight);
  7440. }
  7441. else
  7442. {
  7443. this.Canvas.moveTo(xLeft, yFix);
  7444. this.Canvas.lineTo(xRight, yFix);
  7445. }
  7446. this.Canvas.strokeStyle = this.Color;
  7447. this.Canvas.stroke();
  7448. }
  7449. this.GetMaxMin = function ()
  7450. {
  7451. var xPointCount = this.ChartFrame.XPointCount;
  7452. var range = {};
  7453. range.Min = null;
  7454. range.Max = null;
  7455. if (!this.Data || !this.Data.Data) return range;
  7456. if (this.Data.Data.length != 1) return range;
  7457. range.Min = this.Data.Data[0];
  7458. range.Max = this.Data.Data[0];
  7459. return range;
  7460. }
  7461. }
  7462. ////////////////////////////////////////////////////////////////////////////////////////////////////
  7463. // 其他图形
  7464. //
  7465. //
  7466. ////////////////////////////////////////////////////////////////////////////////////////////////////
  7467. /*
  7468. 饼图
  7469. */
  7470. function ChartPie()
  7471. {
  7472. this.newMethod = IChartPainting; //派生
  7473. this.newMethod();
  7474. delete this.newMethod;
  7475. this.Draw = function ()
  7476. {
  7477. if (!this.Data || !this.Data.Data || !(this.Data.Data.length > 0)) return this.DrawEmptyData();
  7478. let left = this.ChartBorder.GetLeft();
  7479. let right = this.ChartBorder.GetRight();
  7480. let top = this.ChartBorder.GetTop();
  7481. let bottom = this.ChartBorder.GetBottom();
  7482. let width = this.ChartBorder.GetWidth();
  7483. let height = this.ChartBorder.GetHeight();
  7484. //圆半径
  7485. let radius = width / 4 * 0.8;
  7486. this.Canvas.save();
  7487. this.Canvas.translate(left + radius, top + height / 2);
  7488. let totalValue = 0; //求和
  7489. for (let i in this.Data.Data) {
  7490. totalValue += this.Data.Data[i].Value;
  7491. }
  7492. let startAngle = Math.PI * 1.5;
  7493. let start = startAngle;
  7494. let end = startAngle;
  7495. //画饼图
  7496. for (let i in this.Data.Data)
  7497. {
  7498. let item = this.Data.Data[i];
  7499. let rate = item.Value / totalValue; //占比
  7500. // 绘制扇形
  7501. this.Canvas.beginPath();
  7502. this.Canvas.moveTo(0, 0);
  7503. end += rate * 2 * Math.PI;//终止角度
  7504. this.Canvas.strokeStyle = "white";
  7505. this.Canvas.fillStyle = item.Color;
  7506. this.Canvas.arc(0, 0, radius, start, end);
  7507. this.Canvas.fill();
  7508. this.Canvas.closePath();
  7509. this.Canvas.stroke();
  7510. start += rate * 2 * Math.PI;//起始角度
  7511. }
  7512. //画文字
  7513. this.Canvas.restore();
  7514. let textLeft = left + width / 2 + 5;
  7515. // let textTop = top + height / 2 + 20;
  7516. let textTop = top;
  7517. this.Canvas.textBaseline = "bottom";
  7518. this.Canvas.font = "12px 微软雅黑";
  7519. for (let i = 0, j = 0; i < this.Data.Data.length; ++i)
  7520. {
  7521. let item = this.Data.Data[i];
  7522. if (!item.Text) continue;
  7523. this.Canvas.fillStyle = item.Color;
  7524. this.Canvas.fillRect(textLeft, textTop - 15, 13, 13);
  7525. this.Canvas.fillStyle = 'rgb(102,102,102)';
  7526. this.Canvas.fillText(item.Text, textLeft + 16, textTop);
  7527. // textTop += 20;
  7528. textTop += 17;
  7529. if (textTop > top + height / 2 + radius) {
  7530. ++j;
  7531. if (j >= 2) break;
  7532. // textTop = top + height / 2 + 20;
  7533. textTop = top;
  7534. textLeft = right - (width / 4) + 5;
  7535. }
  7536. }
  7537. }
  7538. //空数据
  7539. this.DrawEmptyData = function ()
  7540. {
  7541. console.log('[ChartPie::DrawEmptyData]')
  7542. let left = this.ChartBorder.GetLeft();
  7543. let right = this.ChartBorder.GetRight();
  7544. let top = this.ChartBorder.GetTop();
  7545. let bottom = this.ChartBorder.GetBottom();
  7546. let width = this.ChartBorder.GetWidth();
  7547. let height = this.ChartBorder.GetHeight();
  7548. //圆半径
  7549. let radius = width / 4 * 0.8;
  7550. this.Canvas.save();
  7551. this.Canvas.translate(left + radius, top + height / 2);
  7552. this.Canvas.beginPath();
  7553. this.Canvas.fillStyle = 'rgb(211,211,211)';
  7554. this.Canvas.strokeStyle = "white";
  7555. this.Canvas.arc(0, 0, radius * 0.8, 0, 2 * Math.PI);
  7556. this.Canvas.fill();
  7557. this.Canvas.closePath();
  7558. this.Canvas.stroke();
  7559. this.Canvas.restore();
  7560. }
  7561. }
  7562. /*
  7563. 圆环
  7564. */
  7565. function ChartCircle()
  7566. {
  7567. this.newMethod = IChartPainting; //派生
  7568. this.newMethod();
  7569. delete this.newMethod;
  7570. this.BGColor = 'white'; //背景色
  7571. this.TextHeight = 25;
  7572. //空数据
  7573. this.DrawEmptyData = function ()
  7574. {
  7575. console.log('[ChartCircle::DrawEmptyData]')
  7576. }
  7577. this.Draw = function ()
  7578. {
  7579. if (!this.Data || !this.Data.Data || !(this.Data.Data.length > 0)) return this.DrawEmptyData();
  7580. let left = this.ChartBorder.GetLeft();
  7581. let right = this.ChartBorder.GetRight();
  7582. let top = this.ChartBorder.GetTop();
  7583. let bottom = this.ChartBorder.GetBottom();
  7584. let width = this.ChartBorder.GetWidth();
  7585. let height = this.ChartBorder.GetHeight();
  7586. //圆半径
  7587. let lTextHeight = this.TextHeight;
  7588. let size = width - lTextHeight;
  7589. if (size > height - lTextHeight) size = height - lTextHeight;
  7590. let radius = (size - lTextHeight) / 2;
  7591. this.Canvas.save();
  7592. this.Canvas.translate(left + width / 2, top + height / 2 - lTextHeight / 2);
  7593. let totalValue = 0; //求和
  7594. for (let i in this.Data.Data)
  7595. {
  7596. totalValue += this.Data.Data[i].Value;
  7597. }
  7598. let startAngle = Math.PI * 1.5;
  7599. let start = startAngle;
  7600. let end = startAngle;
  7601. //画饼图
  7602. for (let i in this.Data.Data)
  7603. {
  7604. let item = this.Data.Data[i];
  7605. let rate = item.Value / totalValue; //占比
  7606. //console.log('[ChartPie::Draw]', i, rate, item);
  7607. // 绘制扇形
  7608. this.Canvas.beginPath();
  7609. this.Canvas.moveTo(0, 0);
  7610. end += rate * 2 * Math.PI;//终止角度
  7611. this.Canvas.strokeStyle = "white";
  7612. this.Canvas.fillStyle = item.Color;
  7613. this.Canvas.arc(0, 0, radius, start, end);
  7614. this.Canvas.fill();
  7615. this.Canvas.closePath();
  7616. this.Canvas.stroke();
  7617. start += rate * 2 * Math.PI;//起始角度
  7618. }
  7619. //中心画一个背景色的圆
  7620. this.Canvas.beginPath();
  7621. this.Canvas.fillStyle = this.BGColor;
  7622. this.Canvas.arc(0, 0, radius * 0.5, 0, 2 * Math.PI);
  7623. this.Canvas.fill();
  7624. this.Canvas.closePath();
  7625. this.Canvas.stroke();
  7626. this.Canvas.restore();
  7627. //画文字
  7628. this.Canvas.restore();
  7629. let textLeft = left;
  7630. let textTop = top + height / 2 - lTextHeight / 2 + radius + 5 + 20;
  7631. this.Canvas.textBaseline = "bottom";
  7632. this.Canvas.textAlign = 'left';
  7633. this.Canvas.font = "14px 微软雅黑";
  7634. let textWidth = 0;
  7635. //以圆心左右显示
  7636. for (let i = 0, j = 0; i < this.Data.Data.length; ++i)
  7637. {
  7638. let item = this.Data.Data[i];
  7639. if (!item.Text) continue;
  7640. this.Canvas.fillStyle = item.Color;
  7641. if (j % 2 == 0)
  7642. {
  7643. textLeft = left + width / 2 - 10;
  7644. textWidth = this.Canvas.measureText(item.Text).width;
  7645. textLeft = textLeft - textWidth - 16;
  7646. this.Canvas.fillRect(textLeft, textTop - 15, 13, 13);
  7647. this.Canvas.fillStyle = 'rgb(102,102,102)';
  7648. this.Canvas.fillText(item.Text, textLeft + 16, textTop);
  7649. }
  7650. else
  7651. {
  7652. textLeft = left + width / 2 + 10 + 10;
  7653. this.Canvas.fillRect(textLeft, textTop - 15, 13, 13);
  7654. this.Canvas.fillStyle = 'rgb(102,102,102)';
  7655. this.Canvas.fillText(item.Text, textLeft + 16, textTop);
  7656. textTop += 20;
  7657. }
  7658. if (textTop > bottom) break;
  7659. ++j;
  7660. }
  7661. }
  7662. }
  7663. // 中国地图
  7664. function ChartChinaMap()
  7665. {
  7666. this.newMethod = IChartPainting; //派生
  7667. this.newMethod();
  7668. delete this.newMethod;
  7669. this.ImageData = null;
  7670. this.Left;
  7671. this.Top;
  7672. this.Width;
  7673. this.Height;
  7674. this.ImageWidth;
  7675. this.ImageHeight;
  7676. this.DefaultColor = [217, 222, 239];
  7677. this.Color =
  7678. [
  7679. { Name: '海南', Color: 'rgb(217,222,223)' },
  7680. { Name: '内蒙古', Color: 'rgb(217,222,225)' },
  7681. { Name: '新疆', Color: 'rgb(217,222,226)' },
  7682. { Name: '青海', Color: 'rgb(217,222,227)' },
  7683. { Name: '西藏', Color: 'rgb(217,222,228)' },
  7684. { Name: '云南', Color: 'rgb(217,222,229)' },
  7685. { Name: '黑龙江', Color: 'rgb(217,222,230)' },
  7686. { Name: '吉林', Color: 'rgb(217,222,231)' },
  7687. { Name: '辽宁', Color: 'rgb(217,222,232)' },
  7688. { Name: '河北', Color: 'rgb(217,222,233)' },
  7689. { Name: '山东', Color: 'rgb(217,222,234)' },
  7690. { Name: '江苏', Color: 'rgb(217,222,235)' },
  7691. { Name: '浙江', Color: 'rgb(217,222,236)' },
  7692. { Name: '福建', Color: 'rgb(217,222,237)' },
  7693. { Name: '广东', Color: 'rgb(217,222,238)' },
  7694. { Name: '广西', Color: 'rgb(217,222,239)' },
  7695. { Name: '贵州', Color: 'rgb(217,222,240)' },
  7696. { Name: '湖南', Color: 'rgb(217,222,241)' },
  7697. { Name: '江西', Color: 'rgb(217,222,242)' },
  7698. { Name: '安徽', Color: 'rgb(217,222,243)' },
  7699. { Name: '湖北', Color: 'rgb(217,222,244)' },
  7700. { Name: '重庆', Color: 'rgb(217,222,245)' },
  7701. { Name: '四川', Color: 'rgb(217,222,246)' },
  7702. { Name: '甘肃', Color: 'rgb(217,222,247)' },
  7703. { Name: '陕西', Color: 'rgb(217,222,248)' },
  7704. { Name: '山西', Color: 'rgb(217,222,249)' },
  7705. { Name: '河南', Color: 'rgb(217,222,250)' }
  7706. ];
  7707. this.Draw = function ()
  7708. {
  7709. let left = this.ChartBorder.GetLeft() + 1;
  7710. let right = this.ChartBorder.GetRight() - 1;
  7711. let top = this.ChartBorder.GetTop() + 1;
  7712. let bottom = this.ChartBorder.GetBottom() - 1;
  7713. let width = this.ChartBorder.GetWidth() - 2;
  7714. let height = this.ChartBorder.GetHeight() - 2;
  7715. let imageWidth = CHINA_MAP_IMAGE.width;
  7716. let imageHeight = CHINA_MAP_IMAGE.height;
  7717. let drawImageWidth = imageWidth;
  7718. let drawImageHeight = imageHeight;
  7719. if (height < drawImageHeight || width < drawImageWidth)
  7720. {
  7721. this.ImageData = null;
  7722. return;
  7723. }
  7724. if (this.Left != left || this.Top != top || this.Width != width || this.Height != height || this.ImageWidth != imageWidth || this.ImageHeight != imageHeight)
  7725. {
  7726. this.ImageData = null;
  7727. this.ImageWidth = imageWidth;
  7728. this.ImageHeight = imageHeight;
  7729. this.Left = left;
  7730. this.Top = top;
  7731. this.Width = width;
  7732. this.Height = height;
  7733. console.log(imageWidth, imageHeight);
  7734. }
  7735. if (this.ImageData == null)
  7736. {
  7737. this.Canvas.drawImage(CHINA_MAP_IMAGE, 0, 0, imageWidth, imageHeight, left, top, drawImageWidth, drawImageHeight);
  7738. this.ImageData = this.Canvas.getImageData(left, top, drawImageWidth, drawImageHeight);
  7739. let defaultColorSet = new Set(); //默认颜色填充的色块
  7740. let colorMap = new Map(); //定义颜色填充的色块
  7741. let nameMap = new Map();
  7742. if (this.Data.length > 0)
  7743. {
  7744. for (let i in this.Data)
  7745. {
  7746. let item = this.Data[i];
  7747. nameMap.set(item.Name, item.Color)
  7748. }
  7749. }
  7750. console.log(this.Data);
  7751. for (let i in this.Color)
  7752. {
  7753. let item = this.Color[i];
  7754. if (nameMap.has(item.Name))
  7755. {
  7756. colorMap.set(item.Color, nameMap.get(item.Name));
  7757. }
  7758. else
  7759. {
  7760. defaultColorSet.add(item.Color);
  7761. }
  7762. }
  7763. var color;
  7764. for (let i = 0; i < this.ImageData.data.length; i += 4)
  7765. {
  7766. color = 'rgb(' + this.ImageData.data[i] + ',' + this.ImageData.data[i + 1] + ',' + this.ImageData.data[i + 2] + ')';
  7767. if (defaultColorSet.has(color))
  7768. {
  7769. this.ImageData.data[i] = this.DefaultColor[0];
  7770. this.ImageData.data[i + 1] = this.DefaultColor[1];
  7771. this.ImageData.data[i + 2] = this.DefaultColor[2];
  7772. }
  7773. else if (colorMap.has(color))
  7774. {
  7775. let colorValue = colorMap.get(color);
  7776. this.ImageData.data[i] = colorValue[0];
  7777. this.ImageData.data[i + 1] = colorValue[1];
  7778. this.ImageData.data[i + 2] = colorValue[2];
  7779. }
  7780. }
  7781. this.Canvas.clearRect(left, top, drawImageWidth, drawImageHeight);
  7782. this.Canvas.putImageData(this.ImageData, left, top, 0, 0, drawImageWidth, drawImageHeight);
  7783. }
  7784. else
  7785. {
  7786. this.Canvas.putImageData(this.ImageData, left, top, 0, 0, drawImageWidth, drawImageHeight);
  7787. }
  7788. }
  7789. }
  7790. // 雷达图
  7791. function ChartRadar()
  7792. {
  7793. this.newMethod = IChartPainting; //派生
  7794. this.newMethod();
  7795. delete this.newMethod;
  7796. this.BorderPoint = []; //边框点
  7797. this.DataPoint = []; //数据点
  7798. this.CenterPoint = {};
  7799. this.StartAngle = 0;
  7800. this.Color = 'rgb(198,198,198)';
  7801. this.AreaColor = 'rgba(242,154,118,0.4)'; //面积图颜色
  7802. this.AreaLineColor = 'rgb(242,154,118)';
  7803. this.TitleFont = '24px 微软雅黑';
  7804. this.TitleColor = 'rgb(102,102,102)';
  7805. this.BGColor = ['rgb(255,255,255)', 'rgb(224,224,224)']//背景色
  7806. this.DrawBorder = function () //画边框
  7807. {
  7808. if (this.BorderPoint.length <= 0) return;
  7809. this.Canvas.font = this.TitleFont;
  7810. this.Canvas.strokeStyle = this.Color;
  7811. const aryBorder = [1, 0.8, 0.6, 0.4, 0.2];
  7812. for (let j in aryBorder)
  7813. {
  7814. var rate = aryBorder[j];
  7815. var isFirstDraw = true;
  7816. for (let i in this.BorderPoint)
  7817. {
  7818. var item = this.BorderPoint[i];
  7819. item.X = this.CenterPoint.X + item.Radius * Math.cos(item.Angle * Math.PI / 180) * rate;
  7820. item.Y = this.CenterPoint.Y + item.Radius * Math.sin(item.Angle * Math.PI / 180) * rate;
  7821. if (isFirstDraw)
  7822. {
  7823. this.Canvas.beginPath();
  7824. this.Canvas.moveTo(item.X, item.Y);
  7825. isFirstDraw = false;
  7826. }
  7827. else
  7828. {
  7829. this.Canvas.lineTo(item.X, item.Y);
  7830. }
  7831. if (j == 0) this.DrawText(item);
  7832. }
  7833. this.Canvas.closePath();
  7834. this.Canvas.stroke();
  7835. this.Canvas.fillStyle = this.BGColor[j % 2 == 0 ? 0 : 1];
  7836. this.Canvas.fill();
  7837. }
  7838. this.Canvas.beginPath();
  7839. for (let i in this.BorderPoint)
  7840. {
  7841. var item = this.BorderPoint[i];
  7842. item.X = this.CenterPoint.X + item.Radius * Math.cos(item.Angle * Math.PI / 180);
  7843. item.Y = this.CenterPoint.Y + item.Radius * Math.sin(item.Angle * Math.PI / 180);
  7844. this.Canvas.moveTo(this.CenterPoint.X, this.CenterPoint.Y);
  7845. this.Canvas.lineTo(item.X, item.Y);
  7846. }
  7847. this.Canvas.stroke();
  7848. }
  7849. this.DrawArea = function ()
  7850. {
  7851. if (!this.DataPoint || this.DataPoint.length <= 0) return;
  7852. this.Canvas.fillStyle = this.AreaColor;
  7853. this.Canvas.strokeStyle = this.AreaLineColor;
  7854. this.Canvas.beginPath();
  7855. var isFirstDraw = true;
  7856. for (let i in this.DataPoint)
  7857. {
  7858. var item = this.DataPoint[i];
  7859. if (isFirstDraw)
  7860. {
  7861. this.Canvas.beginPath();
  7862. this.Canvas.moveTo(item.X, item.Y);
  7863. isFirstDraw = false;
  7864. }
  7865. else
  7866. {
  7867. this.Canvas.lineTo(item.X, item.Y);
  7868. }
  7869. }
  7870. this.Canvas.closePath();
  7871. this.Canvas.fill();
  7872. this.Canvas.stroke();
  7873. }
  7874. this.DrawText = function (item)
  7875. {
  7876. if (!item.Text) return;
  7877. //console.log(item.Text, item.Angle);
  7878. this.Canvas.fillStyle = this.TitleColor;
  7879. var xText = item.X, yText = item.Y;
  7880. //显示每个角度的位置
  7881. if (item.Angle > 0 && item.Angle < 45)
  7882. {
  7883. this.Canvas.textAlign = 'left';
  7884. this.Canvas.textBaseline = 'middle';
  7885. xText += 2;
  7886. }
  7887. else if (item.Angle >= 0 && item.Angle < 90) {
  7888. this.Canvas.textAlign = 'left';
  7889. this.Canvas.textBaseline = 'top';
  7890. xText += 2;
  7891. }
  7892. else if (item.Angle >= 90 && item.Angle < 135)
  7893. {
  7894. this.Canvas.textAlign = 'right';
  7895. this.Canvas.textBaseline = 'top';
  7896. xText -= 2;
  7897. }
  7898. else if (item.Angle >= 135 && item.Angle < 180)
  7899. {
  7900. this.Canvas.textAlign = 'right';
  7901. this.Canvas.textBaseline = 'top';
  7902. xText -= 2;
  7903. }
  7904. else if (item.Angle >= 180 && item.Angle < 225) {
  7905. this.Canvas.textAlign = 'right';
  7906. this.Canvas.textBaseline = 'middle';
  7907. xText -= 2;
  7908. }
  7909. else if (item.Angle >= 225 && item.Angle <= 270) {
  7910. this.Canvas.textAlign = 'center';
  7911. this.Canvas.textBaseline = 'bottom';
  7912. }
  7913. else if (item.Angle > 270 && item.Angle < 315)
  7914. {
  7915. this.Canvas.textAlign = 'left';
  7916. this.Canvas.textBaseline = 'bottom';
  7917. xText += 2;
  7918. }
  7919. else
  7920. {
  7921. this.Canvas.textAlign = 'left';
  7922. this.Canvas.textBaseline = 'middle';
  7923. xText += 2;
  7924. }
  7925. this.Canvas.fillText(item.Text, xText, yText);
  7926. }
  7927. this.Draw = function ()
  7928. {
  7929. this.BorderPoint = [];
  7930. this.DataPoint = [];
  7931. this.InternalBorderPoint = [];
  7932. this.CenterPoint = {};
  7933. if (!this.Data || !this.Data.Data || !(this.Data.Data.length > 0))
  7934. this.CalculatePoints(null);
  7935. else
  7936. this.CalculatePoints(this.Data.Data);
  7937. this.DrawBorder();
  7938. this.DrawArea();
  7939. }
  7940. this.CalculatePoints = function (data)
  7941. {
  7942. let left = this.ChartBorder.GetLeft();
  7943. let right = this.ChartBorder.GetRight();
  7944. let top = this.ChartBorder.GetTop();
  7945. let bottom = this.ChartBorder.GetBottom();
  7946. let width = this.ChartBorder.GetWidth();
  7947. let height = this.ChartBorder.GetHeight();
  7948. let ptCenter = { X: left + width / 2, Y: top + height / 2 }; //中心点
  7949. let radius = Math.min(width / 2, height / 2) - 2 //半径
  7950. let count = Math.max(5, data ? data.length : 0);
  7951. let averageAngle = 360 / count;
  7952. for (let i = 0; i < count; ++i)
  7953. {
  7954. let ptBorder = { Index: i, Radius: radius, Angle: i * averageAngle + this.StartAngle };
  7955. let angle = ptBorder.Angle;
  7956. if (data && i < data.length)
  7957. {
  7958. var item = data[i];
  7959. let ptData = { Index: i, Text: item.Text };
  7960. ptBorder.Text = item.Name;
  7961. if (!item.Value)
  7962. {
  7963. ptData.X = ptCenter.X;
  7964. ptData.Y = ptCenter.Y;
  7965. }
  7966. else
  7967. {
  7968. var value = item.Value;
  7969. if (value >= 1) value = 1;
  7970. var dataRadius = radius * value;
  7971. ptData.X = ptCenter.X + dataRadius * Math.cos(angle * Math.PI / 180);
  7972. ptData.Y = ptCenter.Y + dataRadius * Math.sin(angle * Math.PI / 180);
  7973. }
  7974. this.DataPoint.push(ptData);
  7975. }
  7976. this.BorderPoint.push(ptBorder);
  7977. }
  7978. this.CenterPoint = ptCenter;
  7979. }
  7980. }
  7981. ///////////////////////////////////////////////////////////////////////////////////////////////////
  7982. //十字光标
  7983. function ChartCorssCursor()
  7984. {
  7985. this.Frame;
  7986. this.Canvas; //画布
  7987. this.HPenColor = g_JSChartResource.CorssCursorHPenColor; //水平线颜色
  7988. this.HPenType = 0; //水平线样式 0=虚线 1=实线
  7989. this.VPenColor = g_JSChartResource.CorssCursorVPenColor; //垂直线颜色
  7990. this.VPenType = 0; //垂直线颜色 0=虚线 1=实线 2=K线宽度
  7991. this.Font = g_JSChartResource.CorssCursorTextFont; //字体
  7992. this.TextColor = g_JSChartResource.CorssCursorTextColor; //文本颜色
  7993. this.TextBGColor = g_JSChartResource.CorssCursorBGColor; //文本背景色
  7994. this.TextHeight = 15; //文本字体高度
  7995. this.LastPoint;
  7996. this.CursorIndex; //当前数据的位置
  7997. this.PointX;
  7998. this.PointY;
  7999. this.StringFormatX;
  8000. this.StringFormatY;
  8001. this.IsShow = true; //是否显示
  8002. this.ShowTextMode = { Left: 1, Right: 1, Bottom: 1 }; //0=不显示 1=显示在框架外 2=显示在框架内
  8003. this.TextFormat= { Right:0 }; //0=默认 1=价格显示(分时图才有用)
  8004. this.IsShowCorss = true; //是否显示十字光标
  8005. this.IsShowClose = false; //Y轴始终显示收盘价
  8006. this.IsOnlyDrawMinute=false; //是否只能画在走势图价格线上
  8007. this.IsFixXLastTime=false; //是否修正X轴,超出当前时间的,X轴调整到当前最后的时间.
  8008. this.RightMargin={ Left:2, Right:2, Top:2, Bottom:1 };
  8009. JSChartResource.CopyMargin(this.RightMargin, g_JSChartResource.CorssCursor.RightMargin);
  8010. //内部使用
  8011. this.Close = null; //收盘价格
  8012. this.GetCloseYPoint = function (index)
  8013. {
  8014. this.Close = null;
  8015. if (!this.StringFormatX.Data) return null;
  8016. var data = this.StringFormatX.Data;
  8017. if (!data.Data || data.Data.length <= 0) return null;
  8018. var dataIndex = data.DataOffset + index;
  8019. if (dataIndex >= data.Data.length) dataIndex = data.Data.length - 1;
  8020. if (dataIndex < 0) return null;
  8021. var klineData = data.Data[dataIndex];
  8022. if (!klineData) return null;
  8023. this.Close = klineData.Close;
  8024. var yPoint = this.Frame.GetYFromData(this.Close);
  8025. return yPoint;
  8026. }
  8027. this.GetMinuteCloseYPoint=function(index)
  8028. {
  8029. if (!IFrameSplitOperator.IsNumber(index)) return null;
  8030. index=parseInt(index);
  8031. if (!this.StringFormatX.Data) return null;
  8032. var data = this.StringFormatX.Data;
  8033. if (!data.Data || data.Data.length <= 0) return null;
  8034. var dataIndex = data.DataOffset + index;
  8035. if (dataIndex >= data.Data.length) dataIndex = data.Data.length - 1;
  8036. if (dataIndex < 0) return null;
  8037. var close = data.Data[dataIndex];
  8038. if (!IFrameSplitOperator.IsNumber(index)) return null;
  8039. this.Close=close;
  8040. var yPoint = this.Frame.GetYFromData(this.Close);
  8041. return yPoint;
  8042. }
  8043. this.FixMinuteLastTimeXPoint=function(index)
  8044. {
  8045. if (!IFrameSplitOperator.IsNumber(index)) return null;
  8046. index=parseInt(index);
  8047. if (!this.StringFormatX.Data) return null;
  8048. var data = this.StringFormatX.Data;
  8049. if (!data.Data || data.Data.length <= 0) return null;
  8050. var dataIndex = data.DataOffset + index;
  8051. if (dataIndex<data.Data.length) return null;
  8052. dataIndex=data.Data.length - 1;
  8053. dataIndex-=data.DataOffset;
  8054. var xPoint=this.Frame.GetXFromIndex(dataIndex);
  8055. return { X:xPoint, Index:dataIndex };
  8056. }
  8057. this.Draw = function ()
  8058. {
  8059. if (!this.LastPoint) return;
  8060. var x = this.LastPoint.X;
  8061. var y = this.LastPoint.Y;
  8062. var isInClient = false;
  8063. var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
  8064. isInClient = rtClient.IsPointIn(x, y);
  8065. this.PointY = null;
  8066. this.PointY == null;
  8067. if (!isInClient) return;
  8068. if (this.Frame.IsHScreen === true)
  8069. {
  8070. this.HScreenDraw();
  8071. return;
  8072. }
  8073. var left = this.Frame.ChartBorder.GetLeft();
  8074. var right = this.Frame.ChartBorder.GetRight();
  8075. var top = this.Frame.ChartBorder.GetTopTitle();
  8076. var bottom = this.Frame.ChartBorder.GetBottom();
  8077. var rightWidth = this.Frame.ChartBorder.Right;
  8078. var chartRight = this.Frame.ChartBorder.GetChartWidth();
  8079. x = this.Frame.GetXFromIndex(this.CursorIndex); //手机端 十字只能画在K线上
  8080. if (this.IsShowClose) //手机端 十字只能画在K线上
  8081. {
  8082. var yPoint = this.GetCloseYPoint(this.CursorIndex);
  8083. if (yPoint != null) y = yPoint;
  8084. }
  8085. else if (this.IsOnlyDrawMinute)
  8086. {
  8087. var yPoint = this.GetMinuteCloseYPoint(this.CursorIndex);
  8088. if (yPoint != null) y=yPoint;
  8089. }
  8090. if (this.IsFixXLastTime)
  8091. {
  8092. var value=this.FixMinuteLastTimeXPoint(this.CursorIndex)
  8093. if (value)
  8094. {
  8095. x=value.X;
  8096. this.CursorIndex=value.Index;
  8097. }
  8098. }
  8099. this.PointY = [[left, y], [right, y]];
  8100. this.PointX = [[x, top], [x, bottom]];
  8101. if (this.IsShowCorss) //十字线
  8102. {
  8103. if (this.HPenType==1 || this.HPenType==0)
  8104. {
  8105. this.Canvas.strokeStyle = this.HPenColor;
  8106. if (this.HPenType == 0) this.Canvas.setLineDash([3, 2]); //虚线
  8107. //this.Canvas.lineWidth=0.5
  8108. this.Canvas.beginPath();
  8109. this.Canvas.moveTo(left, ToFixedPoint(y));
  8110. this.Canvas.lineTo(right, ToFixedPoint(y));
  8111. this.Canvas.stroke();
  8112. this.Canvas.setLineDash([]);
  8113. }
  8114. this.Canvas.save();
  8115. this.Canvas.strokeStyle = this.VPenColor;
  8116. if (this.VPenType == 0)
  8117. {
  8118. this.Canvas.setLineDash([3, 2]); //虚线
  8119. }
  8120. else if (this.VPenType == 2)
  8121. {
  8122. let barWidth = this.Frame.SubFrame[0].Frame.DataWidth; //和K线一样宽度
  8123. if (barWidth > 2) this.Canvas.lineWidth = barWidth;
  8124. }
  8125. this.Canvas.beginPath();
  8126. if (this.Frame.SubFrame.length > 0)
  8127. {
  8128. for (var i in this.Frame.SubFrame)
  8129. {
  8130. var frame = this.Frame.SubFrame[i].Frame;
  8131. top = frame.ChartBorder.GetTopTitle();
  8132. bottom = frame.ChartBorder.GetBottom();
  8133. this.Canvas.moveTo(ToFixedPoint(x), top);
  8134. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  8135. }
  8136. }
  8137. else
  8138. {
  8139. this.Canvas.moveTo(ToFixedPoint(x), top);
  8140. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  8141. }
  8142. this.Canvas.stroke();
  8143. this.Canvas.restore();
  8144. }
  8145. var xValue = this.Frame.GetXData(x);
  8146. var yValueExtend = {};
  8147. var yValue = this.Frame.GetYData(y, yValueExtend);
  8148. this.StringFormatY.RValue = yValueExtend.RightYValue; //右侧子坐标
  8149. if (this.IsShowClose && this.Close != null) yValue = this.Close;
  8150. this.StringFormatX.Value = this.CursorIndex;
  8151. this.StringFormatY.Value = yValue;
  8152. this.StringFormatY.RValue=yValueExtend.RightYValue; //右侧子坐标
  8153. this.StringFormatY.Point={X:x, Y:y};
  8154. this.StringFormatY.FrameID = yValueExtend.FrameID;
  8155. if (((this.ShowTextMode.Left == 1 && this.Frame.ChartBorder.Left >= 30) || this.ShowTextMode.Left == 2 ||
  8156. (this.ShowTextMode.Right == 1 && this.Frame.ChartBorder.Right >= 30) || this.ShowTextMode.Right == 2) && this.StringFormatY.Operator())
  8157. {
  8158. var text = this.StringFormatY.Text;
  8159. this.Canvas.font = this.Font;
  8160. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  8161. if (this.Frame.ChartBorder.Left >= 30 && this.ShowTextMode.Left == 1)
  8162. {
  8163. this.Canvas.fillStyle = this.TextBGColor;
  8164. if (left < textWidth) //左边空白的地方太少了画布下
  8165. {
  8166. this.Canvas.fillRect(2, y - this.TextHeight / 2, textWidth, this.TextHeight);
  8167. this.Canvas.textAlign = "left";
  8168. this.Canvas.textBaseline = "middle";
  8169. this.Canvas.fillStyle = this.TextColor;
  8170. this.Canvas.fillText(text, 2 + 2, y, textWidth);
  8171. }
  8172. else
  8173. {
  8174. this.Canvas.fillRect(left - 2, y - this.TextHeight / 2, -textWidth, this.TextHeight);
  8175. this.Canvas.textAlign = "right";
  8176. this.Canvas.textBaseline = "middle";
  8177. this.Canvas.fillStyle = this.TextColor;
  8178. this.Canvas.fillText(text, left - 4, y, textWidth);
  8179. }
  8180. }
  8181. else if (this.ShowTextMode.Left == 2)
  8182. {
  8183. this.Canvas.fillStyle = this.TextBGColor;
  8184. this.Canvas.fillRect(left, y - this.TextHeight / 2, textWidth, this.TextHeight);
  8185. this.Canvas.textAlign = "left";
  8186. this.Canvas.textBaseline = "middle";
  8187. this.Canvas.fillStyle = this.TextColor;
  8188. this.Canvas.fillText(text, left + 2, y, textWidth);
  8189. }
  8190. var complexText=
  8191. {
  8192. ShowType:0, //0=单行(默认) 1=多行
  8193. Font:this.Font, Color:this.TextColor,
  8194. Text:[ { Text:text, Margin:this.RightMargin } ],
  8195. };
  8196. var yTop=y-this.TextHeight/2;
  8197. var textSize={ Width:0, Height:0, Text:[] };
  8198. if (this.StringFormatY.PercentageText)
  8199. {
  8200. if (this.TextFormat.Right==0)
  8201. {
  8202. text=this.StringFormatY.PercentageText+'%';
  8203. complexText.Text[0].Text=text;
  8204. }
  8205. }
  8206. if (this.StringFormatY.RText)
  8207. {
  8208. text = this.StringFormatY.RText;
  8209. complexText.Text[0].Text=text;
  8210. }
  8211. if (this.StringFormatY.RComplexText && IFrameSplitOperator.IsNonEmptyArray(this.StringFormatY.RComplexText.Text))
  8212. {
  8213. complexText=this.StringFormatY.RComplexText;
  8214. if (!complexText.Font) complexText.Font=this.Font;
  8215. if (!complexText.Font) complexText.Color=this.TextColor;
  8216. }
  8217. this.CalculateComplexTextSize(complexText, textSize);
  8218. if (this.Frame.ChartBorder.Right >= 30 && this.ShowTextMode.Right == 1)
  8219. {
  8220. if (rightWidth > textSize.Width) //右边不够就不画
  8221. {
  8222. var itemLeft=right+2;
  8223. this.DrawTextBGRect(itemLeft, yTop, textSize.Width, textSize.Height);
  8224. this.DrawComplexTextV2(itemLeft,yTop,complexText,textSize);
  8225. }
  8226. else
  8227. {
  8228. var itemLeft=chartRight-2-textSize.Width;
  8229. this.DrawTextBGRect(itemLeft, yTop, textSize.Width, textSize.Height);
  8230. this.DrawComplexTextV2(itemLeft,yTop,complexText,textSize);
  8231. }
  8232. }
  8233. else if (this.ShowTextMode.Right == 2)
  8234. {
  8235. var showLeft = right - textSize.Width;
  8236. this.DrawTextBGRect(showLeft,yTop,textSize.Width,textSize.Height);
  8237. this.DrawComplexTextV2(showLeft,yTop,complexText,textSize);
  8238. }
  8239. }
  8240. //Bottom==8 自定义X轴文字位置
  8241. if ((this.ShowTextMode.Bottom == 1 || this.ShowTextMode.Bottom==8) && this.StringFormatX.Operator())
  8242. {
  8243. var text = this.StringFormatX.Text;
  8244. this.Canvas.font = this.Font;
  8245. this.Canvas.fillStyle = this.TextBGColor;
  8246. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  8247. var bShowText=true;
  8248. var yText=bottom + 2; //文字顶部坐标
  8249. if (this.ShowTextMode.Bottom==8)
  8250. {
  8251. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_CORSSCURSOR_POSITION);
  8252. if (event && event.Callback)
  8253. {
  8254. var yCenter=yText+this.TextHeight/2;
  8255. var yTop=yText;
  8256. var sendData={ YCenter:yCenter, YTop:yTop, Height:this.TextHeight, IsShowText:bShowText };
  8257. event.Callback(event, sendData, this);
  8258. yCenter=sendData.YCenter;
  8259. yText=sendData.YTop;
  8260. bShowText=sendData.IsShowText;
  8261. }
  8262. }
  8263. if (bShowText)
  8264. {
  8265. if (x - textWidth / 2 < 3) //左边位置不够了, 顶着左边画
  8266. {
  8267. this.Canvas.fillRect(x - 1, yText, textWidth, this.TextHeight);
  8268. this.Canvas.textAlign = "left";
  8269. this.Canvas.textBaseline = "top";
  8270. this.Canvas.fillStyle = this.TextColor;
  8271. this.Canvas.fillText(text, x + 1, yText, textWidth);
  8272. }
  8273. else if ((right - left) - x < textWidth)
  8274. { //右边位置不够用,顶着右边画
  8275. this.Canvas.fillRect(x - textWidth, yText, textWidth, this.TextHeight);
  8276. this.Canvas.textAlign = "right";
  8277. this.Canvas.textBaseline = "top";
  8278. this.Canvas.fillStyle = this.TextColor;
  8279. this.Canvas.fillText(text, x - 1, yText, textWidth);
  8280. }
  8281. else
  8282. {
  8283. this.Canvas.fillRect(x - textWidth / 2, yText, textWidth, this.TextHeight);
  8284. this.Canvas.textAlign = "center";
  8285. this.Canvas.textBaseline = "top";
  8286. this.Canvas.fillStyle = this.TextColor;
  8287. this.Canvas.fillText(text, x, yText, textWidth);
  8288. }
  8289. }
  8290. }
  8291. }
  8292. this.DrawTextBGRect=function(x,y, height, width)
  8293. {
  8294. this.Canvas.fillStyle=this.TextBGColor;
  8295. this.Canvas.fillRect(ToFixedPoint(x),ToFixedPoint(y),ToFixedRect(height),ToFixedRect(width));
  8296. //this.Canvas.fillRect(x,y,height,width);
  8297. }
  8298. this.CalculateComplexTextSize=function(complexText, size)
  8299. {
  8300. if (!complexText || !IFrameSplitOperator.IsNonEmptyArray(complexText.Text)) return;
  8301. var showType=0;
  8302. if (complexText.ShowType==1) showType=complexText.ShowType;
  8303. if (showType==1) //多行
  8304. {
  8305. var textWidth=0, textHeight=0;
  8306. for(var i=0; i<complexText.Text.length; ++i)
  8307. {
  8308. var item=complexText.Text[i];
  8309. if (item.Font) this.Canvas.font=item.Font;
  8310. else this.Canvas.font=complexText.Font;
  8311. var itemWidth=this.Canvas.measureText(item.Text).width; //前后各空2个像素
  8312. var itemHeight=this.Canvas.measureText("擎").width;
  8313. if (item.Margin)
  8314. {
  8315. var margin=item.Margin;
  8316. if (IFrameSplitOperator.IsNumber(margin.Left)) itemWidth+=margin.Left;
  8317. if (IFrameSplitOperator.IsNumber(margin.Right)) itemWidth+=margin.Right;
  8318. if (IFrameSplitOperator.IsNumber(margin.Top)) itemHeight+=margin.Top;
  8319. if (IFrameSplitOperator.IsNumber(margin.Bottom)) itemHeight+=margin.Bottom;
  8320. }
  8321. size.Text[i]={ Width:itemWidth, Height:itemHeight }; //保存所有文字的大小信息
  8322. if (textWidth<itemWidth) textWidth=itemWidth;
  8323. textHeight+=itemHeight;
  8324. }
  8325. size.Width=textWidth;
  8326. size.Height=textHeight;
  8327. }
  8328. else //水平 单行
  8329. {
  8330. var textWidth=0, textHeight=0;
  8331. for(var i=0; i<complexText.Text.length; ++i)
  8332. {
  8333. var item=complexText.Text[i];
  8334. if (item.Font) this.Canvas.font=item.Font;
  8335. else this.Canvas.font=complexText.Font;
  8336. var itemWidth=this.Canvas.measureText(item.Text).width; //前后各空2个像素
  8337. var itemHeight=this.Canvas.measureText("擎").width;
  8338. if (item.Margin)
  8339. {
  8340. var margin=item.Margin;
  8341. if (IFrameSplitOperator.IsNumber(margin.Left)) itemWidth+=margin.Left;
  8342. if (IFrameSplitOperator.IsNumber(margin.Right)) itemWidth+=margin.Right;
  8343. if (IFrameSplitOperator.IsNumber(margin.Top)) itemHeight+=margin.Top;
  8344. if (IFrameSplitOperator.IsNumber(margin.Bottom)) itemHeight+=margin.Bottom;
  8345. }
  8346. size.Text[i]={ Width:itemWidth, Height:itemHeight }; //保存所有文字的大小信息
  8347. textWidth+=itemWidth;
  8348. if (textHeight<itemHeight) textHeight=itemHeight;
  8349. }
  8350. size.Width=textWidth;
  8351. size.Height=textHeight;
  8352. }
  8353. }
  8354. this.DrawComplexTextV2=function(left, yTop, complexText, size)
  8355. {
  8356. this.Canvas.textAlign="left";
  8357. this.Canvas.textBaseline="bottom";
  8358. var showType=0;
  8359. if (complexText.ShowType==1) showType=complexText.ShowType;
  8360. if (showType==1) //多行
  8361. {
  8362. var xLeft=left;
  8363. var yText=yTop; //顶
  8364. for(var i=0; i<complexText.Text.length; ++i)
  8365. {
  8366. var item=complexText.Text[i];
  8367. var itemSize=size.Text[i];
  8368. if (item.Font) this.Canvas.font=item.Font;
  8369. else this.Canvas.font=complexText.Font;
  8370. if (item.Color) this.Canvas.fillStyle=item.Color;
  8371. else this.Canvas.fillStyle=complexText.Color;
  8372. var y=yText+itemSize.Height;
  8373. var x=xLeft;
  8374. if (item.Margin)
  8375. {
  8376. var margin=item.Margin;
  8377. if (IFrameSplitOperator.IsNumber(margin.Bottom)) y-=margin.Bottom;
  8378. if (IFrameSplitOperator.IsNumber(margin.Left)) x+=margin.Left;
  8379. }
  8380. this.Canvas.fillText(item.Text,x,y,itemSize.Width);
  8381. yText+=itemSize.Height;
  8382. }
  8383. }
  8384. else //水平 单行
  8385. {
  8386. var xText=left;
  8387. var yBottom=yTop+size.Height;
  8388. for(var i=0; i<complexText.Text.length; ++i)
  8389. {
  8390. var item=complexText.Text[i];
  8391. var itemSize=size.Text[i];
  8392. if (item.Font) this.Canvas.font=item.Font;
  8393. else this.Canvas.font=complexText.Font;
  8394. if (item.Color) this.Canvas.fillStyle=item.Color;
  8395. else this.Canvas.fillStyle=complexText.Color;
  8396. var y=yBottom;
  8397. var x=xText;
  8398. if (item.Margin)
  8399. {
  8400. var margin=item.Margin;
  8401. if (IFrameSplitOperator.IsNumber(margin.Bottom)) y-=margin.Bottom;
  8402. if (IFrameSplitOperator.IsNumber(margin.Left)) x+=margin.Left;
  8403. }
  8404. this.Canvas.fillText(item.Text,x,y,itemSize.Width);
  8405. xText+=itemSize.Width;
  8406. }
  8407. }
  8408. }
  8409. this.HScreenDraw = function ()
  8410. {
  8411. var x = this.LastPoint.X;
  8412. var y = this.LastPoint.Y;
  8413. y = this.Frame.GetXFromIndex(this.CursorIndex); //手机端 十字只能画在K线上
  8414. if (this.IsShowClose) //手机端 十字只能画在K线上
  8415. {
  8416. var yPoint = this.GetCloseYPoint(this.CursorIndex);
  8417. if (yPoint != null) x = yPoint;
  8418. }
  8419. else if (this.IsOnlyDrawMinute)
  8420. {
  8421. var yPoint = this.GetMinuteCloseYPoint(this.CursorIndex);
  8422. if (yPoint != null) x=yPoint;
  8423. }
  8424. var left = this.Frame.ChartBorder.GetLeft();
  8425. var right = this.Frame.ChartBorder.GetRightEx();
  8426. var top = this.Frame.ChartBorder.GetTop();
  8427. var bottom = this.Frame.ChartBorder.GetBottom();
  8428. var bottomWidth = this.Frame.ChartBorder.Bottom;
  8429. this.PointY = [[left, y], [right, y]];
  8430. this.PointX = [[x, top], [x, bottom]];
  8431. if (this.IsShowCorss) //十字线
  8432. {
  8433. this.Canvas.save();
  8434. this.Canvas.strokeStyle = this.HPenColor;
  8435. if (this.HPenType == 0) this.Canvas.setLineDash([3, 2]); //虚线
  8436. //画竖线
  8437. this.Canvas.beginPath();
  8438. this.Canvas.moveTo(ToFixedPoint(x), top);
  8439. this.Canvas.lineTo(ToFixedPoint(x), bottom);
  8440. this.Canvas.stroke();
  8441. this.Canvas.restore();
  8442. this.Canvas.save();
  8443. this.Canvas.strokeStyle = this.VPenColor;
  8444. if (this.VPenType == 0)
  8445. {
  8446. this.Canvas.setLineDash([3, 2]); //虚线
  8447. }
  8448. else if (this.VPenType == 2)
  8449. {
  8450. let barWidth = this.Frame.SubFrame[0].Frame.DataWidth; //和K线一样宽度
  8451. if (barWidth > 2) this.Canvas.lineWidth = barWidth;
  8452. }
  8453. this.Canvas.beginPath();
  8454. //画横线
  8455. if (this.Frame.SubFrame.length > 0)
  8456. {
  8457. for (var i in this.Frame.SubFrame)
  8458. {
  8459. var frame = this.Frame.SubFrame[i].Frame;
  8460. this.Canvas.moveTo(frame.ChartBorder.GetLeft(), ToFixedPoint(y));
  8461. this.Canvas.lineTo(frame.ChartBorder.GetRightTitle(), ToFixedPoint(y));
  8462. }
  8463. }
  8464. else
  8465. {
  8466. this.Canvas.moveTo(left, ToFixedPoint(y));
  8467. this.Canvas.lineTo(right, ToFixedPoint(y));
  8468. }
  8469. this.Canvas.stroke();
  8470. this.Canvas.restore();
  8471. }
  8472. var xValue = this.Frame.GetXData(y);
  8473. var yValueExtend = {};
  8474. var yValue = this.Frame.GetYData(x, yValueExtend);
  8475. this.StringFormatX.Value = xValue;
  8476. this.StringFormatY.Value = yValue;
  8477. this.StringFormatY.RValue=yValueExtend.RightYValue; //右侧子坐标
  8478. this.StringFormatY.Point={X:x, Y:y};
  8479. this.StringFormatY.FrameID = yValueExtend.FrameID;
  8480. if (((this.ShowTextMode.Left == 1 && this.Frame.ChartBorder.Top >= 30) || this.ShowTextMode.Left == 2 ||
  8481. (this.ShowTextMode.Right == 1 && this.Frame.ChartBorder.Bottom >= 30) || this.ShowTextMode.Right == 2) && this.StringFormatY.Operator()) {
  8482. var text = this.StringFormatY.Text;
  8483. this.Canvas.font = this.Font;
  8484. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  8485. if (this.Frame.ChartBorder.Top >= 30 && this.ShowTextMode.Left == 1) {
  8486. var xText = x, yText = top;
  8487. this.Canvas.save();
  8488. this.Canvas.translate(xText, yText);
  8489. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  8490. this.Canvas.fillStyle = this.TextBGColor;
  8491. if (top >= textWidth) {
  8492. this.Canvas.fillRect(-textWidth, -(this.TextHeight / 2), textWidth, this.TextHeight);
  8493. this.Canvas.textAlign = "right";
  8494. this.Canvas.textBaseline = "middle";
  8495. this.Canvas.fillStyle = this.TextColor;
  8496. this.Canvas.fillText(text, -2, 0, textWidth);
  8497. }
  8498. else {
  8499. this.Canvas.fillRect((textWidth - top), -(this.TextHeight / 2), -textWidth, this.TextHeight);
  8500. this.Canvas.textAlign = "right";
  8501. this.Canvas.textBaseline = "middle";
  8502. this.Canvas.fillStyle = this.TextColor;
  8503. this.Canvas.fillText(text, (textWidth - top) - 2, 0, textWidth);
  8504. }
  8505. this.Canvas.restore();
  8506. }
  8507. else if (this.ShowTextMode.Left == 2) {
  8508. var xText = x;
  8509. var yText = top;
  8510. this.Canvas.save();
  8511. this.Canvas.translate(xText, yText);
  8512. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  8513. this.Canvas.fillStyle = this.TextBGColor;
  8514. this.Canvas.fillRect(0, -(this.TextHeight / 2), textWidth, this.TextHeight);
  8515. this.Canvas.textAlign = "left";
  8516. this.Canvas.textBaseline = "middle";
  8517. this.Canvas.fillStyle = this.TextColor;
  8518. this.Canvas.fillText(text, 2, 0, textWidth);
  8519. this.Canvas.restore();
  8520. }
  8521. if (this.StringFormatY.RText)
  8522. {
  8523. text=this.StringFormatY.RText;
  8524. var textWidth=this.Canvas.measureText(text).width+4; //前后各空2个像素
  8525. }
  8526. if (this.Frame.ChartBorder.Bottom >= 30 && this.ShowTextMode.Right == 1) {
  8527. var xText = x, yText = bottom;
  8528. this.Canvas.save();
  8529. this.Canvas.translate(xText, yText);
  8530. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  8531. this.Canvas.fillStyle = this.TextBGColor;
  8532. if (bottomWidth > textWidth) {
  8533. this.Canvas.fillRect(0, -(this.TextHeight / 2), textWidth, this.TextHeight);
  8534. this.Canvas.textAlign = "left";
  8535. this.Canvas.textBaseline = "middle";
  8536. this.Canvas.fillStyle = this.TextColor;
  8537. this.Canvas.fillText(text, 2, 0, textWidth);
  8538. }
  8539. else {
  8540. this.Canvas.fillRect((bottomWidth - textWidth), -(this.TextHeight / 2), textWidth, this.TextHeight);
  8541. this.Canvas.textAlign = "left";
  8542. this.Canvas.textBaseline = "middle";
  8543. this.Canvas.fillStyle = this.TextColor;
  8544. this.Canvas.fillText(text, (bottomWidth - textWidth) + 2, 0, textWidth);
  8545. }
  8546. this.Canvas.restore();
  8547. }
  8548. else if (this.ShowTextMode.Right == 2) {
  8549. var xText = x;
  8550. var yText = bottom;
  8551. this.Canvas.save();
  8552. this.Canvas.translate(xText, yText);
  8553. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  8554. this.Canvas.fillStyle = this.TextBGColor;
  8555. this.Canvas.fillRect(0, -(this.TextHeight / 2), -textWidth, this.TextHeight);
  8556. this.Canvas.textAlign = "right";
  8557. this.Canvas.textBaseline = "middle";
  8558. this.Canvas.fillStyle = this.TextColor;
  8559. this.Canvas.fillText(text, -2, 0, textWidth);
  8560. this.Canvas.restore();
  8561. }
  8562. }
  8563. if ((this.ShowTextMode.Bottom === 1 ||this.ShowTextMode.Bottom==8) && this.StringFormatX.Operator())
  8564. {
  8565. var text = this.StringFormatX.Text;
  8566. this.Canvas.font = this.Font;
  8567. this.Canvas.fillStyle = this.TextBGColor;
  8568. var textWidth = this.Canvas.measureText(text).width + 4; //前后各空2个像素
  8569. var bShowText=true;
  8570. var yText = y;
  8571. var xText=left;
  8572. if (this.ShowTextMode.Bottom==8)
  8573. {
  8574. var event=this.GetEventCallback(JSCHART_EVENT_ID.ON_CUSTOM_CORSSCURSOR_POSITION);
  8575. if (event && event.Callback)
  8576. {
  8577. var sendData={ XText:xText, Height:this.TextHeight, IsShowText:bShowText };
  8578. event.Callback(event, sendData, this);
  8579. xText=sendData.XText;
  8580. bShowText=sendData.IsShowText;
  8581. }
  8582. }
  8583. if (bShowText)
  8584. {
  8585. if (y - textWidth / 2 < 3) //左边位置不够了, 顶着左边画
  8586. {
  8587. this.Canvas.save();
  8588. this.Canvas.translate(xText, yText);
  8589. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  8590. this.Canvas.fillRect(0, 0, textWidth, this.TextHeight);
  8591. this.Canvas.textAlign = "center";
  8592. this.Canvas.textBaseline = "top";
  8593. this.Canvas.fillStyle = this.TextColor;
  8594. this.Canvas.fillText(text, 0, 0, textWidth);
  8595. this.Canvas.restore();
  8596. }
  8597. else
  8598. {
  8599. this.Canvas.save();
  8600. this.Canvas.translate(xText, yText);
  8601. this.Canvas.rotate(90 * Math.PI / 180); //数据和框子旋转180度
  8602. this.Canvas.fillRect(-(textWidth / 2), 0, textWidth, this.TextHeight);
  8603. this.Canvas.textAlign = "center";
  8604. this.Canvas.textBaseline = "top";
  8605. this.Canvas.fillStyle = this.TextColor;
  8606. this.Canvas.fillText(text, 0, 0, textWidth);
  8607. this.Canvas.restore();
  8608. }
  8609. }
  8610. }
  8611. }
  8612. }
  8613. //分钟线
  8614. function ChartMinutePriceLine()
  8615. {
  8616. this.newMethod = ChartLine; //派生
  8617. this.newMethod();
  8618. delete this.newMethod;
  8619. this.YClose;
  8620. this.IsDrawArea = true; //是否画价格面积图
  8621. this.AreaColor = 'rgba(0,191,255,0.1)';
  8622. this.Draw = function ()
  8623. {
  8624. if (this.NotSupportMessage)
  8625. {
  8626. this.DrawNotSupportmessage();
  8627. return;
  8628. }
  8629. if (!this.IsShow) return;
  8630. if (!this.Data) return;
  8631. var isHScreen = (this.ChartFrame.IsHScreen === true);
  8632. var dataWidth = this.ChartFrame.DataWidth;
  8633. var distanceWidth = this.ChartFrame.DistanceWidth;
  8634. var chartright = this.ChartBorder.GetRight();
  8635. if (isHScreen === true) chartright = this.ChartBorder.GetBottom();
  8636. var xPointCount = this.ChartFrame.XPointCount;
  8637. var minuteCount = this.ChartFrame.MinuteCount;
  8638. var bottom = this.ChartBorder.GetBottom();
  8639. var left = this.ChartBorder.GetLeft();
  8640. var bFirstPoint = true;
  8641. var ptFirst = {}; //第1个点
  8642. var drawCount = 0;
  8643. var pointCount=0;
  8644. this.Canvas.save();
  8645. this.ClipClient(isHScreen); //裁剪区域 防止线段毛刺超出图形
  8646. if (IFrameSplitOperator.IsPlusNumber(this.LineWidth>0)) this.Canvas.lineWidth=this.LineWidth;
  8647. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  8648. {
  8649. var value = this.Data.Data[i];
  8650. ++pointCount;
  8651. if (value == null) continue;
  8652. var x = this.ChartFrame.GetXFromIndex(j);
  8653. var y = this.ChartFrame.GetYFromData(value);
  8654. if (bFirstPoint)
  8655. {
  8656. this.Canvas.strokeStyle = this.Color;
  8657. this.Canvas.beginPath();
  8658. if (isHScreen) this.Canvas.moveTo(y, x);
  8659. else this.Canvas.moveTo(x, y);
  8660. bFirstPoint = false;
  8661. ptFirst = { X: x, Y: y };
  8662. }
  8663. else
  8664. {
  8665. if (isHScreen) this.Canvas.lineTo(y, x);
  8666. else this.Canvas.lineTo(x, y);
  8667. }
  8668. ++drawCount;
  8669. if (pointCount >= minuteCount) //上一天的数据和这天地数据线段要断开
  8670. {
  8671. bFirstPoint = true;
  8672. this.Canvas.stroke();
  8673. if (this.IsDrawArea) //画面积
  8674. {
  8675. if (isHScreen)
  8676. {
  8677. this.Canvas.lineTo(left, x);
  8678. this.Canvas.lineTo(left, ptFirst.X);
  8679. this.SetFillStyle(this.AreaColor, this.ChartBorder.GetRight(), bottom, this.ChartBorder.GetLeftEx(), bottom);
  8680. }
  8681. else
  8682. {
  8683. this.Canvas.lineTo(x, bottom);
  8684. this.Canvas.lineTo(ptFirst.X, bottom);
  8685. this.SetFillStyle(this.AreaColor, left, this.ChartBorder.GetTopEx(), left, bottom);
  8686. }
  8687. this.Canvas.fill();
  8688. }
  8689. drawCount = 0;
  8690. pointCount=0;
  8691. }
  8692. }
  8693. if (drawCount > 0)
  8694. {
  8695. this.Canvas.stroke();
  8696. if (this.IsDrawArea) //画面积
  8697. {
  8698. if (isHScreen)
  8699. {
  8700. this.Canvas.lineTo(left, x);
  8701. this.Canvas.lineTo(left, ptFirst.X);
  8702. this.SetFillStyle(this.AreaColor, this.ChartBorder.GetRight(), bottom, this.ChartBorder.GetLeftEx(), bottom);
  8703. }
  8704. else
  8705. {
  8706. this.Canvas.lineTo(x, bottom);
  8707. this.Canvas.lineTo(ptFirst.X, bottom);
  8708. this.SetFillStyle(this.AreaColor, left, this.ChartBorder.GetTopEx(), left, bottom);
  8709. }
  8710. this.Canvas.fill();
  8711. }
  8712. }
  8713. this.Canvas.restore();
  8714. }
  8715. this.GetMaxMin = function ()
  8716. {
  8717. var xPointCount = this.ChartFrame.XPointCount;
  8718. var range = {};
  8719. if (this.YClose == null) return range;
  8720. range.Min = this.YClose;
  8721. range.Max = this.YClose;
  8722. for (var i = this.Data.DataOffset, j = 0; i < this.Data.Data.length && j < xPointCount; ++i, ++j)
  8723. {
  8724. var value = this.Data.Data[i];
  8725. if (!value) continue;
  8726. if (range.Max == null) range.Max = value;
  8727. if (range.Min == null) range.Min = value;
  8728. if (range.Max < value) range.Max = value;
  8729. if (range.Min > value) range.Min = value;
  8730. }
  8731. if (range.Max == this.YClose && range.Min == this.YClose)
  8732. {
  8733. range.Max = this.YClose + this.YClose * 0.1;
  8734. range.Min = this.YClose - this.YClose * 0.1;
  8735. return range;
  8736. }
  8737. var distance = Math.max(Math.abs(this.YClose - range.Max), Math.abs(this.YClose - range.Min));
  8738. range.Max = this.YClose + distance;
  8739. range.Min = this.YClose - distance;
  8740. return range;
  8741. }
  8742. }
  8743. ////////////////////////////////////////////////////////////////////////////////
  8744. //深度图十字光标
  8745. function DepthChartCorssCursor()
  8746. {
  8747. this.Frame;
  8748. this.Canvas; //画布
  8749. this.Data;
  8750. this.Symbol;
  8751. this.HQChart;
  8752. this.HPenType=0; //水平线样式 0=虚线 1=实线
  8753. this.VPenType=0; //垂直线颜色 0=虚线 1=实线
  8754. this.LineDash=g_JSChartResource.DepthCorss.LineDash;
  8755. this.AskColor=g_JSChartResource.DepthCorss.AskColor.Line; //卖
  8756. this.BidColor=g_JSChartResource.DepthCorss.BidColor.Line; //买
  8757. this.LineWidth=g_JSChartResource.DepthCorss.LineWidth;
  8758. this.IsShowTooltip=true;
  8759. this.Tooltip=
  8760. {
  8761. LineHeight:g_JSChartResource.DepthCorss.Tooltip.LineHeight,
  8762. Border:
  8763. {
  8764. Top:g_JSChartResource.DepthCorss.Tooltip.Border.Top,
  8765. Left:g_JSChartResource.DepthCorss.Tooltip.Border.Left,
  8766. Right:g_JSChartResource.DepthCorss.Tooltip.Border.Right,
  8767. Bottom:g_JSChartResource.DepthCorss.Tooltip.Border.Bottom,
  8768. ItemSpace: g_JSChartResource.DepthCorss.Tooltip.Border.ItemSpace
  8769. },
  8770. Font:g_JSChartResource.DepthCorss.Tooltip.Font,
  8771. TextColor:g_JSChartResource.DepthCorss.Tooltip.TextColor,
  8772. BGColor:g_JSChartResource.DepthCorss.Tooltip.BGColor
  8773. }; // Width: Height:
  8774. this.Font=g_JSChartResource.CorssCursorTextFont; //字体
  8775. this.TextColor=g_JSChartResource.CorssCursorTextColor; //文本颜色
  8776. this.TextBGColor=g_JSChartResource.CorssCursorBGColor; //文本背景色
  8777. this.TextHeight=20; //文本字体高度
  8778. this.LastPoint;
  8779. this.PointX;
  8780. this.PointY;
  8781. this.StringFormatX;
  8782. this.StringFormatY;
  8783. this.IsShowCorss=true; //是否显示十字光标
  8784. this.IsShow=true;
  8785. this.GetVol=function(price, isAsk)
  8786. {
  8787. if (!this.Data) return null;
  8788. var aryData=isAsk? this.Data.Asks:this.Data.Bids;
  8789. if (!aryData || !Array.isArray(aryData) || aryData.length<=0) return null;
  8790. for(var i in aryData)
  8791. {
  8792. var item=aryData[i];
  8793. if (item.Price==price) return item.Vol;
  8794. }
  8795. return null;
  8796. }
  8797. this.Draw=function()
  8798. {
  8799. this.Status=0;
  8800. if (!this.LastPoint) return;
  8801. if (!this.Data) return;
  8802. if (!this.IsShow) return;
  8803. var x=this.LastPoint.X;
  8804. var y=this.LastPoint.Y;
  8805. var isInClient=false;
  8806. var rtClient = new Rect(this.Frame.ChartBorder.GetLeft(), this.Frame.ChartBorder.GetTop(), this.Frame.ChartBorder.GetWidth(), this.Frame.ChartBorder.GetHeight());
  8807. isInClient = rtClient.IsPointIn(x, y);
  8808. this.PointY=null;
  8809. this.PointY==null;
  8810. if (!isInClient) return;
  8811. if (this.Frame.IsHScreen===true)
  8812. {
  8813. return;
  8814. }
  8815. var left=this.Frame.ChartBorder.GetLeft();
  8816. var right=this.Frame.ChartBorder.GetRight();
  8817. var top=this.Frame.ChartBorder.GetTopTitle();
  8818. var bottom=this.Frame.ChartBorder.GetBottom();
  8819. var rightWidth=this.Frame.ChartBorder.Right;
  8820. var chartRight=this.Frame.ChartBorder.GetChartWidth();
  8821. var xValue=this.Frame.GetXData(x);
  8822. var xInfo=this.Frame.GetXFromPrice(xValue); //调整价格到有数据的点上
  8823. if (!xInfo) return;
  8824. var yVol=this.GetVol(xInfo.Price, xInfo.IsAsk);
  8825. y=this.Frame.GetYFromData(yVol); //调整Y轴, 让它在线段上
  8826. xInfo.Vol=yVol;
  8827. xInfo.Y=y;
  8828. this.PointY=[[left,y],[right,y]];
  8829. this.PointX=[[x,top],[x,bottom]];
  8830. if (this.IsShowCorss)
  8831. {
  8832. if (xInfo.IsAsk) this.Canvas.strokeStyle=this.AskColor;
  8833. else this.Canvas.strokeStyle=this.BidColor;
  8834. this.Canvas.save();
  8835. this.Canvas.lineWidth=this.LineWidth;
  8836. var lineWidth=this.Canvas.lineWidth;
  8837. if (this.HPenType==1 || this.HPenType==0) //0=实线 1=虚线
  8838. {
  8839. if (this.HPenType==0) this.Canvas.setLineDash(this.LineDash); //虚线
  8840. var yFix=ToFixedPoint(y);
  8841. this.Canvas.beginPath();
  8842. this.Canvas.moveTo(left,yFix);
  8843. this.Canvas.lineTo(right,yFix);
  8844. this.Canvas.stroke();
  8845. if (this.HPenType==0) this.Canvas.setLineDash([]);
  8846. }
  8847. if (this.VPenType==0) this.Canvas.setLineDash(this.LineDash); //虚线
  8848. var xFix=ToFixedPoint(xInfo.X);
  8849. this.Canvas.beginPath();
  8850. this.Canvas.moveTo(xFix,top);
  8851. this.Canvas.lineTo(xFix,bottom);
  8852. this.Canvas.stroke();
  8853. if (this.VPenType==0) this.Canvas.setLineDash([]);
  8854. this.Canvas.restore();
  8855. }
  8856. if (this.HQChart)
  8857. {
  8858. var event=this.HQChart.GetEvent(JSCHART_EVENT_ID.ON_DRAW_DEPTH_TOOLTIP);
  8859. if (event)
  8860. {
  8861. event.Callback(event,xInfo,this);
  8862. }
  8863. }
  8864. if (this.IsShowTooltip)
  8865. {
  8866. var aryText=this.GetFormatTooltip(xInfo);
  8867. this.DrawTooltip(aryText, xInfo);
  8868. }
  8869. }
  8870. //[{Title:, TitleColor:, Text:, Color:}]
  8871. this.GetFormatTooltip=function(drawData)
  8872. {
  8873. var aryText=[];
  8874. var floatPrecision=2;
  8875. if (this.Symbol) floatPrecision=JSCommonCoordinateData.GetfloatPrecision(this.Symbol); //价格小数位数
  8876. var item=
  8877. {
  8878. Title:g_JSChartLocalization.GetText('Depth-Price',this.HQChart.LanguageID),
  8879. TitleColor:this.Tooltip.TextColor,
  8880. Text:drawData.Price.toFixed(floatPrecision),
  8881. Color:this.Tooltip.TextColor
  8882. };
  8883. aryText.push(item);
  8884. var item=
  8885. {
  8886. Title:g_JSChartLocalization.GetText('Depth-Sum',this.HQChart.LanguageID),
  8887. TitleColor:this.Tooltip.TextColor,
  8888. Text:drawData.Vol.toFixed(4),
  8889. Color:this.Tooltip.TextColor
  8890. };
  8891. aryText.push(item);
  8892. return aryText;
  8893. }
  8894. this.DrawTooltip=function(aryText,data)
  8895. {
  8896. if (!IFrameSplitOperator.IsNonEmptyArray(aryText)) return;
  8897. this.Canvas.font=this.Tooltip.Font;
  8898. var maxWidth=0, lineCount=0, itemCount=0;
  8899. for(var i=0;i<aryText.length;++i)
  8900. {
  8901. var item=aryText[i];
  8902. if (!item) continue;
  8903. var isVaild=false;
  8904. if (item.Title)
  8905. {
  8906. var textWidth=this.Canvas.measureText(item.Title).width;
  8907. if (maxWidth<textWidth) maxWidth=textWidth;
  8908. ++lineCount;
  8909. isVaild=true;
  8910. }
  8911. if (item.Text)
  8912. {
  8913. var textWidth=this.Canvas.measureText(item.Text).width;
  8914. if (maxWidth<textWidth) maxWidth=textWidth;
  8915. ++lineCount;
  8916. isVaild=true;
  8917. }
  8918. if (isVaild) ++itemCount;
  8919. }
  8920. if (maxWidth<=0 || lineCount<=0) return;
  8921. var border=this.Tooltip.Border;
  8922. var chartRight=this.Frame.ChartBorder.GetRight();
  8923. var chartTop=this.Frame.ChartBorder.GetTop();
  8924. this.Tooltip.LineHeight=this.Canvas.measureText("擎").width+2;
  8925. this.Tooltip.Width=maxWidth+(border.Left+border.Right);
  8926. this.Tooltip.Height=this.Tooltip.LineHeight*lineCount + (border.Top+border.Bottom) + (border.ItemSpace)*(itemCount-1);
  8927. var left=data.X;
  8928. var top=data.Y-this.Tooltip.Height
  8929. if (left+this.Tooltip.Width>=chartRight) left=data.X-this.Tooltip.Width;
  8930. if (top<chartTop) top=data.Y;
  8931. this.Canvas.fillStyle=this.Tooltip.BGColor;
  8932. this.Canvas.fillRect(left,top,this.Tooltip.Width,this.Tooltip.Height);
  8933. this.Canvas.textBaseline="top";
  8934. this.Canvas.textAlign="left";
  8935. var x=border.Left+left;
  8936. var y=border.Top+top;
  8937. for(var i=0;i<aryText.length;++i)
  8938. {
  8939. var item=aryText[i];
  8940. var isVaild=false;
  8941. if (item.Title)
  8942. {
  8943. if (item.TitleColor) this.Canvas.fillStyle=item.TitleColor;
  8944. else this.Canvas.fillStyle=this.Tooltip.TextColor;
  8945. this.Canvas.fillText(item.Title,x,y);
  8946. y+=this.Tooltip.LineHeight;
  8947. isVaild=true;
  8948. }
  8949. if (item.Text)
  8950. {
  8951. if (item.Color) this.Canvas.fillStyle=item.Color;
  8952. else this.Canvas.fillStyle=this.Tooltip.TextColor;
  8953. this.Canvas.fillText(item.Text,x,y);
  8954. y+=this.Tooltip.LineHeight;
  8955. isVaild=true;
  8956. }
  8957. if (isVaild) y+=border.ItemSpace;
  8958. }
  8959. }
  8960. }
  8961. //深度图
  8962. function ChartOrderbookDepth()
  8963. {
  8964. this.newMethod=IChartPainting; //派生
  8965. this.newMethod();
  8966. delete this.newMethod;
  8967. this.ClassName="ChartOrderbookDepth";
  8968. this.Data=null;
  8969. this.AskColor={ Line:g_JSChartResource.DepthChart.AskColor.Line, Area:g_JSChartResource.DepthChart.AskColor.Area } //卖
  8970. this.BidColor={ Line:g_JSChartResource.DepthChart.BidColor.Line, Area:g_JSChartResource.DepthChart.BidColor.Area } //买
  8971. this.LineWidth=g_JSChartResource.DepthChart.LineWidth;
  8972. this.Draw=function()
  8973. {
  8974. if (!this.Data) return;
  8975. this.Canvas.save();
  8976. this.Canvas.lineWidth=this.LineWidth;
  8977. this.DrawArea(this.Data.Bids, this.BidColor.Line, this.BidColor.Area, true);
  8978. this.DrawArea(this.Data.Asks, this.AskColor.Line, this.AskColor.Area, false);
  8979. this.Canvas.restore();
  8980. }
  8981. this.DrawArea=function(aryData, colorLine, colorArea, isLeft)
  8982. {
  8983. var xRange=this.ChartFrame.VerticalRange;
  8984. var aryPoint=[];
  8985. for(var i in aryData)
  8986. {
  8987. var item=aryData[i];
  8988. if (isLeft)
  8989. {
  8990. if (item.Price<xRange.Min) break;
  8991. }
  8992. else
  8993. {
  8994. if (item.Price>xRange.Max) break;
  8995. }
  8996. var x=this.ChartFrame.GetXFromIndex(item.Price);
  8997. var y=this.ChartFrame.GetYFromData(item.Vol);
  8998. aryPoint.push({X:x,Y:y});
  8999. }
  9000. if (aryPoint.length<=1) return;
  9001. var left=this.ChartBorder.GetLeft();
  9002. var bottom=this.ChartBorder.GetBottom();
  9003. var right=this.ChartBorder.GetRight();
  9004. this.Canvas.beginPath();
  9005. this.Canvas.moveTo(aryPoint[0].X, bottom);
  9006. for(var i in aryPoint)
  9007. {
  9008. var item=aryPoint[i];
  9009. this.Canvas.lineTo(item.X,item.Y);
  9010. }
  9011. this.Canvas.lineTo(isLeft?left:right,aryPoint[aryPoint.length-1].Y);
  9012. this.Canvas.lineTo(isLeft?left:right,bottom);
  9013. this.Canvas.lineTo(aryPoint[0].X,bottom);
  9014. this.Canvas.closePath();
  9015. this.Canvas.fillStyle = colorArea;
  9016. this.Canvas.fill();
  9017. this.Canvas.beginPath();
  9018. this.Canvas.moveTo(aryPoint[0].X, bottom);
  9019. for(var i in aryPoint)
  9020. {
  9021. var item=aryPoint[i];
  9022. this.Canvas.lineTo(item.X,item.Y);
  9023. }
  9024. this.Canvas.lineTo(isLeft?left:right,aryPoint[aryPoint.length-1].Y);
  9025. this.Canvas.strokeStyle=colorLine;
  9026. this.Canvas.stroke();
  9027. }
  9028. this.GetMaxMin=function()
  9029. {
  9030. var range={ Min:null, Max:null, XMin:null, XMax:null };
  9031. var xRange=this.ChartFrame.VerticalRange;
  9032. for(var i in this.Data.Asks)
  9033. {
  9034. var item=this.Data.Asks[i];
  9035. if (item.Price>xRange.Max) break;
  9036. if (range.XMin==null || range.XMin>item.Price) range.XMin=item.Price;
  9037. if (range.XMax==null || range.XMax<item.Price) range.XMax=item.Price;
  9038. if (range.Min==null || range.Min>item.Vol) range.Min=item.Vol;
  9039. if (range.Max==null || range.Max<item.Vol) range.Max=item.Vol;
  9040. }
  9041. for(var i in this.Data.Bids)
  9042. {
  9043. var item=this.Data.Bids[i];
  9044. if (item.Price<xRange.Min) break;
  9045. if (range.XMin==null || range.XMin>item.Price) range.XMin=item.Price;
  9046. if (range.XMax==null || range.XMax<item.Price) range.XMax=item.Price;
  9047. if (range.Min==null || range.Min>item.Vol) range.Min=item.Vol;
  9048. if (range.Max==null || range.Max<item.Vol) range.Max=item.Vol;
  9049. }
  9050. return range;
  9051. }
  9052. }
  9053. ///////////////////////////////////////////////////////////////////////////////////////
  9054. // 公共函数
  9055. //修正线段有毛刺
  9056. function ToFixedPoint(value)
  9057. {
  9058. //return value;
  9059. return parseInt(value) + 0.5;
  9060. }
  9061. function ToFixedRect(value)
  9062. {
  9063. var rounded;
  9064. return rounded = (0.5 + value) << 0;
  9065. }
  9066. //导出统一使用JSCommon命名空间名
  9067. export
  9068. {
  9069. IChartPainting,
  9070. ChartKLine,
  9071. ChartColorKline,
  9072. ChartLine,
  9073. ChartArea,
  9074. ChartStepLine,
  9075. ChartSubLine,
  9076. ChartSingleText,
  9077. ChartDrawIcon,
  9078. ChartDrawText,
  9079. ChartDrawNumber,
  9080. ChartPointDot,
  9081. ChartStick,
  9082. ChartLineStick,
  9083. ChartStickLine,
  9084. ChartBackground,
  9085. ChartBackgroundDiv,
  9086. ChartMinuteVolumBar,
  9087. ChartOverlayKLine,
  9088. ChartLock,
  9089. ChartVolStick,
  9090. ChartBand,
  9091. ChartMinutePriceLine,
  9092. ChartOverlayMinutePriceLine,
  9093. ChartLineMultiData,
  9094. ChartStraightLine,
  9095. ChartPie,
  9096. ChartCircle,
  9097. ChartChinaMap,
  9098. ChartRadar,
  9099. ChartMinuteInfo,
  9100. ChartRectangle,
  9101. ChartMultiText,
  9102. ChartMultiLine,
  9103. ChartMultiPoint,
  9104. ChartMultiHtmlDom,
  9105. ChartMultiBar,
  9106. ChartBuySell,
  9107. ChartMACD,
  9108. ChartStackedBar,
  9109. ChartText,
  9110. ChartStraightArea,
  9111. ChartCorssCursor,
  9112. DepthChartCorssCursor,
  9113. ChartOrderbookDepth,
  9114. ChartSplashPaint,
  9115. GetFontHeight,
  9116. ColorToRGBA,
  9117. ChartSingleLine,
  9118. };
  9119. /*
  9120. module.exports =
  9121. {
  9122. JSCommonChartPaint:
  9123. {
  9124. IChartPaintin: IChartPainting,
  9125. ChartKLine: ChartKLine,
  9126. ChartColorKline:ChartColorKline,
  9127. ChartLine: ChartLine,
  9128. ChartSubLine: ChartSubLine,
  9129. ChartSingleText: ChartSingleText,
  9130. ChartDrawIcon:ChartDrawIcon,
  9131. ChartDrawText:ChartDrawText,
  9132. ChartDrawNumber:ChartDrawNumber,
  9133. ChartPointDot: ChartPointDot,
  9134. ChartStick: ChartStick,
  9135. ChartLineStick: ChartLineStick,
  9136. ChartStickLine: ChartStickLine,
  9137. ChartOverlayKLine: ChartOverlayKLine,
  9138. ChartMinuteInfo: ChartMinuteInfo,
  9139. ChartRectangle: ChartRectangle,
  9140. ChartMultiText: ChartMultiText,
  9141. ChartMultiHtmlDom:ChartMultiHtmlDom,
  9142. ChartMultiLine: ChartMultiLine,
  9143. ChartBackground:ChartBackground,
  9144. ChartBuySell: ChartBuySell,
  9145. ChartMultiBar: ChartMultiBar,
  9146. ChartMACD:ChartMACD,
  9147. ChartMinutePriceLine:ChartMinutePriceLine,
  9148. ChartLock:ChartLock,
  9149. ChartVolStick:ChartVolStick,
  9150. ChartBand:ChartBand,
  9151. ChartMinuteVolumBar:ChartMinuteVolumBar,
  9152. ChartText:ChartText,
  9153. ChartOverlayMinutePriceLine:ChartOverlayMinutePriceLine,
  9154. ChartLineMultiData:ChartLineMultiData,
  9155. ChartStraightLine:ChartStraightLine,
  9156. ChartStraightArea:ChartStraightArea,
  9157. ChartSplashPaint:ChartSplashPaint,
  9158. ChartPie: ChartPie,
  9159. ChartCircle: ChartCircle,
  9160. ChartChinaMap: ChartChinaMap,
  9161. ChartRadar: ChartRadar,
  9162. ChartCorssCursor: ChartCorssCursor, //十字光标
  9163. DepthChartCorssCursor:DepthChartCorssCursor,
  9164. ChartOrderbookDepth:ChartOrderbookDepth,
  9165. },
  9166. //单个类导出
  9167. JSCommonChartPaint_IChartPainting: IChartPainting,
  9168. JSCommonChartPaint_ChartKLine: ChartKLine,
  9169. JSCommonChartPaint_ChartColorKline:ChartColorKline,
  9170. JSCommonChartPaint_ChartLine: ChartLine,
  9171. JSCommonChartPaint_ChartSubLine: ChartSubLine,
  9172. JSCommonChartPaint_ChartSingleText: ChartSingleText,
  9173. JSCommonChartPaint_ChartDrawIcon:ChartDrawIcon,
  9174. JSCommonChartPaint_ChartDrawText:ChartDrawText,
  9175. JSCommonChartPaint_ChartDrawNumber:ChartDrawNumber,
  9176. JSCommonChartPaint_ChartPointDot: ChartPointDot,
  9177. JSCommonChartPaint_ChartStick: ChartStick,
  9178. JSCommonChartPaint_ChartLineStick: ChartLineStick,
  9179. JSCommonChartPaint_ChartStickLine: ChartStickLine,
  9180. JSCommonChartPaint_ChartBackground:ChartBackground,
  9181. JSCommonChartPaint_ChartMinuteVolumBar:ChartMinuteVolumBar,
  9182. JSCommonChartPaint_ChartOverlayKLine: ChartOverlayKLine,
  9183. JSCommonChartPaint_ChartLock:ChartLock,
  9184. JSCommonChartPaint_ChartVolStick:ChartVolStick,
  9185. JSCommonChartPaint_ChartBand:ChartBand,
  9186. JSCommonChartPaint_ChartMinutePriceLine:ChartMinutePriceLine,
  9187. JSCommonChartPaint_ChartOverlayMinutePriceLine:ChartOverlayMinutePriceLine,
  9188. JSCommonChartPaint_ChartLineMultiData:ChartLineMultiData,
  9189. JSCommonChartPaint_ChartStraightLine:ChartStraightLine,
  9190. JSCommonChartPaint_ChartPie: ChartPie,
  9191. JSCommonChartPaint_ChartCircle: ChartCircle,
  9192. JSCommonChartPaint_ChartChinaMap: ChartChinaMap,
  9193. JSCommonChartPaint_ChartRadar: ChartRadar,
  9194. JSCommonChartPaint_ChartMinuteInfo: ChartMinuteInfo,
  9195. JSCommonChartPaint_ChartRectangle: ChartRectangle,
  9196. JSCommonChartPaint_ChartMultiText: ChartMultiText,
  9197. JSCommonChartPaint_ChartMultiLine: ChartMultiLine,
  9198. JSCommonChartPaint_ChartMultiHtmlDom: ChartMultiHtmlDom,
  9199. JSCommonChartPaint_ChartMultiBar: ChartMultiBar,
  9200. JSCommonChartPaint_ChartBuySell: ChartBuySell,
  9201. JSCommonChartPaint_ChartMACD: ChartMACD,
  9202. JSCommonChartPaint_ChartText:ChartText,
  9203. JSCommonChartPaint_ChartStraightArea:ChartStraightArea,
  9204. JSCommonChartPaint_ChartCorssCursor: ChartCorssCursor,
  9205. JSCommonChartPaint_DepthChartCorssCursor:DepthChartCorssCursor,
  9206. JSCommonChartPaint_ChartOrderbookDepth:ChartOrderbookDepth,
  9207. JSCommonChartPaint_ChartSplashPaint:ChartSplashPaint,
  9208. JSCommonChartPaint_GetFontHeight:GetFontHeight,
  9209. };
  9210. */