hqchart 1.1.12733 → 1.1.12734

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2203 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////
2
+ // 股票分析思维导图
3
+ // 注:include umychart.js
4
+ /////////////////////////////////////////////////////////////////////////////////////
5
+
6
+ var JSMIND_NODE_ID =
7
+ {
8
+ TABLE_NODE:1, //表格节点
9
+ TEXT_NODE:2, //文本节点
10
+ KLINE_NODE:3 //K线图
11
+ }
12
+
13
+ function JSMindNode()
14
+ {
15
+ this.Name;
16
+ this.ID=Guid();
17
+ this.Title;
18
+ this.ChartPaint=[];
19
+
20
+ this.Data; //原始的数据
21
+ this.Position={}; //绘制的位置{X:, Y:, Width, Height}
22
+ this.ScpritOption; //脚本指标设置 {}
23
+ this.NodeType=0;
24
+
25
+ this.Scprit; //ScriptIndexConsole
26
+ this.Children=[]; //子节点
27
+
28
+ this.CreateScprit=function(obj)
29
+ {
30
+ var indexOption=
31
+ {
32
+ Name:obj.Name, ID:this.ID, Args:obj.Args, Script:obj.Script, IsSectionMode:obj.IsSectionMode,
33
+ ErrorCallback:obj.ErrorCallback, FinishCallback:obj.FinishCallback
34
+ };
35
+ console.log('[JSMindNode::CreateScprit] indexOption, node ' , indexOption, this)
36
+ this.Scprit=new ScriptIndexConsole(indexOption);
37
+ }
38
+
39
+ this.SetSelected=function(selected)
40
+ {
41
+ for(var i in this.ChartPaint)
42
+ {
43
+ var item=this.ChartPaint[i];
44
+ item.IsSelected=selected;
45
+ }
46
+ }
47
+
48
+ this.Move=function(xStep, yStep)
49
+ {
50
+ this.Position.X+=xStep;
51
+ this.Position.Y+=yStep;
52
+ }
53
+
54
+ this.Draw=function()
55
+ {
56
+ for(var i in this.ChartPaint)
57
+ {
58
+ var item=this.ChartPaint[i];
59
+ item.Draw();
60
+ }
61
+ }
62
+
63
+ this.SetData=function(data,jsExectute)
64
+ {
65
+ switch(this.NodeType)
66
+ {
67
+ case JSMIND_NODE_ID.TABLE_NODE:
68
+ return this.SetTableData(data,jsExectute);
69
+ default:
70
+ return false;
71
+ }
72
+ }
73
+
74
+ this.SetTableData=function(data,jsExectute)
75
+ {
76
+ this.Data=data;
77
+
78
+ var outVar=data.Out;
79
+ var header=[], body=[];
80
+ var headerFont=new JSFont();
81
+ var colFont=new JSFont();
82
+ headerFont.Color='rgb(51,51,51)';
83
+ colFont.Color='rgb(51,51,51)'
84
+ for(var i in outVar)
85
+ {
86
+ var item=outVar[i];
87
+ var headerItem={Name:item.Name, Font:headerFont};
88
+ header.push(headerItem);
89
+
90
+ var colItem={Text:item.Data.toString(), Value:item.Data };
91
+ body.push(colItem);
92
+ }
93
+
94
+
95
+ var chart=this.ChartPaint[0];
96
+ chart.Data={ Header:[header], Body:[body] };
97
+ return true;
98
+ }
99
+
100
+ this.SetSizeChange=function(bChanged)
101
+ {
102
+ for(var i in this.ChartPaint)
103
+ {
104
+ var item=this.ChartPaint[i];
105
+ item.SizeChange=bChanged;
106
+ }
107
+ }
108
+ }
109
+
110
+ function JSFont()
111
+ {
112
+ this.Color='rgb(0,0,0)'; //颜色,
113
+ this.Name='微软雅黑'; //字体名字,
114
+ this.Size=12; // 字体大小
115
+
116
+ this.GetFont=function()
117
+ {
118
+ return `${this.Size*GetDevicePixelRatio()}px ${this.Name}`;
119
+ }
120
+
121
+ this.GetFontHeight=function()
122
+ {
123
+ return this.Size*GetDevicePixelRatio();
124
+ }
125
+ }
126
+
127
+
128
+ function JSMindContainer(uielement)
129
+ {
130
+ this.ClassName='JSMindContainer';
131
+ this.Frame; //框架画法
132
+ this.Nodes=[]; //JSMindNode
133
+ this.Canvas=uielement.getContext("2d"); //画布
134
+ this.LinesPaint=new NodeLinesPaint();
135
+ this.LinesPaint.Canvas=this.Canvas;
136
+ this.UIElement=uielement;
137
+ this.MouseDrag;
138
+ this.DragMode=1;
139
+ this.SelectedNode=null; //当前选中节点
140
+ this.Symbol;
141
+
142
+ this.Create=function(obj)
143
+ {
144
+ this.UIElement.JSMindContainer=this;
145
+ }
146
+
147
+ uielement.onmousedown=function(e)
148
+ {
149
+ if(!this.JSMindContainer) return;
150
+ var self=this.JSMindContainer;
151
+ if(self.DragMode==0) return;
152
+
153
+ var drag=
154
+ {
155
+ "Click":{},
156
+ "LastMove":{} //最后移动的位置
157
+ };
158
+
159
+ drag.Click.X=e.clientX;
160
+ drag.Click.Y=e.clientY;
161
+ drag.LastMove.X=e.clientX;
162
+ drag.LastMove.Y=e.clientY;
163
+
164
+ self.MouseDrag=drag;
165
+ document.JSMindContainer=self;
166
+ var oldSelectedNode=self.SelectedNode;
167
+ var pixelTatio = GetDevicePixelRatio();
168
+
169
+ var pt={};
170
+ pt.X=(e.clientX-this.getBoundingClientRect().left)*pixelTatio;
171
+ pt.Y=(e.clientY-this.getBoundingClientRect().top)*pixelTatio;
172
+ var selectedNode=self.GetNodeByPoint(pt);
173
+ self.SelectedNode=selectedNode;
174
+
175
+ if (selectedNode!=oldSelectedNode)
176
+ {
177
+ if (oldSelectedNode) oldSelectedNode.SetSelected(false);
178
+ if (selectedNode) selectedNode.SetSelected(true);
179
+ self.Draw();
180
+ }
181
+
182
+ /*
183
+ uielement.ondblclick=function(e)
184
+ {
185
+ var x = e.clientX-this.getBoundingClientRect().left;
186
+ var y = e.clientY-this.getBoundingClientRect().top;
187
+
188
+ if(this.JSChartContainer)
189
+ this.JSChartContainer.OnDoubleClick(x,y,e);
190
+ }
191
+ */
192
+
193
+ document.onmousemove=function(e)
194
+ {
195
+ if(!this.JSMindContainer) return;
196
+ var self=this.JSMindContainer;
197
+ var drag=self.MouseDrag;
198
+ if (!drag) return;
199
+
200
+ var moveSetp=Math.abs(drag.LastMove.X-e.clientX);
201
+
202
+ if (self.SelectedNode)
203
+ {
204
+ if(Math.abs(drag.LastMove.X-e.clientX)<5 && Math.abs(drag.LastMove.Y-e.clientY)<5) return;
205
+
206
+ if(self.MoveNode(e.clientX-drag.LastMove.X,e.clientY-drag.LastMove.Y))
207
+ {
208
+ self.Draw();
209
+ }
210
+
211
+ drag.LastMove.X=e.clientX;
212
+ drag.LastMove.Y=e.clientY;
213
+ }
214
+ };
215
+
216
+ document.onmouseup=function(e)
217
+ {
218
+ //清空事件
219
+ document.onmousemove=null;
220
+ document.onmouseup=null;
221
+
222
+ //清空数据
223
+ console.log('[JSMindContainer::document.onmouseup]',e);
224
+ this.JSMindContainer.UIElement.style.cursor="default";
225
+ this.JSMindContainer.MouseDrag=null;
226
+ this.JSMindContainer=null;
227
+ }
228
+ }
229
+
230
+ this.Draw=function()
231
+ {
232
+ if (this.UIElement.width<=0 || this.UIElement.height<=0) return;
233
+ this.Canvas.clearRect(0,0,this.UIElement.width,this.UIElement.height);
234
+
235
+ for(var i in this.Nodes)
236
+ {
237
+ var item=this.Nodes[i];
238
+ item.Draw();
239
+ }
240
+
241
+ this.LinesPaint.SetNodes(this.Nodes);
242
+ this.LinesPaint.Draw();
243
+ }
244
+
245
+ this.GetNodeByPoint=function(pt)
246
+ {
247
+ for(var i in this.Nodes)
248
+ {
249
+ var node=this.Nodes[i];
250
+ for(var j in node.ChartPaint)
251
+ {
252
+ var item=node.ChartPaint[j];
253
+ if (item.IsPointIn(pt)==1) return node;
254
+ }
255
+ }
256
+
257
+ return null;
258
+ }
259
+
260
+ this.MoveNode=function(xStep,yStep)
261
+ {
262
+ if (!this.SelectedNode) return false;
263
+
264
+ this.SelectedNode.Move(xStep,yStep);
265
+ return true;
266
+ }
267
+
268
+ //添加一个节点 {Name:, Title:, DataScprit:, NodeType:}
269
+ this.AddNode=function(obj,nodeType)
270
+ {
271
+ if (nodeType==JSMIND_NODE_ID.KLINE_NODE) return this.AddKLineNode(obj);
272
+
273
+ var self=this;
274
+ var node=new JSMindNode();
275
+ node.Name=obj.Name;
276
+ if (obj.Title) node.Title=obj.Title;
277
+ if (obj.ID) node.ID=obj.ID; //外部可以指定id,但必须是唯一的
278
+ node.NodeType=nodeType;
279
+ node.Position=obj.Position;
280
+ if (obj.Index) //创建指标脚本
281
+ {
282
+ var indexInfo=
283
+ {
284
+ Name:obj.Index.Name, Args:obj.Index.Args, Script:obj.Index.Script, IsSectionMode:false,
285
+ ErrorCallback: function(error) { self.ExecuteError(node,error); },
286
+ FinishCallback:function(data, jsExectute) { self.ExecuteFinish(node, data, jsExectute); }
287
+ };
288
+
289
+ if (obj.Index.IsSectionMode==true) indexInfo.IsSectionMode=true;
290
+ node.CreateScprit(indexInfo);
291
+ }
292
+
293
+ var chart=null;
294
+ switch(nodeType)
295
+ {
296
+ case JSMIND_NODE_ID.TABLE_NODE:
297
+ chart=new TableNodeChartPaint();
298
+ if (obj.ShowMode>=1) chart.ShowMode=obj.ShowMode; //显示模式
299
+ break;
300
+ case JSMIND_NODE_ID.TEXT_NODE:
301
+ chart=new TextNodeChartPaint()
302
+ if (obj.Content) chart.Data.Content=obj.Content;
303
+ break;
304
+ default:
305
+ return null;
306
+ }
307
+
308
+ chart.Canvas=this.Canvas;
309
+ chart.Title=obj.Title;
310
+ chart.Position=node.Position;
311
+ node.ChartPaint.push(chart);
312
+ this.Nodes.push(node);
313
+
314
+ return node;
315
+ }
316
+
317
+ this.AddTableNode=function(obj)
318
+ {
319
+ return this.AddNode(obj,JSMIND_NODE_ID.TABLE_NODE);
320
+ }
321
+
322
+ this.AddTextNode=function(obj)
323
+ {
324
+ return this.AddNode(obj,JSMIND_NODE_ID.TEXT_NODE);
325
+ }
326
+
327
+ this.AddKLineNode=function(obj)
328
+ {
329
+ var self=this;
330
+ var node=new JSMindNode();
331
+ node.Name=obj.Name;
332
+ if (obj.Title) node.Title=obj.Title;
333
+ if (obj.ID) node.ID=obj.ID; //外部可以指定id,但必须是唯一的
334
+ node.NodeType=JSMIND_NODE_ID.KLINE_NODE;
335
+ node.Position=obj.Position;
336
+
337
+ chart=new KLineNodeChartPaint();
338
+ chart.Canvas=this.Canvas;
339
+ chart.Title=obj.Title;
340
+ chart.SetOption(obj);
341
+ chart.Position=node.Position;
342
+ node.ChartPaint.push(chart);
343
+ this.Nodes.push(node);
344
+ return node;
345
+ }
346
+
347
+ this.ExecuteAllScript=function()
348
+ {
349
+ var stockObj=
350
+ {
351
+ HQDataType:HQ_DATA_TYPE.KLINE_ID,
352
+ Stock: {Symbol:this.Symbol},
353
+ Request: { MaxDataCount: 500, MaxMinuteDayCount:5 },
354
+ Period:0 , Right:0
355
+ };
356
+
357
+ for(var i in this.Nodes)
358
+ {
359
+ var item=this.Nodes[i];
360
+ if (item.NodeType==JSMIND_NODE_ID.KLINE_NODE)
361
+ {
362
+ item.ChartPaint[0].ChangeSymbol(this.Symbol);
363
+ }
364
+ else
365
+ {
366
+ if (!item.Scprit) continue;
367
+ item.Scprit.ExecuteScript(stockObj);
368
+ }
369
+ }
370
+ }
371
+
372
+ this.ExecuteError=function(node,error)
373
+ {
374
+ console.log('[JSMindContainer::ExecuteError] node, error ', node, error);
375
+ }
376
+
377
+ this.ExecuteFinish=function(node, data, jsExectute)
378
+ {
379
+ console.log('[JSMindContainer::ExecuteFinish] node, data, jsExectute ', node, data, jsExectute);
380
+
381
+ if (node.SetData(data,jsExectute))
382
+ {
383
+ node.SetSizeChange(true);
384
+ this.Draw();
385
+ }
386
+ }
387
+
388
+ this.LoadNodeData=function(data) //加载节点树
389
+ {
390
+ for(var i in data.Root)
391
+ {
392
+ var item=data.Root[i];
393
+ this.LoadRootNode(item);
394
+ }
395
+
396
+ if (data.Lines) this.LoadNodeLines(data);
397
+ }
398
+
399
+ this.LoadRootNode=function(node) //加载主节点
400
+ {
401
+ var jsNode=this.AddNode(node, node.Type);
402
+
403
+ if (node.Children)
404
+ {
405
+ for(var j in node.Children)
406
+ {
407
+ var childItem=node.Children[j];
408
+ this.LoadChildNode(childItem,jsNode);
409
+ }
410
+ }
411
+ }
412
+
413
+ this.LoadChildNode=function(node,parentJSNode) //加载子节点
414
+ {
415
+ if (!node || !parentJSNode) return;
416
+
417
+ var jsNode=this.AddNode(node,node.Type);
418
+ if (!jsNode) return;
419
+
420
+ if (node.Children)
421
+ {
422
+ for(var i in item.Children)
423
+ {
424
+ var childItem=item.Children[i];
425
+ this.LoadChildNode(childItem,jsNode);
426
+ }
427
+ }
428
+
429
+ parentJSNode.Children.push(jsNode);
430
+ }
431
+
432
+ this.LoadNodeLines=function(data)
433
+ {
434
+ var lines=data.Lines;
435
+ var linesData=[];
436
+ for(var i in lines)
437
+ {
438
+ var item=lines[i];
439
+ var line={Start:item.Start, End:item.End, Type:0 };
440
+ if (item.Type>=1) line.Type=item.Type;
441
+ linesData.push(line);
442
+ }
443
+
444
+ this.LinesPaint.Data=linesData;
445
+ }
446
+ }
447
+
448
+
449
+ function INodeChartPainting()
450
+ {
451
+ this.Canvas; //画布
452
+ this.ChartBorder; //边框信息
453
+ this.Name; //名称
454
+ this.ClassName='INodeChartPainting'; //类名
455
+ this.SizeChange=true;
456
+ this.IsSelected=false; //是否被选中
457
+ this.SelectedColor='rgb(0,40,40)'; //选中点颜色
458
+ this.SelectedPointSize=4*GetDevicePixelRatio();
459
+
460
+ this.Title; //标题
461
+ this.TitleFont=new JSFont();
462
+ this.TittleBG='rgb(220,220,220)'; //标题背景颜色
463
+ this.PenBorder="rgb(105,105,105)"; //边框颜色
464
+ this.PixelRatio=GetDevicePixelRatio();;
465
+
466
+ this.Data; //数据区
467
+ this.Position;
468
+
469
+ this.Draw=function() { }
470
+
471
+ this.ToInt=function(value)
472
+ {
473
+ return Math.floor(value+0.5);
474
+ }
475
+
476
+ this.IsNull=function(value)
477
+ {
478
+ if (value===undefined) return true;
479
+ if (value===null) return true;
480
+ return false;
481
+ }
482
+
483
+ this.IsPointIn=function(pt) // -1=不在上面, 0=表头
484
+ {
485
+ return -1;
486
+ }
487
+ }
488
+
489
+
490
+
491
+ function TableNodeChartPaint()
492
+ {
493
+ this.newMethod=INodeChartPainting; //派生
494
+ this.newMethod();
495
+ delete this.newMethod;
496
+
497
+ this.ClassName='TableNodeChartPaint'; //类名
498
+ this.Data={Header:[], Body:[]};
499
+ //this.Data; [ [{ Name:列名1, Font:字体设置, ColFont:列字体(缺省使用Font) }, { Name:列名2, Font:字体设置 },], [{Text:显示内容, Value:数值, Font:}, ] ]
500
+ /*
501
+ this.Data={
502
+ Header:[ [
503
+ { Name:'列名1', Font:new JSFont() },
504
+ { Name:'列名2', Font:new JSFont(), ColFont:new JSFont() },
505
+ { Name:'列名3', Font:new JSFont(), ColFont:new JSFont() }
506
+ ] ],
507
+ Body:[
508
+ [ {Text:'显示内容1-1', Value:1 }, {Text:'显示内容1-2', Value:1 }, {Text:'显示内容1-3', Value:1 } ],
509
+ [ {Text:'显示内容(擎擎擎擎擎擎擎)2-1', Value:1 }, {Text:'显示内容2-2', Value:1 } ,{Text:'显示内容2-3', Value:1 }],
510
+ [ {Text:'显示内容3-1', Value:1 }, {Text:'显示内容(擎擎擎擎擎)3-2', Value:1 } ,{Text:'显示内容3-3', Value:1 }],
511
+ [ {Text:'显示内容4-1', Value:1 }, {Text:'显示内容4-2', Value:1 } ,{Text:'显示内容(擎擎)4-3', Value:1 }]
512
+ ]
513
+ };
514
+ */
515
+ this.ShowMode=1; //1 横向显示 2 竖向显示
516
+
517
+ this.HeaderCache; //横向 [ {Height:宽度 } ] | 竖向 [{Width:高度}]
518
+ this.ColumeCache; //[ {Height:, ColFont:}] | 竖向 [ {Width:} ]
519
+ this.RowHeightCache; //[{Height:,RowFont:}]
520
+ this.WidthCache; //整个宽度
521
+ this.HeightCache; //整个高度
522
+ this.TitleHeightCache;
523
+
524
+ this.X=0;
525
+ this.Y=0;
526
+ this.Width=0;
527
+
528
+ this.ColMargin={ Left:5, Top:5, Right:5, Bottom:5 };
529
+ this.TitleMargin={ Left:5, Top:5, Right:5, Bottom:5 };
530
+ this.HeaderMargin={ Left:5, Top:5, Right:5, Bottom:5 };
531
+
532
+ this.Draw=function()
533
+ {
534
+ this.X=this.Position.X;
535
+ this.Y=this.Position.Y;
536
+ this.Width=this.Position.Width;
537
+ this.PixelRatio=GetDevicePixelRatio();
538
+
539
+ if (this.ShowMode==2)
540
+ {
541
+ if (this.SizeChange==true) this.CacluateSize2();
542
+ this.DrawBorder2();
543
+ this.DrawTitle();
544
+ this.DrawHeader2();
545
+ this.DrawBody2();
546
+ }
547
+ else
548
+ {
549
+ if (this.SizeChange==true) this.CacluateSize()
550
+ this.DrawBorder();
551
+ this.DrawTitle();
552
+ this.DrawHeader();
553
+ this.DrawBody();
554
+ }
555
+
556
+ this.DrawSelectPoint();
557
+
558
+ this.SizeChange=false;
559
+ }
560
+
561
+ this.DrawTitle=function()
562
+ {
563
+ var pixelRatio=this.PixelRatio;
564
+ var titleHeight=this.TitleHeightCache;
565
+ this.Canvas.font=this.TitleFont.GetFont();
566
+
567
+ this.Canvas.textAlign='center';
568
+ this.Canvas.textBaseline='middle';
569
+ this.Canvas.font=this.TextFont;
570
+ this.Canvas.fillStyle=this.TitleFont.Color;
571
+ this.Canvas.fillText(this.Title,this.X+this.ToInt(this.WidthCache/2),this.Y+this.ToInt(titleHeight/2));
572
+
573
+ this.Y+=this.TitleHeightCache;
574
+ }
575
+
576
+ this.DrawHeader=function()
577
+ {
578
+ var x=this.X, y=this.Y;
579
+ var aryHeader=this.Data.Header;
580
+ var pixelRatio=this.PixelRatio;
581
+ this.Canvas.textAlign='center';
582
+ this.Canvas.textBaseline='bottom';
583
+ for(var i in aryHeader)
584
+ {
585
+ var header=aryHeader[i];
586
+ var cacheItem=this.HeaderCache[i];
587
+ var headerHeight=cacheItem.Height;
588
+ var left=x, top=y;
589
+ for(var j in header)
590
+ {
591
+ var item=header[j];
592
+ var itemWidth=this.ColumeCache[j].Width;
593
+ this.Canvas.font=item.Font.GetFont();
594
+ this.Canvas.fillStyle=item.Font.Color;
595
+ this.Canvas.fillText(item.Name,left+this.ToInt((itemWidth)/2),top+headerHeight-this.ColMargin.Bottom*pixelRatio);
596
+
597
+ left+=itemWidth;
598
+ }
599
+ y+=headerHeight;
600
+ }
601
+
602
+ this.Y=y;
603
+ }
604
+
605
+ this.DrawBody=function()
606
+ {
607
+ var x=this.X, y=this.Y;
608
+ var body=this.Data.Body;
609
+ var pixelRatio=this.PixelRatio;
610
+ this.Canvas.textAlign='left';
611
+ this.Canvas.textBaseline='bottom';
612
+ var rowHeight=this.RowHeightCache;
613
+ for(var i in body)
614
+ {
615
+ var row=body[i];
616
+ var left=x, top=y;
617
+ for(var j in row)
618
+ {
619
+ var font=this.ColumeCache[j].Font;
620
+ var colWidth=this.ColumeCache[j].Width;
621
+ var item=row[j];
622
+ this.Canvas.font=font.GetFont(); //计算宽度
623
+
624
+ this.Canvas.font=font.GetFont();
625
+ this.Canvas.fillStyle=font.Color;
626
+ this.Canvas.fillText(item.Text,left+this.ColMargin.Left*pixelRatio,top+rowHeight-this.ColMargin.Bottom*pixelRatio);
627
+ left+=colWidth;
628
+ }
629
+ y+=rowHeight;
630
+ }
631
+ }
632
+
633
+ this.DrawBorder=function()
634
+ {
635
+ this.Canvas.strokeStyle=this.PenBorder;
636
+ var left=this.X,top=this.Y;
637
+ var right=left+this.WidthCache;
638
+
639
+ if (this.TittleBG) //标题背景
640
+ {
641
+ this.Canvas.fillStyle=this.TittleBG;
642
+ this.Canvas.fillRect(left, top,this.WidthCache,this.TitleHeightCache);
643
+ }
644
+
645
+ this.Canvas.beginPath(); //标题
646
+ this.Canvas.moveTo(left,ToFixedPoint(top+this.TitleHeightCache));
647
+ this.Canvas.lineTo(right,ToFixedPoint(top+this.TitleHeightCache));
648
+ top+=this.TitleHeightCache;
649
+ var tableTop=top;
650
+
651
+ for(var i in this.HeaderCache) //标题
652
+ {
653
+ var item=this.HeaderCache[i];
654
+ this.Canvas.moveTo(left,ToFixedPoint(top+item.Height));
655
+ this.Canvas.lineTo(right,ToFixedPoint(top+item.Height));
656
+ top+=item.Height;
657
+ }
658
+
659
+ var body=this.Data.Body;
660
+ for(var i in body) //行
661
+ {
662
+ if (i<body.length-1)
663
+ {
664
+ this.Canvas.moveTo(left,ToFixedPoint(top+this.RowHeightCache));
665
+ this.Canvas.lineTo(right,ToFixedPoint(top+this.RowHeightCache));
666
+ }
667
+ top+=this.RowHeightCache
668
+ }
669
+
670
+ for(var i in this.ColumeCache)
671
+ {
672
+ var item=this.ColumeCache[i];
673
+ if (i<this.ColumeCache.length-1)
674
+ {
675
+ this.Canvas.moveTo(ToFixedPoint(left+item.Width),ToFixedPoint(tableTop));
676
+ this.Canvas.lineTo(ToFixedPoint(left+item.Width),ToFixedPoint(top));
677
+ }
678
+ left+=item.Width;
679
+ }
680
+
681
+ //四周边框
682
+ this.Canvas.moveTo(ToFixedPoint(this.X),ToFixedPoint(this.Y));
683
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(this.Y));
684
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(top));
685
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(top));
686
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(this.Y));
687
+
688
+ this.Canvas.stroke();
689
+ }
690
+
691
+ this.CacluateSize=function()
692
+ {
693
+ var pixelRatio=this.PixelRatio;
694
+ this.HeaderCache=[];
695
+ this.ColumeCache=[];
696
+ this.RowHeightCache=null;
697
+ this.WidthCache=null;
698
+ this.HeightCache=0;
699
+ this.TitleHeightCache=null;
700
+
701
+ this.TitleHeightCache=this.TitleFont.GetFontHeight()+(this.TitleMargin.Top+this.TitleMargin.Bottom)*pixelRatio;
702
+ this.Canvas.font=this.TitleFont.GetFont();
703
+ this.WidthCache=this.Canvas.measureText(this.Title).width+(this.TitleMargin.Left+this.TitleMargin.Right)*pixelRatio;
704
+ this.HeightCache+=this.TitleHeightCache;
705
+
706
+ var aryHeader=this.Data.Header;
707
+ for(var i in aryHeader)
708
+ {
709
+ var header=aryHeader[i];
710
+ var headerCache={ Height:null };
711
+ this.RowHeightCache=null;
712
+ for(var j in header)
713
+ {
714
+ var item=header[j];
715
+ var fontHeight=item.Font.GetFontHeight()+(this.HeaderMargin.Top+this.HeaderMargin.Bottom)*pixelRatio;
716
+ if (headerCache.Height==null || headerCache.Height<fontHeight) headerCache.Height=fontHeight; //表头高度
717
+
718
+ this.Canvas.font=item.Font.GetFont(); //计算宽度
719
+ var textWidth=this.ToInt(this.Canvas.measureText(item.Name).width+(this.HeaderMargin.Left+this.HeaderMargin.Right)*pixelRatio);
720
+
721
+ var colFont=item.ColFont? item.ColFont:item.Font; //行高
722
+ var rowHeight=colFont.GetFontHeight()+(this.ColMargin.Top+this.ColMargin.Bottom)*pixelRatio;
723
+ if (this.RowHeightCache==null || this.RowHeightCache<rowHeight) this.RowHeightCache=rowHeight;
724
+ if (this.IsNull(this.ColumeCache[j]))
725
+ {
726
+ this.ColumeCache[j]={ Font:colFont, Width:textWidth };
727
+ }
728
+ else
729
+ {
730
+ var colItem=this.ColumeCache[j];
731
+ colItem.Font=colFont;
732
+ if (colItem.Width<textWidth) colItem.Width=textWidth;
733
+ }
734
+ }
735
+
736
+ this.HeaderCache[i]=headerCache;
737
+ this.HeightCache+=headerCache.Height;
738
+ }
739
+
740
+ //计算表格每列最大宽度
741
+ var body=this.Data.Body;
742
+ for(var i in body)
743
+ {
744
+ var row=body[i];
745
+ for(var j in row)
746
+ {
747
+ var font=this.ColumeCache[j].Font;
748
+ var item=row[j];
749
+ this.Canvas.font=font.GetFont(); //计算宽度
750
+ var textWidth=this.ToInt(this.Canvas.measureText(item.Text).width+(this.ColMargin.Left+this.ColMargin.Right)*pixelRatio);
751
+ if (this.ColumeCache[j].Width<textWidth) this.ColumeCache[j].Width=textWidth;
752
+ }
753
+
754
+ this.HeightCache+=this.RowHeightCache;
755
+ }
756
+
757
+ var totalWidth=0;
758
+ for(var i in this.ColumeCache)
759
+ {
760
+ totalWidth+=this.ColumeCache[i].Width;
761
+ }
762
+
763
+ if (totalWidth>this.WidthCache)
764
+ {
765
+ this.WidthCache=totalWidth;
766
+ }
767
+ }
768
+
769
+ //横向
770
+ this.CacluateSize2=function()
771
+ {
772
+ var pixelRatio=this.PixelRatio;
773
+ this.HeaderCache=[];
774
+ this.ColumeCache=[];
775
+ this.RowHeightCache=[];
776
+ this.WidthCache=null;
777
+ this.HeightCache=0;
778
+ this.TitleHeightCache=null;
779
+
780
+ this.TitleHeightCache=this.TitleFont.GetFontHeight()+(this.TitleMargin.Top+this.TitleMargin.Bottom)*pixelRatio;
781
+ this.Canvas.font=this.TitleFont.GetFont();
782
+ this.WidthCache=this.Canvas.measureText(this.Title).width+(this.TitleMargin.Left+this.TitleMargin.Right)*pixelRatio;
783
+ this.HeightCache+=this.TitleHeightCache;
784
+
785
+ var aryHeader=this.Data.Header;
786
+ for(var i in aryHeader)
787
+ {
788
+ var header=aryHeader[i];
789
+ var headerCache=null;
790
+ if (this.IsNull(this.HeaderCache[i])) headerCache={ Width:null };
791
+ else headerCache=this.HeaderCache[i];
792
+
793
+ for(var j in header)
794
+ {
795
+ var item=header[j];
796
+ var fontHeight=item.Font.GetFontHeight()+(this.HeaderMargin.Top+this.HeaderMargin.Bottom)*pixelRatio;
797
+
798
+ this.Canvas.font=item.Font.GetFont(); //计算宽度
799
+ var textWidth=this.ToInt(this.Canvas.measureText(item.Name).width+(this.HeaderMargin.Left+this.HeaderMargin.Right)*pixelRatio);
800
+ if (headerCache.Width==null || headerCache.Width<textWidth) headerCache.Width=textWidth;
801
+
802
+ var colFont=item.ColFont? item.ColFont:item.Font; //行高
803
+ var rowCache=null;
804
+ if (this.IsNull(this.RowHeightCache[j]))
805
+ {
806
+ rowCache={ Height:fontHeight, RowFont:colFont};
807
+ this.RowHeightCache[j]=rowCache;
808
+ }
809
+ else
810
+ {
811
+ rowCache=this.RowHeightCache[j];
812
+ if (rowCache.Heigh<fontHeight) rowCache.Heigh=fontHeight;
813
+ rowCache.RowFont=colFont;
814
+ }
815
+ }
816
+
817
+ this.HeaderCache[i]=headerCache;
818
+ }
819
+
820
+ //计算表格每列最大宽度
821
+ var body=this.Data.Body;
822
+ for(var i in body)
823
+ {
824
+ var row=body[i];
825
+ var colCache=null;
826
+ if (this.IsNull(this.ColumeCache[i]))
827
+ {
828
+ colCache={Width:null};
829
+ this.ColumeCache[i]=colCache;
830
+ }
831
+ else
832
+ {
833
+ colCache=this.ColumeCache[j];
834
+ }
835
+
836
+ for(var j in row)
837
+ {
838
+ var font=this.RowHeightCache[j].RowFont;
839
+ var item=row[j];
840
+ this.Canvas.font=font.GetFont(); //计算宽度
841
+ var textWidth=this.ToInt(this.Canvas.measureText(item.Text).width+(this.ColMargin.Left+this.ColMargin.Right)*pixelRatio);
842
+ if (colCache.Width<textWidth) colCache.Width=textWidth;
843
+ }
844
+ }
845
+
846
+ var totalWidth=0;
847
+ for(var i in this.HeaderCache)
848
+ {
849
+ totalWidth+=this.HeaderCache[i].Width;
850
+ }
851
+
852
+ for(var i in this.ColumeCache)
853
+ {
854
+ totalWidth+=this.ColumeCache[i].Width;
855
+ }
856
+
857
+ if (totalWidth>this.WidthCache)
858
+ {
859
+ this.WidthCache=totalWidth;
860
+ }
861
+
862
+ for(var i in this.RowHeightCache)
863
+ {
864
+ this.HeightCache+=this.RowHeightCache[j].Height;
865
+ }
866
+ }
867
+
868
+ this.DrawHeader2=function()
869
+ {
870
+ var x=this.X, y=this.Y;
871
+ var aryHeader=this.Data.Header;
872
+ var pixelRatio=this.PixelRatio;
873
+ this.Canvas.textAlign='center';
874
+ this.Canvas.textBaseline='bottom';
875
+ for(var i in aryHeader)
876
+ {
877
+ var header=aryHeader[i];
878
+ var cacheItem=this.HeaderCache[i];
879
+ var headerWidth=cacheItem.Width;
880
+ var left=x, top=y;
881
+ for(var j in header)
882
+ {
883
+ var item=header[j];
884
+ var itemHeight=this.RowHeightCache[i].Height;
885
+ this.Canvas.font=item.Font.GetFont();
886
+ this.Canvas.fillStyle=item.Font.Color;
887
+ this.Canvas.fillText(item.Name,left+this.ToInt((headerWidth)/2),top+itemHeight-this.ColMargin.Bottom*pixelRatio);
888
+
889
+ top+=itemHeight;
890
+ }
891
+ x+=headerWidth;
892
+ }
893
+
894
+ this.X=x;
895
+ }
896
+
897
+ this.DrawBody2=function()
898
+ {
899
+ var x=this.X, y=this.Y;
900
+ var body=this.Data.Body;
901
+ var pixelRatio=this.PixelRatio;
902
+ this.Canvas.textAlign='left';
903
+ this.Canvas.textBaseline='bottom';
904
+
905
+ var left=x, top=y;
906
+ for(var i in body)
907
+ {
908
+ var row=body[i];
909
+ var colWidth=this.ColumeCache[i].Width;
910
+ var top=y;
911
+ for(var j in row)
912
+ {
913
+ var font=this.RowHeightCache[j].RowFont;
914
+ var colHeight=this.RowHeightCache[j].Height;
915
+ var item=row[j];
916
+
917
+ this.Canvas.font=font.GetFont();
918
+ this.Canvas.fillStyle=font.Color;
919
+ this.Canvas.fillText(item.Text,left+this.ColMargin.Left*pixelRatio,top+colHeight-this.ColMargin.Bottom*pixelRatio);
920
+ top+=colHeight;
921
+ }
922
+
923
+ left+=colWidth;
924
+ }
925
+ }
926
+
927
+ this.DrawBorder2=function()
928
+ {
929
+ this.Canvas.strokeStyle=this.PenBorder;
930
+ var left=this.X,top=this.Y;
931
+ var right=left+this.WidthCache;
932
+
933
+ if (this.TittleBG) //标题背景
934
+ {
935
+ this.Canvas.fillStyle=this.TittleBG;
936
+ this.Canvas.fillRect(left, top,this.WidthCache,this.TitleHeightCache);
937
+ }
938
+
939
+ this.Canvas.beginPath(); //标题
940
+ this.Canvas.moveTo(left,ToFixedPoint(top+this.TitleHeightCache));
941
+ this.Canvas.lineTo(right,ToFixedPoint(top+this.TitleHeightCache));
942
+ top+=this.TitleHeightCache;
943
+ var tableTop=top;
944
+
945
+ for(var i in this.RowHeightCache)
946
+ {
947
+ if (i<this.RowHeightCache.length-1)
948
+ {
949
+ var item=this.RowHeightCache[i];
950
+ this.Canvas.moveTo(ToFixedPoint(left),ToFixedPoint(top+item.Height));
951
+ this.Canvas.lineTo(ToFixedPoint(right),ToFixedPoint(top+item.Height));
952
+ }
953
+ top+=item.Height;
954
+ }
955
+
956
+ left=this.X;
957
+ for(var i in this.HeaderCache) //标题
958
+ {
959
+ var item=this.HeaderCache[i];
960
+ this.Canvas.moveTo(ToFixedPoint(left+item.Width),ToFixedPoint(tableTop));
961
+ this.Canvas.lineTo(ToFixedPoint(left+item.Width),ToFixedPoint(top));
962
+ left+=item.Width;
963
+ }
964
+
965
+ for(var i in this.ColumeCache)
966
+ {
967
+ var item=this.ColumeCache[i];
968
+ if (i<this.ColumeCache.length-1)
969
+ {
970
+ this.Canvas.moveTo(ToFixedPoint(left+item.Width),ToFixedPoint(tableTop));
971
+ this.Canvas.lineTo(ToFixedPoint(left+item.Width),ToFixedPoint(top));
972
+ }
973
+ left+=item.Width;
974
+ }
975
+
976
+
977
+ //四周边框
978
+ this.Canvas.moveTo(ToFixedPoint(this.X),ToFixedPoint(this.Y));
979
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(this.Y));
980
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(top));
981
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(top));
982
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(this.Y));
983
+
984
+ this.Canvas.stroke();
985
+ }
986
+
987
+
988
+ this.DrawSelectPoint=function()
989
+ {
990
+ if (!this.IsSelected) return;
991
+
992
+ var pointSize=this.SelectedPointSize;
993
+ var left=this.Position.X, top=this.Position.Y;
994
+ var right=left+this.WidthCache, bottom=top+this.HeightCache;
995
+ this.Canvas.fillStyle=this.SelectedColor;
996
+ this.Canvas.fillRect(left,top,pointSize,pointSize);
997
+ this.Canvas.fillRect(this.ToInt(left+(this.WidthCache/2)),top,pointSize,pointSize);
998
+ this.Canvas.fillRect(right-pointSize,top,pointSize,pointSize);
999
+
1000
+ this.Canvas.fillRect(left,this.ToInt(top+this.HeightCache/2),pointSize,pointSize);
1001
+ this.Canvas.fillRect(right-pointSize,this.ToInt(top+this.HeightCache/2),pointSize,pointSize);
1002
+
1003
+ this.Canvas.fillRect(left,bottom-pointSize,pointSize,pointSize);
1004
+ this.Canvas.fillRect(this.ToInt(left+(this.WidthCache/2)),bottom-pointSize,pointSize,pointSize);
1005
+ this.Canvas.fillRect(right-pointSize,bottom-pointSize,pointSize,pointSize);
1006
+ }
1007
+
1008
+ this.IsPointIn=function(pt) // -1=不在上面, 0=表头
1009
+ {
1010
+ var left=this.Position.X;
1011
+ var top=this.Position.Y;
1012
+ var right=left+this.WidthCache;
1013
+ var bottom=top+this.TitleHeightCache;
1014
+
1015
+ if (pt.X>left && pt.X<right && pt.Y>top && pt.Y<bottom) return 1;
1016
+
1017
+ return -1;
1018
+ }
1019
+ }
1020
+
1021
+ function TextNodeChartPaint()
1022
+ {
1023
+ this.newMethod=INodeChartPainting; //派生
1024
+ this.newMethod();
1025
+ delete this.newMethod;
1026
+
1027
+ this.ClassName='TextNodeChartPaint'; //类名
1028
+ this.TitleMargin={ Left:5, Top:5, Right:5, Bottom:5 };
1029
+ this.ContentMargin={ Left:5, Top:5, Right:5, Bottom:5 };
1030
+ this.ContentFont=new JSFont();
1031
+ this.Data={};
1032
+ //this.Data={ Content:内容 }
1033
+
1034
+ //临时变量
1035
+ this.X=0;
1036
+ this.Y=0;
1037
+ this.WidthCache;
1038
+ this.HeightCache;
1039
+ this.TitleHeightCache;
1040
+
1041
+ this.Draw=function()
1042
+ {
1043
+ this.X=this.Position.X;
1044
+ this.Y=this.Position.Y;
1045
+ this.PixelRatio=GetDevicePixelRatio();
1046
+
1047
+ if (this.SizeChange) this.CacluateSize();
1048
+
1049
+ this.DrawBorder();
1050
+ this.DrawTitle();
1051
+ this.DrawContent();
1052
+
1053
+ this.DrawSelectPoint();
1054
+
1055
+ this.SizeChange=false;
1056
+ }
1057
+
1058
+ this.CacluateSize=function()
1059
+ {
1060
+ var pixelRatio=this.PixelRatio;
1061
+ this.WidthCache=0;
1062
+ this.HeightCache=0
1063
+ this.TitleHeightCache=null;
1064
+
1065
+ this.TitleHeightCache=this.TitleFont.GetFontHeight()+(this.TitleMargin.Top+this.TitleMargin.Bottom)*pixelRatio;
1066
+ this.Canvas.font=this.TitleFont.GetFont();
1067
+ this.WidthCache=this.Canvas.measureText(this.Title).width+(this.TitleMargin.Left+this.TitleMargin.Right)*pixelRatio;
1068
+ this.HeightCache+=this.TitleHeightCache;
1069
+
1070
+ if (this.Data && this.Data.Content)
1071
+ {
1072
+ this.Canvas.font=this.ContentFont.GetFont();
1073
+ var contentHeight=this.ContentFont.GetFontHeight()+(this.ContentMargin.Top+this.ContentMargin.Bottom)*pixelRatio;
1074
+ this.HeightCache+=contentHeight;
1075
+ var contentWidth=this.Canvas.measureText(this.Data.Content).width+(this.ContentMargin.Left+this.ContentMargin.Right)*pixelRatio;
1076
+ if (contentWidth>this.WidthCache) this.WidthCache=contentWidth;
1077
+ }
1078
+
1079
+ if (this.WidthCache<this.Position.Width) this.Width=this.Position.Width;
1080
+ }
1081
+
1082
+ this.DrawTitle=function()
1083
+ {
1084
+ this.Canvas.textAlign='center';
1085
+ this.Canvas.textBaseline='middle';
1086
+ this.Canvas.font=this.TitleFont.GetFont();
1087
+
1088
+ this.Canvas.fillStyle=this.TitleFont.Color;
1089
+ this.Canvas.fillText(this.Title,this.X+this.ToInt(this.WidthCache/2),this.Y+this.ToInt(this.TitleHeightCache/2));
1090
+
1091
+ this.Y+=this.TitleHeightCache;
1092
+ }
1093
+
1094
+ this.DrawContent=function()
1095
+ {
1096
+ if (!this.Data || !this.Data.Content) return;
1097
+
1098
+ var pixelRatio=this.PixelRatio;
1099
+ this.Canvas.textAlign='left';
1100
+ this.Canvas.textBaseline='bottom';
1101
+ this.Canvas.font=this.ContentFont.GetFont();
1102
+ this.Canvas.fillStyle=this.ContentFont.Color;
1103
+
1104
+ this.Canvas.fillText(this.Data.Content,this.X+this.ContentMargin.Left*pixelRatio,this.Position.Y+this.HeightCache-this.ContentMargin.Bottom*pixelRatio);
1105
+ }
1106
+
1107
+ this.DrawBorder=function()
1108
+ {
1109
+ this.Canvas.strokeStyle=this.PenBorder;
1110
+ var left=this.X,top=this.Y;
1111
+ var right=left+this.WidthCache;
1112
+ var bottom=top+this.HeightCache;
1113
+
1114
+ if (this.TittleBG) //标题背景
1115
+ {
1116
+ this.Canvas.fillStyle=this.TittleBG;
1117
+ this.Canvas.fillRect(left, top,this.WidthCache,this.TitleHeightCache);
1118
+ }
1119
+
1120
+ this.Canvas.beginPath(); //标题
1121
+ this.Canvas.moveTo(left,ToFixedPoint(top+this.TitleHeightCache));
1122
+ this.Canvas.lineTo(right,ToFixedPoint(top+this.TitleHeightCache));
1123
+ top+=this.TitleHeightCache;
1124
+ var tableTop=top;
1125
+
1126
+ //四周边框
1127
+ this.Canvas.moveTo(ToFixedPoint(this.X),ToFixedPoint(this.Y));
1128
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(this.Y));
1129
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(bottom));
1130
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(bottom));
1131
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(this.Y));
1132
+
1133
+ this.Canvas.stroke();
1134
+ }
1135
+
1136
+ this.IsPointIn=function(pt) // -1=不在上面, 0=表头
1137
+ {
1138
+ var left=this.Position.X;
1139
+ var top=this.Position.Y;
1140
+ var right=left+this.WidthCache;
1141
+ var bottom=top+this.TitleHeightCache;
1142
+
1143
+ if (pt.X>left && pt.X<right && pt.Y>top && pt.Y<bottom) return 1;
1144
+
1145
+ return -1;
1146
+ }
1147
+
1148
+ this.DrawSelectPoint=function()
1149
+ {
1150
+ if (!this.IsSelected) return;
1151
+
1152
+ var pointSize=this.SelectedPointSize;
1153
+ var left=this.Position.X, top=this.Position.Y;
1154
+ var right=left+this.WidthCache, bottom=top+this.HeightCache;
1155
+ this.Canvas.fillStyle=this.SelectedColor;
1156
+ this.Canvas.fillRect(left,top,pointSize,pointSize);
1157
+ this.Canvas.fillRect(this.ToInt(left+(this.WidthCache/2)),top,pointSize,pointSize);
1158
+ this.Canvas.fillRect(right-pointSize,top,pointSize,pointSize);
1159
+
1160
+ this.Canvas.fillRect(left,this.ToInt(top+this.HeightCache/2),pointSize,pointSize);
1161
+ this.Canvas.fillRect(right-pointSize,this.ToInt(top+this.HeightCache/2),pointSize,pointSize);
1162
+
1163
+ this.Canvas.fillRect(left,bottom-pointSize,pointSize,pointSize);
1164
+ this.Canvas.fillRect(this.ToInt(left+(this.WidthCache/2)),bottom-pointSize,pointSize,pointSize);
1165
+ this.Canvas.fillRect(right-pointSize,bottom-pointSize,pointSize,pointSize);
1166
+ }
1167
+ }
1168
+
1169
+ function NodeLinesPaint() //节点间连线
1170
+ {
1171
+ this.ClassName='NodeLinesPaint';
1172
+ this.Data=[]; //[{ Start:, End: , Type:}
1173
+ this.Nodes=new Map(); //key:id value:node 方便查找使用map
1174
+ this.Canvas; //画布
1175
+ this.SetNodes=function(nodes)
1176
+ {
1177
+ this.Nodes.clear();
1178
+ for(var i in nodes)
1179
+ {
1180
+ var item=nodes[i];
1181
+ this.Nodes.set(item.ID,item);
1182
+ }
1183
+ }
1184
+
1185
+ this.Draw=function()
1186
+ {
1187
+ for(var i in this.Data)
1188
+ {
1189
+ var item=this.Data[i];
1190
+ var startNode=this.Nodes.get(item.Start);
1191
+ var endNode=this.Nodes.get(item.End);
1192
+ if (!startNode || !endNode) continue;
1193
+ var startChart=startNode.ChartPaint[0];
1194
+ var endChart=endNode.ChartPaint[0];
1195
+
1196
+ var line=this.GetLineDirection(startChart,endChart);
1197
+
1198
+ this.Canvas.strokeStyle=this.PenBorder;
1199
+ this.Canvas.beginPath();
1200
+ this.Canvas.moveTo(ToFixedPoint(line.Start.X),ToFixedPoint(line.Start.Y));
1201
+ this.Canvas.lineTo(ToFixedPoint(line.End.X), ToFixedPoint(line.End.Y));
1202
+ this.Canvas.stroke();
1203
+ }
1204
+ }
1205
+
1206
+ this.GetLineDirection=function(start,end) //获取2个图新的线段位置 1-8 随时针8个方位
1207
+ {
1208
+ //图形中心点
1209
+ var left=start.Position.X;
1210
+ var top=start.Position.Y;
1211
+ var width=start.WidthCache;
1212
+ var height=start.HeightCache;
1213
+ var p1={ X: left+width/2, Y: top+height/2 }; //中心点
1214
+
1215
+ left2=end.Position.X;
1216
+ top2=end.Position.Y;
1217
+ width2=end.WidthCache;
1218
+ height2=end.HeightCache;
1219
+ var p2={ X: left2+width2/2, Y: top2+height2/2 }; //中心点
1220
+
1221
+ var angle = this.GetAngle(p1,p2); //角度
1222
+ var angle2=this.GetAngle(p2,p1);
1223
+
1224
+ console.log('[NodeLinesPaint::GetLineDirection] p1, p2, angle', p1, p2, angle,angle2);
1225
+
1226
+ var linePt;
1227
+ if (angle>325 || angle<=35 ) linePt={X:left+width/2, Y:top};
1228
+ else if (angle>35 && angle<=55) linePt={X:left+width, Y:top};
1229
+ else if (angle>55 && angle<=125) linePt={X:left+width, Y:top+height/2};
1230
+ else if (angle>125 && angle<=145) linePt={X:left+width, Y:top+height};
1231
+ else if (angle>145 && angle<=215) linePt={X:left+width/2, Y:top+height};
1232
+ else if (angle>215 && angle<=235) linePt={X:left, Y:top+height};
1233
+ else if (angle>235 && angle<=305) linePt={X:left, Y:top+height/2};
1234
+ else if (angle>305 && angle<=325) linePt={X:left, Y:top};
1235
+
1236
+ var linePt2;
1237
+ if (angle2>325 || angle2<=35 ) linePt2={X:left2+width2/2, Y:top2};
1238
+ else if (angle2>35 && angle2<=55) linePt2={X:left2+width2, Y:top2};
1239
+ else if (angle2>55 && angle2<=125) linePt2={X:left2+width2, Y:top2+height2/2};
1240
+ else if (angle2>125 && angle2<=145) linePt2={X:left2+width2, Y:top2+height2};
1241
+ else if (angle2>145 && angle2<=215) linePt2={X:left2+width2/2, Y:top2+height2};
1242
+ else if (angle2>215 && angle2<=235) linePt2={X:left2, Y:top2+height2};
1243
+ else if (angle2>235 && angle2<=305) linePt2={X:left2, Y:top2+height2/2};
1244
+ else if (angle2>305 && angle2<=325) linePt2={X:left2, Y:top2};
1245
+
1246
+ console.log('[NodeLinesPaint::GetLineDirection] linePt linePt2 ', linePt,linePt2);
1247
+ return {Start:linePt, End:linePt2};
1248
+ }
1249
+
1250
+ this.GetAngle=function(p1, p2)
1251
+ {
1252
+ var x = Math.abs(p1.X-p2.X);
1253
+ var y = Math.abs(p1.Y-p2.Y);
1254
+ var z = Math.sqrt(Math.pow(x,2)+Math.pow(y,2));
1255
+ var cos = y/z;
1256
+ var radina = Math.acos(cos);//用反三角函数求弧度
1257
+ var angle = Math.floor(180/(Math.PI/radina));//将弧度转换成角度
1258
+
1259
+ if(p2.X>p1.X && p2.Y>p1.Y) angle = 180 - angle; //第2个点在第四象限
1260
+ if(p2.X==p1.X && p2.Y>p1.Y) angle = 180; //第2个点在y轴负方向上
1261
+ if(p2.X>p1.X && p2.Y==p1.Y) angle = 90; //第2个点在x轴正方向上
1262
+ if(p2.X<p1.X && p2.Y>p1.Y) angle = 180+angle; //第2个点在第三象限
1263
+ if(p2.X<p1.X&&p2.Y==p1.Y) angle = 270; //第2个点在x轴负方向
1264
+ if(p2.X<p1.X&&p2.Y<p1.Y) angle = 360 - angle; //第2个点在第二象限
1265
+
1266
+ return angle;
1267
+ }
1268
+ }
1269
+
1270
+
1271
+ function JSMind(divElement)
1272
+ {
1273
+ this.DivElement=divElement;
1274
+ this.JSMindContainer; //画图控件
1275
+
1276
+ //h5 canvas
1277
+ this.CanvasElement=document.createElement("canvas");
1278
+ this.CanvasElement.className='jsmind-drawing';
1279
+ this.CanvasElement.id=Guid();
1280
+ this.CanvasElement.setAttribute("tabindex",0);
1281
+ if(!divElement.hasChildNodes("canvas")) { divElement.appendChild(this.CanvasElement); }
1282
+
1283
+ this.OnSize=function()
1284
+ {
1285
+ //画布大小通过div获取
1286
+ var height=parseInt(this.DivElement.style.height.replace("px",""));
1287
+
1288
+ this.CanvasElement.height=height;
1289
+ this.CanvasElement.width=parseInt(this.DivElement.style.width.replace("px",""));
1290
+ this.CanvasElement.style.width=this.CanvasElement.width+'px';
1291
+ this.CanvasElement.style.height=this.CanvasElement.height+'px';
1292
+
1293
+ var pixelTatio = GetDevicePixelRatio(); //获取设备的分辨率
1294
+ this.CanvasElement.height*=pixelTatio;
1295
+ this.CanvasElement.width*=pixelTatio;
1296
+
1297
+ console.log(`[JSMind::OnSize] devicePixelRatio=${window.devicePixelRatio}, height=${this.CanvasElement.height}, width=${this.CanvasElement.width}`);
1298
+
1299
+ if (this.JSMindContainer && this.JSMindContainer.Frame)
1300
+ this.JSMindContainer.Frame.SetSizeChange(true);
1301
+
1302
+ if (this.JSMindContainer) this.JSMindContainer.Draw();
1303
+ }
1304
+
1305
+ this.SetOption=function(option)
1306
+ {
1307
+ var chart=new JSMindContainer(this.CanvasElement);
1308
+ chart.Create({});
1309
+ if (option.NodeTree) chart.LoadNodeData(option.NodeTree);
1310
+
1311
+ if (option.Symbol) chart.Symbol=option.Symbol;
1312
+
1313
+ chart.ExecuteAllScript();
1314
+
1315
+ this.JSMindContainer=chart;
1316
+ this.DivElement.JSMind=this; //div中保存一份
1317
+ this.JSMindContainer.Draw();
1318
+ }
1319
+
1320
+ this.AddTextNode=function(obj)
1321
+ {
1322
+ if (this.JSMindContainer && typeof(this.JSMindContainer.AddTextNode)=='function')
1323
+ this.JSMindContainer.AddTextNode(obj);
1324
+ }
1325
+
1326
+ this.AddTableNode=function(obj)
1327
+ {
1328
+ if (this.JSMindContainer && typeof(this.JSMindContainer.AddTableNode)=='function')
1329
+ this.JSMindContainer.AddTableNode(obj);
1330
+ }
1331
+ }
1332
+
1333
+
1334
+ //初始化
1335
+ JSMind.Init=function(divElement)
1336
+ {
1337
+ var jsChartControl=new JSMind(divElement);
1338
+ jsChartControl.OnSize();
1339
+
1340
+ return jsChartControl;
1341
+ }
1342
+
1343
+ //边框信息
1344
+ function NodeChartBorder()
1345
+ {
1346
+ //四周间距
1347
+ this.Left=50;
1348
+ this.Right=80;
1349
+ this.Top=0;
1350
+ this.Bottom=50;
1351
+ this.TitleHeight=24; //标题高度
1352
+ this.TopSpace=0;
1353
+ this.BottomSpace=0;
1354
+
1355
+ this.X=10;
1356
+ this.Y=10;
1357
+ this.Width=500;
1358
+ this.Height=400;
1359
+
1360
+ this.GetChartWidth=function()
1361
+ {
1362
+ return this.Width;
1363
+ }
1364
+
1365
+ this.GetChartHeight=function()
1366
+ {
1367
+ return this.Height;
1368
+ }
1369
+
1370
+ this.GetLeft=function()
1371
+ {
1372
+ return this.X+this.Left;
1373
+ }
1374
+
1375
+ this.GetRight=function()
1376
+ {
1377
+ return this.X+this.Width-this.Right;
1378
+ }
1379
+
1380
+ this.GetTop=function()
1381
+ {
1382
+ return this.Y+this.Top;
1383
+ }
1384
+
1385
+ this.GetTopEx=function() //去掉标题,上面间距
1386
+ {
1387
+ return this.Y+this.Top+this.TitleHeight+this.TopSpace;
1388
+ }
1389
+
1390
+ this.GetTopTitle=function() //去掉标题
1391
+ {
1392
+ return this.Y+this.Top+this.TitleHeight;
1393
+ }
1394
+
1395
+ this.GetBottom=function()
1396
+ {
1397
+ return this.Y+this.Height-this.Bottom;
1398
+ }
1399
+
1400
+ this.GetBottomEx=function()
1401
+ {
1402
+ return this.Y+this.Height-this.Bottom-this.BottomSpace;
1403
+ }
1404
+
1405
+ this.GetWidth=function()
1406
+ {
1407
+ return this.Width-this.Left-this.Right;
1408
+ }
1409
+
1410
+ this.GetHeight=function()
1411
+ {
1412
+ return this.Height-this.Top-this.Bottom;
1413
+ }
1414
+
1415
+ this.GetHeightEx=function() //去掉标题的高度, 上下间距
1416
+ {
1417
+ return this.Height-this.Top-this.Bottom-this.TitleHeight-this.TopSpace-this.BottomSpace;
1418
+ }
1419
+
1420
+ this.GetRightEx=function() //横屏去掉标题高度的 上面间距
1421
+ {
1422
+ return this.UIElement.width-this.Right-this.TitleHeight- this.TopSpace;
1423
+ }
1424
+
1425
+ this.GetWidthEx=function() //横屏去掉标题宽度 上下间距
1426
+ {
1427
+ return this.UIElement.width-this.Left-this.Right-this.TitleHeight- this.TopSpace - this.BottomSpace;
1428
+ }
1429
+
1430
+ this.GetLeftEx = function () //横屏
1431
+ {
1432
+ return this.Left+this.BottomSpace;
1433
+ }
1434
+
1435
+ this.GetRightTitle = function ()//横屏
1436
+ {
1437
+ return this.UIElement.width - this.Right - this.TitleHeight;
1438
+ }
1439
+
1440
+ this.GetTitleHeight=function()
1441
+ {
1442
+ return this.TitleHeight;
1443
+ }
1444
+ }
1445
+
1446
+ //K线节点
1447
+ function KLineNodeChartPaint(canvasElement)
1448
+ {
1449
+ this.newMethod=INodeChartPainting; //派生
1450
+ this.newMethod();
1451
+ delete this.newMethod;
1452
+
1453
+ this.ClassName='KLineNodeChartPaint'; //类名
1454
+ this.TitleMargin={ Left:5, Top:5, Right:5, Bottom:5 };
1455
+
1456
+ this.Period=0; //周期 0=日线 1=周线 2=月线 3=年线 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟
1457
+ this.Right=0; //复权 0 不复权 1 前复权 2 后复权
1458
+ this.SourceData; //原始的历史数据
1459
+ this.MaxReqeustDataCount=3000; //数据个数
1460
+ this.MaxRequestMinuteDayCount=5; //分钟数据请求的天数
1461
+ this.PageSize=200; //每页数据个数
1462
+
1463
+
1464
+ this.Frame; //框架画法
1465
+ this.ChartPaint=[]; //图形画法
1466
+ this.WindowIndex=[];
1467
+ this.TitlePaint=[]; //标题画法
1468
+ this.KLineApiUrl=g_JSChartResource.Domain+"/API/KLine2"; //历史K线api地址
1469
+ this.MinuteKLineApiUrl=g_JSChartResource.Domain+'/API/KLine3'; //历史分钟数据
1470
+ this.CursorIndex=0; //十字光标X轴索引
1471
+ this.LastPoint=new Point(); //鼠标位置
1472
+
1473
+ this.FrameSplitData=new Map();
1474
+ this.FrameSplitData.set("double",new SplitData());
1475
+ this.FrameSplitData.set("price",new PriceSplitData());
1476
+
1477
+ this.WidthCache;
1478
+ this.HeightCache;
1479
+
1480
+ this.Draw=function()
1481
+ {
1482
+ if (this.X!=this.Position.X || this.Y!=this.Position.Y || !this.WidthCache!=this.Position.Width || this.HeightCache!=this.Position.Height)
1483
+ {
1484
+ this.CacluateTitleSize();
1485
+
1486
+ this.X=this.Position.X;
1487
+ this.Y=this.Position.Y;
1488
+ this.WidthCache=this.Position.Width;
1489
+ this.HeightCache=this.Position.Height;
1490
+
1491
+ this.Frame.ChartBorder.X=this.X;
1492
+ this.Frame.ChartBorder.Y=this.Y+this.TitleHeightCache;
1493
+ this.Frame.ChartBorder.Width=this.WidthCache;
1494
+ this.Frame.ChartBorder.Height=this.HeightCache-this.TitleHeightCache;
1495
+
1496
+ this.Frame.SetSizeChage(true);
1497
+ }
1498
+
1499
+ this.PixelRatio=GetDevicePixelRatio();
1500
+
1501
+ this.DrawBorder();
1502
+ this.DrawTitle();
1503
+
1504
+ this.Canvas.save();
1505
+ this.Canvas.lineWidth=this.PixelRatio; //手机端需要根据分辨率比调整线段宽度
1506
+
1507
+ if (this.ChartSplashPaint && this.ChartSplashPaint.IsEnableSplash)
1508
+ {
1509
+ this.Frame.Draw();
1510
+ this.ChartSplashPaint.Draw();
1511
+ return;
1512
+ }
1513
+ //框架
1514
+ this.Frame.Draw();
1515
+
1516
+ //框架内图形
1517
+ for (var i in this.ChartPaint)
1518
+ {
1519
+ var item=this.ChartPaint[i];
1520
+ if (item.IsDrawFirst)
1521
+ item.Draw();
1522
+ }
1523
+
1524
+ for(var i in this.ChartPaint)
1525
+ {
1526
+ var item=this.ChartPaint[i];
1527
+ if (!item.IsDrawFirst)
1528
+ item.Draw();
1529
+ }
1530
+
1531
+ for(var i in this.ChartPaintEx)
1532
+ {
1533
+ var item=this.ChartPaintEx[i];
1534
+ item.Draw();
1535
+ }
1536
+
1537
+ //叠加股票
1538
+ for(var i in this.OverlayChartPaint)
1539
+ {
1540
+ var item=this.OverlayChartPaint[i];
1541
+ item.Draw();
1542
+ }
1543
+
1544
+ if (this.Frame.DrawOveraly)
1545
+ this.Frame.DrawOveraly(); //画叠加指标
1546
+
1547
+ //固定扩展图形
1548
+ for(var i in this.ExtendChartPaint)
1549
+ {
1550
+ var item=this.ExtendChartPaint[i];
1551
+ if (!item.IsDynamic && item.IsAnimation==false) item.Draw();
1552
+ }
1553
+
1554
+ if (this.Frame.DrawInsideHorizontal) this.Frame.DrawInsideHorizontal();
1555
+ this.Frame.DrawLock();
1556
+ this.Frame.Snapshot();
1557
+
1558
+ this.Canvas.restore();
1559
+
1560
+ this.DrawSelectPoint();
1561
+
1562
+ this.SizeChange=false;
1563
+ }
1564
+
1565
+ this.CacluateTitleSize=function()
1566
+ {
1567
+ var pixelRatio=this.PixelRatio;
1568
+ this.TitleHeightCache=null;
1569
+
1570
+ this.TitleHeightCache=this.TitleFont.GetFontHeight()+(this.TitleMargin.Top+this.TitleMargin.Bottom)*pixelRatio;
1571
+ this.Canvas.font=this.TitleFont.GetFont();
1572
+ this.TitleWidthCache=this.Canvas.measureText(this.Title).width+(this.TitleMargin.Left+this.TitleMargin.Right)*pixelRatio;
1573
+ }
1574
+
1575
+ this.DrawTitle=function()
1576
+ {
1577
+ this.Canvas.textAlign='center';
1578
+ this.Canvas.textBaseline='middle';
1579
+ this.Canvas.font=this.TitleFont.GetFont();
1580
+
1581
+ this.Canvas.fillStyle=this.TitleFont.Color;
1582
+ this.Canvas.fillText(this.Title,this.X+this.ToInt(this.WidthCache/2),this.Y+this.ToInt(this.TitleHeightCache/2));
1583
+ }
1584
+
1585
+ this.DrawBorder=function()
1586
+ {
1587
+ this.Canvas.strokeStyle=this.PenBorder;
1588
+ var left=this.X,top=this.Y;
1589
+ var right=left+this.WidthCache;
1590
+ var bottom=top+this.HeightCache;
1591
+
1592
+ if (this.TittleBG) //标题背景
1593
+ {
1594
+ this.Canvas.fillStyle=this.TittleBG;
1595
+ this.Canvas.fillRect(left, top,this.WidthCache,this.TitleHeightCache);
1596
+ }
1597
+
1598
+ this.Canvas.beginPath(); //标题
1599
+ this.Canvas.moveTo(left,ToFixedPoint(top+this.TitleHeightCache));
1600
+ this.Canvas.lineTo(right,ToFixedPoint(top+this.TitleHeightCache));
1601
+ top+=this.TitleHeightCache;
1602
+ var tableTop=top;
1603
+
1604
+ //四周边框
1605
+ this.Canvas.moveTo(ToFixedPoint(this.X),ToFixedPoint(this.Y));
1606
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(this.Y));
1607
+ this.Canvas.lineTo(ToFixedPoint(right), ToFixedPoint(bottom));
1608
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(bottom));
1609
+ this.Canvas.lineTo(ToFixedPoint(this.X), ToFixedPoint(this.Y));
1610
+
1611
+ this.Canvas.stroke();
1612
+ }
1613
+
1614
+ this.DrawSelectPoint=function()
1615
+ {
1616
+ if (!this.IsSelected) return;
1617
+
1618
+ var pointSize=this.SelectedPointSize;
1619
+ var left=this.Position.X, top=this.Position.Y;
1620
+ var right=left+this.WidthCache, bottom=top+this.HeightCache;
1621
+ this.Canvas.fillStyle=this.SelectedColor;
1622
+ this.Canvas.fillRect(left,top,pointSize,pointSize);
1623
+ this.Canvas.fillRect(this.ToInt(left+(this.WidthCache/2)),top,pointSize,pointSize);
1624
+ this.Canvas.fillRect(right-pointSize,top,pointSize,pointSize);
1625
+
1626
+ this.Canvas.fillRect(left,this.ToInt(top+this.HeightCache/2),pointSize,pointSize);
1627
+ this.Canvas.fillRect(right-pointSize,this.ToInt(top+this.HeightCache/2),pointSize,pointSize);
1628
+
1629
+ this.Canvas.fillRect(left,bottom-pointSize,pointSize,pointSize);
1630
+ this.Canvas.fillRect(this.ToInt(left+(this.WidthCache/2)),bottom-pointSize,pointSize,pointSize);
1631
+ this.Canvas.fillRect(right-pointSize,bottom-pointSize,pointSize,pointSize);
1632
+ }
1633
+
1634
+ this.IsPointIn=function(pt) // -1=不在上面, 0=表头
1635
+ {
1636
+ var left=this.Position.X;
1637
+ var top=this.Position.Y;
1638
+ var right=left+this.WidthCache;
1639
+ var bottom=top+this.TitleHeightCache;
1640
+
1641
+ if (pt.X>left && pt.X<right && pt.Y>top && pt.Y<bottom) return 1;
1642
+
1643
+ return -1;
1644
+ }
1645
+
1646
+ this.SetOption=function(option)
1647
+ {
1648
+ if (option.KLine) //k线图的属性设置
1649
+ {
1650
+ if (option.KLine.Right>=0) this.Right=option.KLine.Right;
1651
+ if (option.KLine.Period>=0) this.Period=option.KLine.Period;
1652
+ if (option.KLine.MaxReqeustDataCount>0) this.MaxReqeustDataCount=option.KLine.MaxReqeustDataCount;
1653
+ //if (option.KLine.Info && option.KLine.Info.length>0) chart.SetKLineInfo(option.KLine.Info,false);
1654
+ if (option.KLine.MaxRequestMinuteDayCount>0) this.MaxRequestMinuteDayCount=option.KLine.MaxRequestMinuteDayCount;
1655
+ if (option.KLine.DrawType) this.KLineDrawType=option.KLine.DrawType;
1656
+ if (option.KLine.FirstShowDate>20000101) this.CustomShow={ Date:option.KLine.FirstShowDate };
1657
+ }
1658
+
1659
+ if (!option.Windows || option.Windows.length<=0) return null;
1660
+ this.Create(option.Windows.length);
1661
+
1662
+ if (option.Border)
1663
+ {
1664
+ if (!isNaN(option.Border.Left)) this.Frame.ChartBorder.Left=option.Border.Left;
1665
+ if (!isNaN(option.Border.Right)) this.Frame.ChartBorder.Right=option.Border.Right;
1666
+ if (!isNaN(option.Border.Top)) this.Frame.ChartBorder.Top=option.Border.Top;
1667
+ if (!isNaN(option.Border.Bottom)) this.Frame.ChartBorder.Bottom=option.Border.Bottom;
1668
+ }
1669
+
1670
+ if (option.KLine)
1671
+ {
1672
+ if (option.KLine.PageSize > 0) //一屏显示的数据个数
1673
+ {
1674
+ this.PageSize = option.KLine.PageSize;
1675
+ }
1676
+ }
1677
+
1678
+ if (option.Frame)
1679
+ {
1680
+ for(var i in option.Frame)
1681
+ {
1682
+ var item=option.Frame[i];
1683
+ if (!this.Frame.SubFrame[i]) continue;
1684
+ if (item.SplitCount) this.Frame.SubFrame[i].Frame.YSplitOperator.SplitCount=item.SplitCount;
1685
+ if (item.StringFormat) this.Frame.SubFrame[i].Frame.YSplitOperator.StringFormat=item.StringFormat;
1686
+ if (!isNaN(item.Height)) this.Frame.SubFrame[i].Height = item.Height;
1687
+ if (item.IsShowLeftText===false || item.IsShowLeftText===true)
1688
+ {
1689
+ this.Frame.SubFrame[i].Frame.IsShowYText[0]=item.IsShowLeftText;
1690
+ this.Frame.SubFrame[i].Frame.YSplitOperator.IsShowLeftText=item.IsShowLeftText; //显示左边刻度
1691
+ }
1692
+ if (item.IsShowRightText===false || item.IsShowRightText===true)
1693
+ {
1694
+ this.Frame.SubFrame[i].Frame.IsShowYText[1]=item.IsShowRightText;
1695
+ this.Frame.SubFrame[i].Frame.YSplitOperator.IsShowRightText=item.IsShowRightText; //显示右边刻度
1696
+ }
1697
+ }
1698
+ }
1699
+
1700
+ let scriptData = new JSIndexScript();
1701
+ for(var i in option.Windows)
1702
+ {
1703
+ var item=option.Windows[i];
1704
+ if (item.Script)
1705
+ {
1706
+ this.WindowIndex[i]=new ScriptIndex(item.Name,item.Script,item.Args,item); //脚本执行
1707
+ }
1708
+ else
1709
+ {
1710
+ let indexItem=JSIndexMap.Get(item.Index);
1711
+ if (indexItem)
1712
+ {
1713
+ this.WindowIndex[i]=indexItem.Create();
1714
+ this.CreateWindowIndex(i);
1715
+ }
1716
+ else
1717
+ {
1718
+ let indexInfo = scriptData.Get(item.Index);
1719
+ if (!indexInfo) continue;
1720
+
1721
+ if (item.Lock) indexInfo.Lock=item.Lock;
1722
+ indexInfo.ID=item.Index;
1723
+ this.WindowIndex[i] = new ScriptIndex(indexInfo.Name, indexInfo.Script, indexInfo.Args,indexInfo); //脚本执行
1724
+ }
1725
+
1726
+ }
1727
+
1728
+ if (item.Modify!=null) this.Frame.SubFrame[i].Frame.ModifyIndex=item.Modify;
1729
+ if (item.Change!=null) this.Frame.SubFrame[i].Frame.ChangeIndex=item.Change;
1730
+ if (item.Close!=null) this.Frame.SubFrame[i].Frame.CloseIndex=item.Close;
1731
+ if (item.Overlay!=null) this.Frame.SubFrame[i].Frame.OverlayIndex=item.Overlay;
1732
+
1733
+ if (!isNaN(item.TitleHeight)) this.Frame.SubFrame[i].Frame.ChartBorder.TitleHeight=item.TitleHeight;
1734
+ }
1735
+ }
1736
+
1737
+ //创建指标窗口 windowCount 窗口个数
1738
+ this.Create=function(windowCount)
1739
+ {
1740
+ //创建等待提示
1741
+ this.ChartSplashPaint = new ChartSplashPaint();
1742
+ this.ChartSplashPaint.Canvas = this.Canvas;
1743
+
1744
+ //创建框架容器
1745
+ this.Frame=new HQTradeFrame();
1746
+ this.Frame.CalculateChartBorder=this.Frame.CalculateChartBorder2;
1747
+ this.Frame.ChartBorder=new NodeChartBorder();
1748
+ this.Frame.ChartBorder.Top=30;
1749
+ this.Frame.ChartBorder.Left=1;
1750
+ this.Frame.ChartBorder.Right=1;
1751
+ this.Frame.ChartBorder.Bottom=20;
1752
+ this.Frame.Canvas=this.Canvas;
1753
+ this.ChartSplashPaint.Frame = this.Frame;
1754
+
1755
+ this.CreateChildWindow(windowCount);
1756
+ this.CreateMainKLine();
1757
+
1758
+ //子窗口动态标题
1759
+ for(var i in this.Frame.SubFrame)
1760
+ {
1761
+ var titlePaint=new DynamicChartTitlePainting();
1762
+ titlePaint.Frame=this.Frame.SubFrame[i].Frame;
1763
+ titlePaint.Canvas=this.Canvas;
1764
+
1765
+ this.TitlePaint.push(titlePaint);
1766
+ }
1767
+ }
1768
+
1769
+ //创建子窗口
1770
+ this.CreateChildWindow=function(windowCount)
1771
+ {
1772
+ for(var i=0;i<windowCount;++i)
1773
+ {
1774
+ var border=new NodeChartBorder();
1775
+
1776
+ var frame=new KLineFrame();
1777
+ frame.Canvas=this.Canvas;
1778
+ frame.ChartBorder=border;
1779
+ frame.Identify=i; //窗口序号
1780
+
1781
+ frame.HorizontalMax=20;
1782
+ frame.HorizontalMin=10;
1783
+
1784
+ if (i==0)
1785
+ {
1786
+ frame.YSplitOperator=new FrameSplitKLinePriceY();
1787
+ frame.YSplitOperator.FrameSplitData=this.FrameSplitData.get('price');
1788
+ frame.YSplitOperator.SplitCount=3;
1789
+ var pixelTatio = GetDevicePixelRatio(); //获取设备的分辨率
1790
+ border.BottomSpace=12*pixelTatio; //主图上下留空间
1791
+ border.TopSpace=12*pixelTatio;
1792
+ }
1793
+ else
1794
+ {
1795
+ frame.YSplitOperator=new FrameSplitY();
1796
+ frame.YSplitOperator.FrameSplitData=this.FrameSplitData.get('double');
1797
+ frame.YSplitOperator.SplitCount=2;
1798
+ }
1799
+
1800
+ frame.YSplitOperator.Frame=frame;
1801
+ frame.YSplitOperator.ChartBorder=border;
1802
+ frame.XSplitOperator=new FrameSplitKLineX();
1803
+ frame.XSplitOperator.Frame=frame;
1804
+ frame.XSplitOperator.ChartBorder=border;
1805
+
1806
+ if (i!=windowCount-1) frame.XSplitOperator.ShowText=false;
1807
+
1808
+ for(var j=frame.HorizontalMin;j<=frame.HorizontalMax;j+=1)
1809
+ {
1810
+ frame.HorizontalInfo[j]= new CoordinateInfo();
1811
+ frame.HorizontalInfo[j].Value=j;
1812
+ if (i==0 && j==frame.HorizontalMin) continue;
1813
+
1814
+ frame.HorizontalInfo[j].Message[1]=j.toString();
1815
+ frame.HorizontalInfo[j].Font="14px 微软雅黑";
1816
+ }
1817
+
1818
+ var subFrame=new SubFrameItem();
1819
+ subFrame.Frame=frame;
1820
+ if (i==0)
1821
+ subFrame.Height=20;
1822
+ else
1823
+ subFrame.Height=10;
1824
+
1825
+ this.Frame.SubFrame[i]=subFrame;
1826
+ }
1827
+ }
1828
+
1829
+ //创建主图K线画法
1830
+ this.CreateMainKLine=function()
1831
+ {
1832
+ var kline=new ChartKLine();
1833
+ kline.Canvas=this.Canvas;
1834
+ kline.ChartBorder=this.Frame.SubFrame[0].Frame.ChartBorder;
1835
+ kline.ChartFrame=this.Frame.SubFrame[0].Frame;
1836
+ kline.Name="Main-KLine";
1837
+ kline.DrawType=this.KLineDrawType;
1838
+
1839
+ this.ChartPaint[0]=kline;
1840
+ this.TitlePaint[0]=new DynamicKLineTitlePainting();
1841
+ this.TitlePaint[0].Frame=this.Frame.SubFrame[0].Frame;
1842
+ this.TitlePaint[0].Canvas=this.Canvas;
1843
+ this.TitlePaint[0].OverlayChartPaint=this.OverlayChartPaint; //绑定叠加
1844
+
1845
+ /*
1846
+ //主图叠加画法
1847
+ var paint=new ChartOverlayKLine();
1848
+ paint.Canvas=this.Canvas;
1849
+ paint.ChartBorder=this.Frame.SubFrame[0].Frame.ChartBorder;
1850
+ paint.ChartFrame=this.Frame.SubFrame[0].Frame;
1851
+ paint.Name="Overlay-KLine";
1852
+ paint.DrawType=this.KLineDrawType;
1853
+ this.OverlayChartPaint[0]=paint;
1854
+ */
1855
+ }
1856
+
1857
+ //绑定主图K线数据
1858
+ this.BindMainData=function(hisData,showCount)
1859
+ {
1860
+ this.ChartPaint[0].Data=hisData;
1861
+ this.ChartPaint[0].Symbol=this.Symbol;
1862
+ for(var i in this.Frame.SubFrame)
1863
+ {
1864
+ var item =this.Frame.SubFrame[i].Frame;
1865
+ item.XPointCount=showCount;
1866
+ item.Data=this.ChartPaint[0].Data;
1867
+ }
1868
+
1869
+ //this.TitlePaint[0].Data=this.ChartPaint[0].Data; //动态标题
1870
+ //this.TitlePaint[0].Symbol=this.Symbol;
1871
+ //this.TitlePaint[0].Name=this.Name;
1872
+
1873
+ //this.ChartCorssCursor.StringFormatX.Data=this.ChartPaint[0].Data; //十字光标
1874
+ this.Frame.Data=this.ChartPaint[0].Data;
1875
+
1876
+ //this.OverlayChartPaint[0].MainData=this.ChartPaint[0].Data; //K线叠加
1877
+
1878
+ var dataOffset=hisData.Data.length-showCount;
1879
+ if (dataOffset<0) dataOffset=0;
1880
+ this.ChartPaint[0].Data.DataOffset=dataOffset;
1881
+
1882
+ //this.ChartCorssCursor.StringFormatY.Symbol=this.Symbol;
1883
+
1884
+ this.CursorIndex=showCount;
1885
+ if (this.CursorIndex+dataOffset>=hisData.Data.length) this.CursorIndex=hisData.Data.length-1-dataOffset;
1886
+ if (this.CursorIndex<0) this.CursorIndex=0; //不一定对啊
1887
+
1888
+ if (this.CustomShow) //定制显示 1次有效
1889
+ {
1890
+ this.SetCustomShow(this.CustomShow,hisData);
1891
+ this.CustomShow=null;
1892
+ }
1893
+ }
1894
+
1895
+ this.BindIndexData=function(windowIndex,hisData)
1896
+ {
1897
+ if (!this.WindowIndex[windowIndex]) return;
1898
+
1899
+ if (typeof(this.WindowIndex[windowIndex].RequestData)=="function") //数据需要另外下载的.
1900
+ {
1901
+ this.WindowIndex[windowIndex].RequestData(this,windowIndex,hisData);
1902
+ return;
1903
+ }
1904
+ if (typeof(this.WindowIndex[windowIndex].ExecuteScript)=='function')
1905
+ {
1906
+ this.WindowIndex[windowIndex].ExecuteScript(this,windowIndex,hisData);
1907
+ return;
1908
+ }
1909
+
1910
+ this.WindowIndex[windowIndex].BindData(this,windowIndex,hisData);
1911
+ }
1912
+
1913
+ //切换股票代码
1914
+ this.ChangeSymbol=function(symbol)
1915
+ {
1916
+ this.Symbol=symbol;
1917
+ if (IsIndexSymbol(symbol)) this.Right=0; //指数没有复权
1918
+
1919
+ //清空指标
1920
+ if (this.Frame && this.Frame.SubFrame)
1921
+ {
1922
+ for(var i=0;i<this.Frame.SubFrame.length;++i)
1923
+ {
1924
+ this.DeleteIndexPaint(i);
1925
+ }
1926
+ }
1927
+
1928
+ if (this.Period<=3)
1929
+ {
1930
+ this.RequestHistoryData(); //请求日线数据
1931
+ //this.ReqeustKLineInfoData();
1932
+ }
1933
+ else
1934
+ {
1935
+ this.ReqeustHistoryMinuteData(); //请求分钟数据
1936
+ }
1937
+ }
1938
+
1939
+ //删除某一个窗口的指标
1940
+ this.DeleteIndexPaint=function(windowIndex)
1941
+ {
1942
+ let paint=new Array(); //踢出当前窗口的指标画法
1943
+ for(let i in this.ChartPaint)
1944
+ {
1945
+ let item=this.ChartPaint[i];
1946
+
1947
+ if (i==0 || item.ChartFrame!=this.Frame.SubFrame[windowIndex].Frame)
1948
+ paint.push(item);
1949
+ }
1950
+
1951
+ this.Frame.SubFrame[windowIndex].Frame.YSpecificMaxMin=null; //清空指定最大最小值
1952
+ this.Frame.SubFrame[windowIndex].Frame.IsLocked=false; //解除上锁
1953
+ this.Frame.SubFrame[windowIndex].Frame.YSplitScale = null; //清空固定刻度
1954
+
1955
+ this.ChartPaint=paint;
1956
+
1957
+ //清空东条标题
1958
+ //var titleIndex=windowIndex+1;
1959
+ //this.TitlePaint[titleIndex].Data=[];
1960
+ //this.TitlePaint[titleIndex].Title=null;
1961
+ }
1962
+
1963
+ this.RequestHistoryData=function()
1964
+ {
1965
+ var self=this;
1966
+ this.ChartSplashPaint.IsEnableSplash = true;
1967
+ this.FlowCapitalReady=false;
1968
+ this.Draw();
1969
+ $.ajax({
1970
+ url: this.KLineApiUrl,
1971
+ data:
1972
+ {
1973
+ "field": ["name","symbol","yclose","open","price","high","low","vol"],
1974
+ "symbol": self.Symbol,
1975
+ "start": -1,
1976
+ "count": self.MaxReqeustDataCount
1977
+ },
1978
+ type:"post",
1979
+ dataType: "json",
1980
+ async:true,
1981
+ success: function (data)
1982
+ {
1983
+ self.ChartSplashPaint.IsEnableSplash = false;
1984
+ self.RecvHistoryData(data);
1985
+ //self.AutoUpdate();
1986
+ }
1987
+ });
1988
+ }
1989
+
1990
+ this.RecvHistoryData=function(data)
1991
+ {
1992
+ var aryDayData=KLineChartContainer.JsonDataToHistoryData(data);
1993
+
1994
+ //原始数据
1995
+ var sourceData=new ChartData();
1996
+ sourceData.Data=aryDayData;
1997
+ sourceData.DataType=0; //0=日线数据 1=分钟数据
1998
+
1999
+ //显示的数据
2000
+ var bindData=new ChartData();
2001
+ bindData.Data=aryDayData;
2002
+ bindData.Right=this.Right;
2003
+ bindData.Period=this.Period;
2004
+ bindData.DataType=0;
2005
+
2006
+ if (bindData.Right>0) //复权
2007
+ {
2008
+ var rightData=bindData.GetRightDate(bindData.Right);
2009
+ bindData.Data=rightData;
2010
+ }
2011
+
2012
+ if (bindData.Period>0 && bindData.Period<=3) //周期数据
2013
+ {
2014
+ var periodData=bindData.GetPeriodData(bindData.Period);
2015
+ bindData.Data=periodData;
2016
+ }
2017
+
2018
+ //绑定数据
2019
+ this.SourceData=sourceData;
2020
+ this.Symbol=data.symbol;
2021
+ this.Name=data.name;
2022
+ this.BindMainData(bindData,this.PageSize);
2023
+ //this.BindInstructionIndexData(bindData); //执行指示脚本
2024
+
2025
+ var firstSubFrame;
2026
+ for(var i=0; i<this.Frame.SubFrame.length; ++i) //执行指标
2027
+ {
2028
+ if (i==0) firstSubFrame=this.Frame.SubFrame[i].Frame;
2029
+ this.BindIndexData(i,bindData);
2030
+ }
2031
+
2032
+ if (firstSubFrame && firstSubFrame.YSplitOperator)
2033
+ {
2034
+ firstSubFrame.YSplitOperator.Symbol=this.Symbol;
2035
+ firstSubFrame.YSplitOperator.Data=this.ChartPaint[0].Data; //K线数据
2036
+ }
2037
+
2038
+ //this.RequestFlowCapitalData(); //请求流通股本数据 (主数据下载完再下载)
2039
+ //this.RequestOverlayHistoryData(); //请求叠加数据 (主数据下载完再下载)
2040
+
2041
+ //刷新画图
2042
+ this.UpdataDataoffset(); //更新数据偏移
2043
+ this.UpdateFrameMaxMin(); //调整坐标最大 最小值
2044
+ this.Frame.SetSizeChage(true);
2045
+ this.Draw();
2046
+ this.UpdatePointByCursorIndex(); //更新十字光标位子
2047
+
2048
+ /*
2049
+ //叠加指标
2050
+ for(var i=0;i<this.Frame.SubFrame.length;++i)
2051
+ {
2052
+ var item=this.Frame.SubFrame[i];
2053
+ for(var j in item.OverlayIndex)
2054
+ {
2055
+ var overlayItem=item.OverlayIndex[j];
2056
+ this.BindOverlayIndexData(overlayItem,i,bindData)
2057
+ }
2058
+ }
2059
+ */
2060
+ }
2061
+
2062
+ this.UpdataDataoffset=function()
2063
+ {
2064
+ var data=null;
2065
+ if (this.Frame.Data)
2066
+ data=this.Frame.Data;
2067
+ else
2068
+ data=this.Frame.SubFrame[0].Frame.Data;
2069
+
2070
+ if (!data) return;
2071
+
2072
+ for(var i in this.ChartPaint)
2073
+ {
2074
+ var item =this.ChartPaint[i];
2075
+ if (!item.Data) continue;
2076
+ item.Data.DataOffset=data.DataOffset;
2077
+ }
2078
+
2079
+ for(var i in this.OverlayChartPaint)
2080
+ {
2081
+ var item =this.OverlayChartPaint[i];
2082
+ if (!item.Data) continue;
2083
+ item.Data.DataOffset=data.DataOffset;
2084
+ }
2085
+
2086
+ //叠加指标当前显示的数据偏移
2087
+ for (var i in this.Frame.SubFrame)
2088
+ {
2089
+ var subFrame=this.Frame.SubFrame[i];
2090
+ for(var j in subFrame.OverlayIndex)
2091
+ {
2092
+ var overlayItem=subFrame.OverlayIndex[j];
2093
+ for(var k in overlayItem.ChartPaint)
2094
+ {
2095
+ var item=overlayItem.ChartPaint[k];
2096
+ if (!item.Data) continue;
2097
+ item.Data.DataOffset=data.DataOffset;
2098
+ }
2099
+ }
2100
+ }
2101
+
2102
+ }
2103
+
2104
+ this.UpdateFrameMaxMin=function()
2105
+ {
2106
+ var frameMaxMinData=new Array();
2107
+
2108
+ var chartPaint=new Array();
2109
+
2110
+ for(var i in this.ChartPaint)
2111
+ {
2112
+ var item=this.ChartPaint[i];
2113
+ if (item.IsShow==false) continue; //隐藏的图形不计算
2114
+ chartPaint.push(this.ChartPaint[i]);
2115
+ }
2116
+ for(var i in this.OverlayChartPaint)
2117
+ {
2118
+ chartPaint.push(this.OverlayChartPaint[i]);
2119
+ }
2120
+
2121
+ for(var i in chartPaint)
2122
+ {
2123
+ var paint=chartPaint[i];
2124
+ var range=paint.GetMaxMin();
2125
+ if (range==null || range.Max==null || range.Min==null) continue;
2126
+ var frameItem=null;
2127
+ for(var j in frameMaxMinData)
2128
+ {
2129
+ if (frameMaxMinData[j].Frame==paint.ChartFrame)
2130
+ {
2131
+ frameItem=frameMaxMinData[j];
2132
+ break;
2133
+ }
2134
+ }
2135
+
2136
+ if (frameItem)
2137
+ {
2138
+ if (frameItem.Range.Max<range.Max) frameItem.Range.Max=range.Max;
2139
+ if (frameItem.Range.Min>range.Min) frameItem.Range.Min=range.Min;
2140
+ }
2141
+ else
2142
+ {
2143
+ frameItem={};
2144
+ frameItem.Frame=paint.ChartFrame;
2145
+ frameItem.Range=range;
2146
+ frameMaxMinData.push(frameItem);
2147
+ }
2148
+ }
2149
+
2150
+ for(var i in frameMaxMinData)
2151
+ {
2152
+ var item=frameMaxMinData[i];
2153
+ if (!item.Frame || !item.Range) continue;
2154
+ if (item.Range.Max==null || item.Range.Min==null) continue;
2155
+ if (item.Frame.YSpecificMaxMin)
2156
+ {
2157
+ item.Frame.HorizontalMax=item.Frame.YSpecificMaxMin.Max;
2158
+ item.Frame.HorizontalMin=item.Frame.YSpecificMaxMin.Min;
2159
+ }
2160
+ else
2161
+ {
2162
+ item.Frame.HorizontalMax=item.Range.Max;
2163
+ item.Frame.HorizontalMin=item.Range.Min;
2164
+ }
2165
+ item.Frame.XYSplit=true;
2166
+ }
2167
+
2168
+ //更新子坐标
2169
+ for(var i in this.Frame.SubFrame)
2170
+ {
2171
+ var subFrame=this.Frame.SubFrame[i];
2172
+ for(var j in subFrame.OverlayIndex)
2173
+ {
2174
+ var overlayItem=subFrame.OverlayIndex[j];
2175
+ overlayItem.UpdateFrameMaxMin();
2176
+ }
2177
+ }
2178
+ }
2179
+
2180
+ this.UpdatePointByCursorIndex=function()
2181
+ {
2182
+ this.LastPoint.X=this.Frame.GetXFromIndex(this.CursorIndex);
2183
+
2184
+ var index=Math.abs(this.CursorIndex-0.5);
2185
+ index=parseInt(index.toFixed(0));
2186
+ var data=this.Frame.Data;
2187
+ if (data.DataOffset+index>=data.Data.length)
2188
+ {
2189
+ return;
2190
+ }
2191
+ var close=data.Data[data.DataOffset+index].Close;
2192
+
2193
+ this.LastPoint.Y=this.Frame.GetYFromData(close);
2194
+ }
2195
+
2196
+ //显示隐藏主图K线
2197
+ this.ShowKLine=function(isShow)
2198
+ {
2199
+ if (this.ChartPaint.length<=0 || !this.ChartPaint[0]) return;
2200
+ this.ChartPaint[0].IsShow=isShow;
2201
+ }
2202
+
2203
+ }