public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point) { if (!IsVisible) { return(null); } switch (DrawingState) { case DrawingState.Building: return(Cursors.Pen); case DrawingState.Moving: return(IsLocked ? Cursors.No : Cursors.SizeAll); case DrawingState.Editing: if (IsLocked) { return(Cursors.No); } return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE); default: Point startAnchorPixelPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale); ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point); if (closest != null) { if (IsLocked) { return(Cursors.Arrow); } return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE); } // Check the anchor lines for cursor Point endAnchorPixelPoint = EndAnchor.GetPoint(chartControl, chartPanel, chartScale); Point extAnchorPixelPoint = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale); Point midAnchorPixelPoint = new Point((endAnchorPixelPoint.X + extAnchorPixelPoint.X) / 2, (endAnchorPixelPoint.Y + extAnchorPixelPoint.Y) / 2); Vector startToEndVec = endAnchorPixelPoint - startAnchorPixelPoint; Vector endToExtVec = extAnchorPixelPoint - endAnchorPixelPoint; Vector startToMidVec = midAnchorPixelPoint - startAnchorPixelPoint; foreach (Tuple <Point, Point> endPoint in GetAndrewsEndPoints(chartControl, chartScale)) { Vector andrewVector = endPoint.Item1 - endPoint.Item2; if (MathHelper.IsPointAlongVector(point, endPoint.Item2, andrewVector, cursorSensitivity)) { return(IsLocked ? Cursors.Arrow : Cursors.SizeAll); } } return(MathHelper.IsPointAlongVector(point, startAnchorPixelPoint, startToEndVec, cursorSensitivity) || MathHelper.IsPointAlongVector(point, endAnchorPixelPoint, endToExtVec, cursorSensitivity) || MathHelper.IsPointAlongVector(point, startAnchorPixelPoint, startToMidVec, cursorSensitivity) ? (IsLocked ? Cursors.Arrow : Cursors.SizeAll) : null); } }
private IEnumerable <Tuple <Point, Point> > GetAndrewsEndPoints(ChartControl chartControl, ChartScale chartScale) { ChartPanel panel = chartControl.ChartPanels[PanelIndex]; double totalPriceRange = EndAnchor.Price - ExtensionAnchor.Price; double startPrice = ExtensionAnchor.Price; Point anchorExtensionPoint = ExtensionAnchor.GetPoint(chartControl, panel, chartScale); Point anchorStartPoint = StartAnchor.GetPoint(chartControl, panel, chartScale); Point anchorEndPoint = EndAnchor.GetPoint(chartControl, panel, chartScale); Point midPointExtension = new Point((anchorExtensionPoint.X + anchorEndPoint.X) / 2, (anchorExtensionPoint.Y + anchorEndPoint.Y) / 2); foreach (PriceLevel pl in PriceLevels.Where(pl => pl.IsVisible)) { double levelPrice = (startPrice + ((pl.Value / 100) * totalPriceRange)); float pixelY = chartScale.GetYByValue(levelPrice); float pixelX = anchorExtensionPoint.X > anchorEndPoint.X ? (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (pl.Value / 100)))) : (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (pl.Value / 100))); Point startPoint = new Point(pixelX, pixelY); Point endPoint = new Point(startPoint.X + (midPointExtension.X - anchorStartPoint.X), startPoint.Y + (midPointExtension.Y - anchorStartPoint.Y)); Point maxLevelPoint = GetExtendedPoint(startPoint, endPoint); yield return(new Tuple <Point, Point>(new Point(Math.Max(maxLevelPoint.X, 1), Math.Max(maxLevelPoint.Y, 1)), startPoint)); } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { try { if (!model.parent.Input_TickAggregator_OnOff) { Dispose(); return; } if (model != null) { SharpDX.Direct2D1.AntialiasMode oldAntialiasMode = RenderTarget.AntialiasMode; RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex]; Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale); // align to full pixel to avoid unneeded aliasing double strokePixAdj = ((double)(1 % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d; Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj); //Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale); // convert our start / end pixel points to directx 2d vectors Point startPointAdjusted = startPoint + pixelAdjustVec; SharpDX.Vector2 startVec = startPointAdjusted.ToVector2(); // if a plain ol' line, then we're all done // if we're an arrow line, make sure to draw the actual line. for extended lines, only a single // line to extended points is drawn below, to avoid unneeded multiple DrawLine calls // RenderTarget.DrawLine(startVec, endVec, tmpBrush, LineStroke.Width, LineStroke.StrokeStyle); brush0DX = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.WhiteSmoke); brush1DX = model.parent.Input_TickAggregator_AskColor.ToDxBrush(RenderTarget); brush1DX.Opacity = (float)0.3; brush2DX = model.parent.Input_TickAggregator_BidColor.ToDxBrush(RenderTarget); brush2DX.Opacity = (float)0.3; brush3DX = model.parent.Input_TickAggregator_AskColor.ToDxBrush(RenderTarget); brush4DX = model.parent.Input_TickAggregator_BidColor.ToDxBrush(RenderTarget); brush5DX = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.Black); brush5DX.Opacity = (float)0.01; brush6DX = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.White); brush6DX.Opacity = (float)0.3; brush7DX = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget, SharpDX.Color.White); SharpDX.Direct2D1.Ellipse el = new SharpDX.Direct2D1.Ellipse(startVec, Radius, Radius); int Position_Y1 = chartScale.GetYByValue(TickAggregatorData.TopPrice) - model.Claster_Height / 2; int Position_Y2 = chartScale.GetYByValue(TickAggregatorData.LowPrice); int Delta_Y = Position_Y2 - Position_Y1 + model.Claster_Height / 2; if (Delta_Y < 1) { Delta_Y = model.Claster_Height; } int max = model.parent.Input_TickAggregator_Distance; int Position_X1 = chartControl.GetXByTime(TickAggregatorData.Time); int Delta_X = TickAggregatorData.Volume * max / model.MaxTickAggregatorVolume; int Delta_X_Ask = TickAggregatorData.Volume_Ask * Delta_X / 100; int Delta_X_Bid = Delta_X - Delta_X_Ask; if (IsSelected) { SharpDX.DirectWrite.TextFormat Claster_textFormat = chartControl.Properties.LabelFont.ToDirectWriteTextFormat(); string str = "Volume: " + TickAggregatorData.Volume.ToString() + " ="; //+" - "+TickAggregatorData.Volume_Ask.ToString()+" - "+TickAggregatorData.Volume_Bid.ToString(); //string str =""; bool tmpFirst = true; foreach (Model.Print p in TickAggregatorData.PrintList) { if (p.Volume >= model.parent.Input_TickAggregator_TickShow) { if (tmpFirst) { str += " " + p.Volume; tmpFirst = false; } else { str += " + " + p.Volume; } } else { break; } } string str1 = "Time: " + TickAggregatorData.Time.ToLongTimeString() + " MaxPrice: " + TickAggregatorData.TopPrice.ToString() + " MinPrice: " + TickAggregatorData.LowPrice.ToString() + " Ask: " + TickAggregatorData.Volume_Ask.ToString() + "% Bid:" + TickAggregatorData.Volume_Bid.ToString() + "% Delta: " + TickAggregatorData.Volume_Delta.ToString() + "%"; if (model.parent.Input_TickAggregator_Standart) { RenderTarget.DrawText(str1, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, startVec.Y - Radius - 23, str1.Length * 8, 10), brush0DX); RenderTarget.DrawText(str, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, startVec.Y - Radius - 12, str.Length * 8, 10), brush0DX); } else { RenderTarget.DrawText(str1, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, Position_Y1 - 23, str1.Length * 8, 10), brush0DX); RenderTarget.DrawText(str, Claster_textFormat, new SharpDX.RectangleF(startVec.X + 5, Position_Y1 - 12, str.Length * 8, 10), brush0DX); } Claster_textFormat.Dispose(); } if (model.parent.Input_TickAggregator_Standart) { if (TickAggregatorData.Volume_Ask > TickAggregatorData.Volume_Bid) { RenderTarget.DrawEllipse(el, brush3DX); if (IsSelected) { RenderTarget.FillEllipse(el, brush1DX); } } else if (TickAggregatorData.Volume_Ask < TickAggregatorData.Volume_Bid) { RenderTarget.DrawEllipse(el, brush4DX); if (IsSelected) { RenderTarget.FillEllipse(el, brush2DX); } } else if (TickAggregatorData.Volume_Ask == TickAggregatorData.Volume_Bid) { RenderTarget.DrawEllipse(el, brush7DX); if (IsSelected) { RenderTarget.FillEllipse(el, brush6DX); } } if (!IsSelected) { RenderTarget.FillEllipse(el, brush5DX); } } else { RenderTarget.FillRectangle(new SharpDX.RectangleF(Position_X1, Position_Y1, Delta_X_Ask, Delta_Y), brush1DX); RenderTarget.FillRectangle(new SharpDX.RectangleF(Position_X1 + Delta_X_Ask, Position_Y1, Delta_X_Bid, Delta_Y), brush2DX); } RenderTarget.AntialiasMode = oldAntialiasMode; if (brush0DX != null) { brush0DX.Dispose(); } if (brush1DX != null) { brush1DX.Dispose(); } if (brush2DX != null) { brush2DX.Dispose(); } if (brush3DX != null) { brush3DX.Dispose(); } if (brush4DX != null) { brush4DX.Dispose(); } if (brush5DX != null) { brush5DX.Dispose(); } if (brush6DX != null) { brush6DX.Dispose(); } if (brush7DX != null) { brush7DX.Dispose(); } } } catch (Exception ex) { Print("MR CustomEllipse 417: " + ex); } return; }
public override Cursor GetCursor(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, Point point) { switch (DrawingState) { case DrawingState.Building: return(Cursors.Pen); case DrawingState.Moving: return(IsLocked ? Cursors.No : Cursors.SizeAll); case DrawingState.Editing: if (IsLocked) { return(Cursors.No); } return(editingAnchor == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE); default: // draw move cursor if cursor is near line path anywhere Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale); ChartAnchor closest = GetClosestAnchor(chartControl, chartPanel, chartScale, cursorSensitivity, point); if (closest != null) { if (IsLocked) { return(Cursors.Arrow); } return(closest == StartAnchor ? Cursors.SizeNESW : Cursors.SizeNWSE); } int Position_Y1 = chartScale.GetYByValue(TickAggregatorData.TopPrice) - model.Claster_Height / 2; int Position_Y2 = chartScale.GetYByValue(TickAggregatorData.LowPrice); int Delta_Y = Position_Y2 - Position_Y1 + model.Claster_Height / 2; if (Delta_Y < 1) { Delta_Y = model.Claster_Height; } int max = model.parent.Input_TickAggregator_Distance; int Position_X1 = chartControl.GetXByTime(TickAggregatorData.Time); int Delta_X = TickAggregatorData.Volume * max / model.MaxTickAggregatorVolume; //Point endPoint = EndAnchor.GetPoint(chartControl, chartPanel, chartScale); Point TopLeft = new Point(Position_X1, Position_Y1); Point TopRight = new Point(Position_X1 + Delta_X, Position_Y1); Point BotRight = new Point(Position_X1 + Delta_X, Position_Y1 + Delta_Y); Point BotLeft = new Point(Position_X1, Position_Y1 + Delta_Y); //Point maxPoint = endPoint; Vector totalVector = startPoint - point; if (model.parent.Input_TickAggregator_Standart) { return(Math.Abs(totalVector.Length) <= Radius + cursorSensitivity? IsLocked ? Cursors.Arrow : Cursors.SizeAll : null); } else { return(MathHelper.IsPointInsideTriangle(point, TopLeft, TopRight, BotLeft) || MathHelper.IsPointInsideTriangle(point, BotLeft, TopRight, BotRight)? IsLocked ? Cursors.Arrow : Cursors.SizeAll : null); } } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { if (model == null) { return; } try { // first of all, turn on anti-aliasing to smooth out our line RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; ChartPanel panel = chartControl.ChartPanels[chartScale.PanelIndex]; Point startPoint = StartAnchor.GetPoint(chartControl, panel, chartScale); Point endPoint = EndAnchor.GetPoint(chartControl, panel, chartScale); // convert our start / end pixel points to directx 2d vectors Point startPointAdjusted = startPoint /*+ pixelAdjustVec*/; Point endPointAdjusted = endPoint /*+ pixelAdjustVec*/; SharpDX.Vector2 startVec = startPointAdjusted.ToVector2(); SharpDX.Vector2 endVec = endPointAdjusted.ToVector2(); //SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : LineStroke.BrushDX; SharpDX.Vector2 tmpVect = startVec - endVec; SharpDX.Direct2D1.Brush brush = Brushes.Red.ToDxBrush(RenderTarget); brush.Opacity = IsSelected ? (float)0.3 : 0; RenderTarget.DrawRectangle(new SharpDX.RectangleF(endVec.X, endVec.Y, tmpVect.X, tmpVect.Y), model.Input_ProfileRange_Border_Color.ToDxBrush(RenderTarget), (float)1); //RenderTarget.FillRectangle(new SharpDX.RectangleF(endVec.X, endVec.Y, tmpVect.X, tmpVect.Y),brush); int firstindex = ((int)model.parent.ChartControl.GetSlotIndexByTime(StartAnchor.Time)); int lastIndex = ((int)model.parent.ChartControl.GetSlotIndexByTime(EndAnchor.Time)); IEnumerable <Model.Bar> bars; if (firstindex <= lastIndex) { bars = model.GetBarRange(firstindex, lastIndex); } else { bars = model.GetBarRange(lastIndex, firstindex); } int leftPosition = 0; int topPosition = 0; if (startVec.X < endVec.X) { leftPosition = (int)startVec.X; } else { leftPosition = (int)endVec.X; } if (startVec.Y < endVec.Y) { topPosition = (int)startVec.Y; } else { topPosition = (int)endVec.Y; } Model.HistogrammClass profile = new Model.HistogrammClass(); int count = 0; foreach (Model.Bar bar in bars) { IEnumerable <KeyValuePair <double, Model.Claster> > clasters; if (StartAnchor.Price >= EndAnchor.Price) { clasters = bar.ListOfClasters.Where(c => c.Key <= StartAnchor.Price && c.Key >= EndAnchor.Price); } else { clasters = bar.ListOfClasters.Where(c => c.Key >= StartAnchor.Price && c.Key <= EndAnchor.Price); } foreach (KeyValuePair <double, Model.Claster> claster in clasters) { profile.AddPrintToHistogramm(claster.Key, claster.Value.Volume_Ask_sum, PrintType.ASK); profile.AddPrintToHistogramm(claster.Key, claster.Value.Volume_Bid_sum, PrintType.BID); } } //textToRender+=" : "+profile.ListOfCurrentBar.Count.ToString(); SharpDX.Direct2D1.Brush profile_Claster_Color = model.Input_ProfileRange_Inside_Color.ToDxBrush(RenderTarget); profile_Claster_Color.Opacity = (float)0.5; int volumeSum = 0; foreach (KeyValuePair <double, Model.CurrentClaster> claster in profile.ListOfCurrentBar) { int Y_histogramm = chartScale.GetYByValue(claster.Key) - model.Claster_Height / 2; int vol = claster.Value.Volume_sum * (int)Math.Abs(tmpVect.X) / profile.ListOfCurrentBar[profile.pocPrice].Volume_sum; volumeSum += claster.Value.Volume_sum; if (claster.Key == profile.pocPrice) { RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol, model.Claster_Height), model.Input_ProfileRange_POC_Color.ToDxBrush(RenderTarget)); } else { RenderTarget.FillRectangle(new SharpDX.RectangleF(leftPosition, Y_histogramm, vol, model.Claster_Height), profile_Claster_Color); } } SharpDX.DirectWrite.TextFormat Claster_textFormat = chartControl.Properties.LabelFont.ToDirectWriteTextFormat(); RenderTarget.DrawText("Σ " + volumeSum.ToString(), Claster_textFormat, new SharpDX.RectangleF(leftPosition, topPosition + Math.Abs(tmpVect.Y) + 3, volumeSum.ToString().Length *8 + 10, 10), Brushes.WhiteSmoke.ToDxBrush(RenderTarget)); int text_Y = chartScale.GetYByValue(profile.pocPrice) - model.Claster_Height / 2; int text_width = profile.pocPrice.ToString().Length *7; RenderTarget.DrawText(profile.pocPrice.ToString(), Claster_textFormat, new SharpDX.RectangleF(leftPosition - text_width, text_Y, text_width, 10), model.Input_ProfileRange_POC_Color.ToDxBrush(RenderTarget)); if (false) { RenderTarget.DrawRectangle(new SharpDX.RectangleF(leftPosition, topPosition - 20, 15, 15), Brushes.Gray.ToDxBrush(RenderTarget), (float)1); } return; } catch (Exception ex) { Print("MR CustomProfile 414: " + ex); } }