コピペ: OmegaChart 任意のローソク足でルーラーを止める ChartCanvas.cs 追加・修正ポイントには//☆FixDate

形式
Plain text
投稿日時
2019-03-07 17:55
公開期間
無期限
  1. /*
  2. * Copyright (c) Daisuke OKAJIMA All rights reserved.
  3. *
  4. * $Id$
  5. */
  6. using System;
  7. using System.Collections;
  8. using System.ComponentModel;
  9. using System.Drawing;
  10. using System.Windows.Forms;
  11. using System.Diagnostics;
  12. using Zanetti.Indicators;
  13. using Zanetti.Data;
  14. using Zanetti.Forms;
  15. namespace Zanetti.UI
  16. {
  17. /// <summary>
  18. /// </summary>
  19. internal class ChartCanvas : System.Windows.Forms.UserControl
  20. {
  21. private AbstractBrand _brand;
  22. private ChartDrawing _drawing;
  23. private ChartTitle _title;
  24. private System.Windows.Forms.HScrollBar _scrollBar;
  25. private Label _complementaryLabel;
  26. private int _diffX = 0;
  27. private int _diffY = 0;
  28. private int _destX = 0;
  29. private int _pivotX = 0;
  30. private int _destY = 0;
  31. private int _pivotY = 0;
  32. /// <summary>
  33. /// 必要なデザイナ変数です。
  34. /// </summary>
  35. private System.ComponentModel.Container components = null;
  36. public ChartCanvas()
  37. {
  38. // この呼び出しは、Windows.Forms フォーム デザイナで必要です。
  39. InitializeComponent();
  40. // TODO: InitializeComponent 呼び出しの後に初期化処理を追加します。
  41. this.BackColor = Env.Preference.BackBrush.Color;
  42. this.SetStyle(ControlStyles.AllPaintingInWmPaint|ControlStyles.DoubleBuffer, true);
  43. _drawing = new ChartDrawing(this);
  44. }
  45. /// <summary>
  46. /// 使用されているリソースに後処理を実行します。
  47. /// </summary>
  48. protected override void Dispose( bool disposing )
  49. {
  50. if( disposing )
  51. {
  52. if(components != null)
  53. {
  54. components.Dispose();
  55. }
  56. }
  57. base.Dispose( disposing );
  58. }
  59. #region コンポーネント デザイナで生成されたコード
  60. /// <summary>
  61. /// デザイナ サポートに必要なメソッドです。このメソッドの内容を
  62. /// コード エディタで変更しないでください。
  63. /// </summary>
  64. private void InitializeComponent()
  65. {
  66. this._scrollBar = new System.Windows.Forms.HScrollBar();
  67. _title = new ChartTitle();
  68. this.SuspendLayout();
  69. //
  70. // _scrollBar
  71. //
  72. this._scrollBar.Dock = System.Windows.Forms.DockStyle.Bottom;
  73. this._scrollBar.Enabled = false;
  74. this._scrollBar.LargeChange = 2;
  75. this._scrollBar.Location = new System.Drawing.Point(0, 83);
  76. this._scrollBar.Maximum = 4;
  77. this._scrollBar.Name = "_scrollBar";
  78. this._scrollBar.Size = new System.Drawing.Size(100, 17);
  79. this._scrollBar.TabIndex = 0;
  80. this._scrollBar.ValueChanged += new System.EventHandler(this.OnScrollBarValueChanged);
  81. _title.Location = new Point(0, 0);
  82. _title.Size = new Size(this.Width, Env.Layout.HeaderHeight);
  83. //
  84. // ChartCanvas
  85. //
  86. this.Controls.Add(this._scrollBar);
  87. this.Controls.Add(this._title);
  88. this.MouseUp += new MouseEventHandler(OnMouseUp);
  89. this.Name = "ChartCanvas";
  90. this.Size = new System.Drawing.Size(100, 100);
  91. this.ResumeLayout(false);
  92. _title.BringToFront();
  93. }
  94. #endregion
  95. public Label ComplementaryLabel {
  96. get {
  97. if(_complementaryLabel==null) {
  98. _complementaryLabel = new Label();
  99. _complementaryLabel.Visible = false;
  100. _complementaryLabel.Font = Env.Preference.DefaultFont;
  101. _complementaryLabel.TextAlign = ContentAlignment.MiddleLeft;
  102. _complementaryLabel.BorderStyle = BorderStyle.FixedSingle;
  103. _complementaryLabel.BackColor = Color.FromKnownColor(KnownColor.Info);
  104. _complementaryLabel.ForeColor = Color.FromKnownColor(KnownColor.InfoText);
  105. this.Controls.Add(_complementaryLabel);
  106. }
  107. return _complementaryLabel;
  108. }
  109. }
  110. public ChartTitle ChartTitle {
  111. get {
  112. return _title;
  113. }
  114. }
  115. public ChartDrawing DrawingEngine {
  116. get {
  117. return _drawing;
  118. }
  119. }
  120. public int BodyHeight {
  121. get {
  122. return this.Height - _scrollBar.Height;
  123. }
  124. }
  125. public void LoadBrand(AbstractBrand br, bool preserve_date) {
  126. int date = -1;
  127. if(preserve_date && _brand!=null) {
  128. DataFarm f = _brand.ReserveFarm();
  129. if(!f.IsEmpty) {
  130. Debug.Assert(_drawing.FirstDateIndex>=0 && _drawing.FirstDateIndex<f.TotalLength);
  131. if(_drawing.FirstDateIndex + Env.Layout.DisplayColumnCount >= f.TotalLength)
  132. date = -1; //最終データが見えているときは「最後が見えている」状態を維持
  133. else
  134. date = f.GetByIndex(_drawing.FirstDateIndex).Date;
  135. }
  136. }
  137. _brand = br;
  138. AdjustScrollBar();
  139. if(_scrollBar.Enabled) {
  140. DataFarm f = br.ReserveFarm();
  141. int v = date==-1? GetTotalDataLength() - Env.Layout.DisplayColumnCount : f.DateToIndex(date);
  142. if(v<0) v = 0;
  143. if(v>_scrollBar.Maximum-_scrollBar.LargeChange+1) v = _scrollBar.Maximum-_scrollBar.LargeChange+1;
  144. _scrollBar.Value = v;
  145. }
  146. _drawing.SetBrand(br);
  147. //_title.InitUI();
  148. }
  149. public AbstractBrand GetBrand() {
  150. return _brand;
  151. }
  152. public int FirstDateIndex {
  153. get {
  154. return _drawing.FirstDateIndex;
  155. }
  156. }
  157. public void MoveToLatest() {
  158. AdjustScrollBar();
  159. int v = 0;
  160. if(_scrollBar.Enabled) v = GetTotalDataLength() - Env.Layout.DisplayColumnCount;
  161. if(v<0) v = 0;
  162. _scrollBar.Value = v;
  163. Invalidate(false);
  164. }
  165. public void SetDateIndex(int first, int cursor) {
  166. _scrollBar.Value = first;
  167. DataFarm f = _brand.ReserveFarm();
  168. if(f.IsEmpty)
  169. _drawing.UpdateDateLineIndex(-1);
  170. else
  171. _drawing.UpdateDateLineIndex(Math.Min(cursor, f.FilledLength-1));
  172. Invalidate(true);
  173. }
  174. public void ForceVisibleDate(int date, bool cut) {
  175. DataFarm f = _brand.ReserveFarm();
  176. if(f.IsEmpty) return;
  177. int index = f.DateToIndex(date);
  178. //スクロールしないと見えない
  179. if(_drawing.FirstDateIndex>index || index>=_drawing.FirstDateIndex+Env.Layout.DisplayColumnCount || cut) {
  180. int nv = index - Env.Layout.DisplayColumnCount/2; //大体真ん中に表示
  181. if(nv<0) nv = 0;
  182. if(nv>=f.TotalLength) nv = f.TotalLength-1;
  183. _scrollBar.Value = nv;
  184. }
  185. _drawing.UpdateDateLineIndex(index);
  186. Invalidate(false);
  187. }
  188. public void ReloadFromPreference() {
  189. Preference pref = Env.Preference;
  190. Color bc = pref.BackBrush.Color;
  191. Color fc = pref.TextColor;
  192. this.BackColor = bc;
  193. this.ForeColor = fc;
  194. if(_complementaryLabel!=null) _complementaryLabel.Font = pref.DefaultFont;
  195. //InitOscillatorGroupUI();
  196. _drawing.ClearScale();
  197. }
  198. public void ResetLayout() {
  199. //_oscillatorGroup.Visible = Env.Options.ShowOscillator;
  200. AdjustScrollBar(); //これは価格帯出来高の表示設定が変化したときだけでもよい
  201. _drawing.ClearScale();
  202. _title.InitUI();
  203. }
  204. //メッセージ処理がらみ
  205. protected override void OnLoad(EventArgs e) {
  206. base.OnLoad (e);
  207. Preference pref = Env.Preference;
  208. }
  209. protected override void OnPaint(PaintEventArgs e) {
  210. base.OnPaint (e);
  211. if(this.DesignMode || _brand==null) return;
  212. _drawing.PaintMain(e.Graphics, e.ClipRectangle);
  213. if(_currentFreeLine!=null && _currentFreeLine.PivotHasEnoughDistanceTo(this.PointToClient(Control.MousePosition))) {
  214. IntPtr hdc = e.Graphics.GetHdc();
  215. _currentFreeLine.Draw(Env.Layout.ChartBodyRect, hdc);
  216. e.Graphics.ReleaseHdc(hdc);
  217. }
  218. }
  219. protected override void OnResize(EventArgs e) {
  220. base.OnResize (e);
  221. if(!this.DesignMode && _drawing!=null && _brand!=null && Env.Frame.WindowState!=FormWindowState.Minimized) {
  222. bool last_is_visible = !_scrollBar.Enabled || _scrollBar.Value+_scrollBar.LargeChange>=_scrollBar.Maximum;
  223. _drawing.ClearScale();
  224. AdjustScrollBar();
  225. this.SuspendLayout();
  226. Preference pref = Env.Preference;
  227. //_oscillatorGroup.Top = this.BodyHeight - _oscillatorGroup.Height - 8;
  228. //_oscillatorGroup.Left = this.Width - Env.Layout.RemarkAreaWidth+5;
  229. if(!_brand.ReserveFarm().IsEmpty && last_is_visible) { //最新データ見えているときのリサイズはその状態を維持
  230. int v = _brand.ReserveFarm().TotalLength - Env.Layout.DisplayColumnCount;
  231. if(v<0) v = 0;
  232. _scrollBar.Value = v; //このままValueChangedイベントも誘発
  233. }
  234. Invalidate(false);
  235. this.ResumeLayout();
  236. }
  237. }
  238. protected override void OnMouseMove(MouseEventArgs ev) {
  239. base.OnMouseMove (ev);
  240. if(_drawing==null) return;
  241. Preference pref = Env.Preference;
  242. //隠れてしまうIndicatorテキストの表示・非表示
  243. Point p = new Point(ev.X, ev.Y);//this.PointToClient(Control.MousePosition);
  244. if(_complementaryLabel!=null && _complementaryLabel.Visible) {
  245. if(!new Rectangle(_complementaryLabel.Location, _complementaryLabel.Size).Contains(p))
  246. _complementaryLabel.Visible = false;
  247. }
  248. else {
  249. ArrayList ar = _drawing.TipEntries;
  250. if(ar!=null) {
  251. foreach(ComplementaryTextEntry e in ar) {
  252. if(e.rect.Contains(p)) {
  253. Label l = this.ComplementaryLabel;
  254. l.Location = new Point(e.rect.X-2, e.rect.Y-1);
  255. l.Size = new Size(e.rect.Size.Width+5, e.rect.Size.Height+2);
  256. l.Text = e.text;
  257. l.Visible = true;
  258. l.BringToFront();
  259. l.Invalidate();
  260. break;
  261. }
  262. }
  263. }
  264. }
  265. int offset = -1;
  266. if(p.X >= 0 && p.X < Env.Layout.ChartAreaWidth) {
  267. offset = (p.X-Env.Layout.CandleMiddleOffset) / Env.Layout.DatePitch;
  268. DataFarm farm = _brand.ReserveFarm();
  269. if(!farm.IsEmpty && _drawing.FirstDateIndex+offset>=farm.TotalLength) offset = -1;
  270. }
  271. //横線
  272. if(Env.Preference.MouseTrackingLineMode==MouseTrackingLineMode.Full) {
  273. int my = _drawing.NormalizeByYobine(ev.Y);
  274. if(my!=_drawing.PriceLine._lastDrawn) {
  275. int h = Env.Layout.DefaultTextHeight;
  276. Rectangle yr = new Rectangle(0, _drawing.PriceLine._lastDrawn-h/2, this.Width, h);
  277. Invalidate(yr, false);
  278. yr = new Rectangle(0, my-h/2, this.Width, h);
  279. Invalidate(yr, false);
  280. }
  281. _drawing.PriceLine._nextToBeDrawn = my;
  282. }
  283. if (!Env.FixDate)//☆FixDate このif文で囲む
  284. {
  285. //必要なエリアのInvalidate
  286. int ld = _drawing.DateLine._lastDrawn;
  287. if (offset == -1)
  288. {
  289. if (ld != -1)
  290. {
  291. Rectangle r = Env.Layout.CurrentValueRect;
  292. Invalidate(r, false);
  293. int t = ld - _drawing.FirstDateIndex;
  294. r = new Rectangle((t - 1) * Env.Layout.DatePitch, 0, Env.Layout.DatePitch * 2, this.Height);
  295. Invalidate(r, false);
  296. }
  297. _drawing.UpdateDateLineIndex(-1);
  298. }
  299. else
  300. {
  301. if (_drawing.FirstDateIndex + offset != ld)
  302. {
  303. Rectangle r = Env.Layout.CurrentValueRect;
  304. //r.X += ChartDrawing.VALUEWINDOW_HEADER_WIDTH;
  305. Invalidate(r, false);
  306. //価格帯出来高
  307. if (Env.Preference.ShowAccumulativeVolume)
  308. Invalidate(Env.Layout.AccumulativeVolumeRect, false);
  309. //節の数値のこともあるので広めにInvalidateする
  310. if (ld != -1)
  311. {
  312. int t = ld - _drawing.FirstDateIndex;
  313. //Debug.WriteLine(String.Format("prev offset={0}", t));
  314. r = new Rectangle((t - 1) * Env.Layout.DatePitch, 0, Env.Layout.DatePitch * 2, this.Height);
  315. Invalidate(r, false);
  316. }
  317. r = new Rectangle((offset - 1) * Env.Layout.DatePitch, 0, Env.Layout.DatePitch * 2, this.Height);
  318. Invalidate(r, false);
  319. }
  320. _drawing.UpdateDateLineIndex(_drawing.FirstDateIndex + offset);
  321. }
  322. }
  323. //今引いている直線の再描画
  324. if(_currentFreeLine!=null) {
  325. Invalidate(_currentFreeLine.GetInclusion(this.ClientRectangle), false);
  326. _currentFreeLine.Destination = p;
  327. }
  328. //左クリックしながら、マウスを動かした場合、コピー中と見なす。
  329. if (_diffX != 0 && _diffY != 0 && ev.Button == MouseButtons.Left && Win32.GetAsyncKeyState(System.Windows.Forms.Keys.ShiftKey) < 0 & 0x8000 != 0)
  330. {
  331. _currentFreeLine = new FreeLine(new Point(ev.X, ev.Y), new Point(ev.X - _diffX, ev.Y - _diffY));
  332. }
  333. //Controlキーを押しながら、マウスで左クリックしている時は、ピボット・コピー中と見なす。
  334. if (_diffX != 0 && _diffY != 0 && ev.Button == MouseButtons.Left && Win32.GetAsyncKeyState(System.Windows.Forms.Keys.ControlKey) < 0 & 0x8000 != 0)
  335. {
  336. int x, y = 0;
  337. if (_pivotX < _destX)//画面左から右へと引いたフリーライン
  338. {
  339. if ((_pivotX + _destX) / 2 > ev.X)//軸となる点は旧_dest
  340. {
  341. x = _destX;
  342. y = _destY;
  343. }
  344. else//軸となる点は旧_pivot
  345. {
  346. x = _pivotX;
  347. y = _pivotY;
  348. }
  349. }
  350. else//画面右から左へと引いたフリーライン
  351. {
  352. if ((_pivotX + _destX) / 2 > ev.X)//軸となる点は旧_pivot
  353. {
  354. x = _pivotX;
  355. y = _pivotY;
  356. }
  357. else//軸となる点は旧_dest
  358. {
  359. x = _destX;
  360. y = _destY;
  361. }
  362. }
  363. _currentFreeLine = new FreeLine(new Point(x, y), new Point(ev.X, ev.Y));
  364. }
  365. //接近した線があればそれをクリア
  366. bool near_line_found = false;
  367. foreach(FreeLine line in _drawing.FreeLines) {
  368. double d = line.GetDistance(p);
  369. FreeLine.LineDrawMode m = d<3? FreeLine.LineDrawMode.Hilight : FreeLine.LineDrawMode.Normal;
  370. if(line.DrawMode!=m) {
  371. line.DrawMode = m;
  372. Invalidate(line.GetInclusion(this.ClientRectangle), false);
  373. }
  374. if(!near_line_found) near_line_found = m==FreeLine.LineDrawMode.Hilight;
  375. }
  376. this.Cursor = near_line_found? Cursors.Hand : Cursors.Default;
  377. }
  378. private void OnMouseUp(object sender, MouseEventArgs args) {
  379. if(args.Button==MouseButtons.Right) {
  380. ContextMenu m = Env.Frame.CreateContextMenu();
  381. m.Show(this, new Point(args.X, args.Y));
  382. }
  383. else if(args.Button==MouseButtons.Left) {
  384. if(_currentFreeLine!=null) {
  385. if(_drawing.FreeLineCount==10) {
  386. Util.Warning(Env.Frame, "線は1銘柄につき10本までしか引けません");
  387. Invalidate();
  388. }
  389. else if(Env.FreeLines.Count==1000) {
  390. Util.Warning(Env.Frame, "線は全部で1000本までしか引けません");
  391. Invalidate();
  392. }
  393. else if(_currentFreeLine.PivotHasEnoughDistanceTo(_currentFreeLine.Destination)) {
  394. _drawing.FixFreeLine(_currentFreeLine);
  395. }
  396. _currentFreeLine = null;
  397. }
  398. if(_drawing.RemoveHighlitedFreeLines()) Invalidate(); //削除されたやつがあればInvalidate
  399. }
  400. }
  401. protected override bool IsInputChar(char charCode) {
  402. return false;
  403. }
  404. private void AdjustScrollBar() {
  405. if(_brand==null || _brand.ReserveFarm().IsEmpty) {
  406. _scrollBar.Enabled = false;
  407. }
  408. else {
  409. Preference pref = Env.Preference;
  410. int total = GetTotalDataLength();
  411. int display = Env.Layout.DisplayColumnCount;
  412. if(display>=total) {
  413. _scrollBar.Enabled = false;
  414. _scrollBar.Value = 0;
  415. _drawing.FirstDateIndex = 0;
  416. }
  417. else {
  418. int v = _scrollBar.Value;
  419. _scrollBar.LargeChange = display;
  420. _scrollBar.Maximum = total-1;
  421. //Debug.WriteLine(String.Format("Adjusted disp={0} all={1} v={2}", display, all, v));
  422. if(v > _scrollBar.Maximum - display) _scrollBar.Value = _scrollBar.Maximum - display + 1;
  423. _scrollBar.Enabled = true;
  424. }
  425. }
  426. }
  427. private int GetTotalDataLength() {
  428. return _brand.ReserveFarm().TotalLength;
  429. }
  430. private void OnScrollBarValueChanged(object sender, EventArgs args) {
  431. if(this.DesignMode) return;
  432. int v = _scrollBar.Value;
  433. _drawing.FirstDateIndex = v;
  434. //Debug.WriteLine(String.Format("ValueChange max={0} lc={1} v={2}", _scrollBar.Maximum, _scrollBar.LargeChange, v));
  435. _drawing.ClearScale();
  436. Invalidate();
  437. }
  438. /*
  439. private void OnOscillatorGroupCheckedChanged(object sender, EventArgs args) {
  440. int i = _oscillatorGroupBoxes.IndexOf(sender);
  441. Debug.Assert(i!=-1);
  442. _drawing.OscillatorGroup = Env.CurrentIndicators.GetOscillatorGroupAt(i);
  443. Invalidate();
  444. }
  445. */
  446. //FreeLine関係
  447. private FreeLine _currentFreeLine;
  448. protected override void OnMouseDown(MouseEventArgs e) {
  449. base.OnMouseDown (e);
  450. if (Env.FixDate) Env.FixDate = false;//☆FixDate
  451. if (e.Button==MouseButtons.Left){
  452. if(_brand.ReserveFarm().IsEmpty) return;
  453. foreach (FreeLine line in _drawing.FreeLines)
  454. {
  455. if (line.DrawMode == FreeLine.LineDrawMode.Hilight && e.Button == MouseButtons.Left)
  456. {
  457. _diffX = line.Destination.X - line.Pivot.X;
  458. _diffY = line.Destination.Y - line.Pivot.Y;
  459. _destX = line.Destination.X;
  460. _destY = line.Destination.Y;
  461. _pivotX = line.Pivot.X;
  462. _pivotY = line.Pivot.Y;
  463. }
  464. }
  465. _currentFreeLine = new FreeLine(new Point(e.X, e.Y));
  466. }
  467. }
  468. protected override void OnDoubleClick(EventArgs e)
  469. {
  470. base.OnDoubleClick(e);
  471. var ev = (MouseEventArgs)e;
  472. _currentFreeLine = new FreeLine(new Point(0, ev.Y), new Point(ev.X, ev.Y));
  473. }
  474. public void ClearCurrentFreeLine() {
  475. if(_currentFreeLine!=null) {
  476. Invalidate(_currentFreeLine.GetInclusion(Env.Layout.ChartBodyRect), false);
  477. _currentFreeLine = null;
  478. }
  479. }
  480. //DOJIMA用半日足修正
  481. #if DOJIMA
  482. protected override void OnDoubleClick(EventArgs e) {
  483. base.OnDoubleClick (e);
  484. if(Env.CurrentIndicators.Format!=ChartFormat.HalfDaily) return;
  485. int index = _drawing.DateLine._lastDrawn;
  486. DailyDataFarm f = _brand.ReserveFarm() as DailyDataFarm;
  487. if(index<0 || index>=f.FilledLength) return;
  488. Dojima.ModifyHalfDayData dlg = new Dojima.ModifyHalfDayData();
  489. dlg.InitUI(f.GetByIndex(index), Dojima.DojimaUtil.HalfDailyDataFarmCache.Get(f), index);
  490. if(dlg.ShowDialog(Env.Frame)==DialogResult.OK) {
  491. Invalidate(true); //全画面再描画
  492. }
  493. }
  494. #endif
  495. }
  496. }
ダウンロード 印刷用表示

このコピペの URL

JavaScript での埋め込み

iframe での埋め込み

元のテキスト