private IEnumerable <Point> GetGannEndPoints(ChartControl chartControl, ChartScale chartScale) { ChartPanel panel = chartControl.ChartPanels[PanelIndex]; Point anchorPoint = Anchor.GetPoint(chartControl, panel, chartScale); foreach (GannAngle gannAngle in GannAngles.Where(ga => ga.IsVisible)) { double dx = gannAngle.RatioX * chartControl.Properties.BarDistance; double dVal = gannAngle.RatioY * PointsPerBar; Point stepPoint = GetGannStepPoint(chartScale, anchorPoint.X, Anchor.Price, dx, dVal); Point extendedEndPoint = GetExtendedPoint(anchorPoint, stepPoint); yield return(new Point(Math.Max(extendedEndPoint.X, 1), Math.Max(extendedEndPoint.Y, 1))); } }
public override void OnRender(ChartControl chartControl, ChartScale chartScale) { RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive; ChartPanel panel = chartControl.ChartPanels[PanelIndex]; Point anchorPoint = Anchor.GetPoint(chartControl, panel, chartScale); Point lastEndPoint = new Point(0, 0); SharpDX.Direct2D1.Brush lastBrush = null; foreach (GannAngle gannAngle in GannAngles.Where(ga => ga.IsVisible && ga.Stroke != null).OrderBy(ga => (ga.RatioX / ga.RatioY))) { gannAngle.Stroke.RenderTarget = RenderTarget; double dx = gannAngle.RatioX * chartControl.Properties.BarDistance; double dVal = gannAngle.RatioY * PointsPerBar; //NT7, just multiple directly this is price not pixels //chartScale.GetPixelsForDistance(gannAngle.RatioY * PointsPerBar); Vector gannDataVector = GetGannStepDataVector(dx, dVal); Point extendedEndPoint = CalculateExtendedDataPoint(panel, chartScale, Convert.ToInt32(anchorPoint.X), Anchor.Price, gannDataVector); // align to full pixel to avoid unneeded aliasing double strokePixAdj = ((double)(gannAngle.Stroke.Width % 2)).ApproxCompare(0) == 0 ? 0.5d : 0d; Vector pixelAdjustVec = new Vector(0, strokePixAdj); SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : gannAngle.Stroke.BrushDX; RenderTarget.DrawLine((anchorPoint + pixelAdjustVec).ToVector2(), (extendedEndPoint + pixelAdjustVec).ToVector2(), tmpBrush, gannAngle.Stroke.Width, gannAngle.Stroke.StrokeStyle); if (lastBrush != null) { float oldOpacity = lastBrush.Opacity; lastBrush.Opacity = PriceLevelOpacity / 100f; // create geometry SharpDX.Direct2D1.PathGeometry lineGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory); SharpDX.Direct2D1.GeometrySink sink = lineGeometry.Open(); sink.BeginFigure(lastEndPoint.ToVector2(), SharpDX.Direct2D1.FigureBegin.Filled); // Does the fill color need to fill a corner? Check and add a point if (Math.Abs(lastEndPoint.Y - extendedEndPoint.Y) > 0.1 && Math.Abs(lastEndPoint.X - extendedEndPoint.X) > 0.1) { double boundaryX; double boundaryY; if (lastEndPoint.Y <= ChartPanel.Y || lastEndPoint.Y >= ChartPanel.Y + ChartPanel.H) { if (FanDirection == GannFanDirection.UpLeft || FanDirection == GannFanDirection.UpRight) { boundaryY = extendedEndPoint.Y; boundaryX = lastEndPoint.X; } else { boundaryY = lastEndPoint.Y; boundaryX = extendedEndPoint.X; } } else { if (FanDirection == GannFanDirection.UpLeft || FanDirection == GannFanDirection.UpRight) { boundaryY = lastEndPoint.Y; boundaryX = extendedEndPoint.X; } else { boundaryY = extendedEndPoint.Y; boundaryX = lastEndPoint.X; } } sink.AddLine(new SharpDX.Vector2((float)boundaryX, (float)boundaryY)); } sink.AddLine(extendedEndPoint.ToVector2()); sink.AddLine((anchorPoint + pixelAdjustVec).ToVector2()); sink.AddLine((lastEndPoint).ToVector2()); sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed); sink.Close(); RenderTarget.FillGeometry(lineGeometry, lastBrush); lineGeometry.Dispose(); lastBrush.Opacity = oldOpacity; } lastEndPoint = extendedEndPoint + pixelAdjustVec; lastBrush = tmpBrush; } if (!IsTextDisplayed || IsInHitTest) { return; } foreach (GannAngle gannAngle in GannAngles.Where(ga => ga.IsVisible && ga.Stroke != null).OrderBy(ga => (ga.RatioX / ga.RatioY))) { gannAngle.Stroke.RenderTarget = RenderTarget; double dx = gannAngle.RatioX * chartControl.Properties.BarDistance; double dVal = gannAngle.RatioY * PointsPerBar; //NT7, just multiple directly this is price not pixels //chartScale.GetPixelsForDistance(gannAngle.RatioY * PointsPerBar); Vector gannDataVector = GetGannStepDataVector(dx, dVal); Point extendedEndPoint = CalculateExtendedDataPoint(panel, chartScale, Convert.ToInt32(anchorPoint.X), Anchor.Price, gannDataVector); if (!IsTextDisplayed || IsInHitTest) { continue; } SimpleFont wpfFont = chartControl.Properties.LabelFont ?? new SimpleFont(); SharpDX.DirectWrite.TextFormat textFormat = wpfFont.ToDirectWriteTextFormat(); textFormat.TextAlignment = SharpDX.DirectWrite.TextAlignment.Leading; textFormat.WordWrapping = SharpDX.DirectWrite.WordWrapping.NoWrap; SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, gannAngle.Name, textFormat, 100, textFormat.FontSize); // once text is laid out, update used width to calcuated space required float fontHeight = textLayout.Metrics.Height; Point textEndPoint = new Point(extendedEndPoint.X, extendedEndPoint.Y); if (textEndPoint.X > panel.X + panel.W - textLayout.Metrics.Width) { textEndPoint.X = panel.X + panel.W - textLayout.Metrics.Width; textEndPoint.Y += textLayout.Metrics.Width; } if (gannDataVector.Y > 0) { if (textEndPoint.Y < panel.Y + (fontHeight * 0.5)) { textEndPoint.Y = panel.Y + (fontHeight * 0.5); } } else { if (textEndPoint.Y > panel.Y + panel.H - (fontHeight * 1.5)) { textEndPoint.Y = panel.Y + panel.H - (fontHeight * 1.5); } } float?marginResource = Application.Current.FindResource("FontModalTitleMargin") as float?; float margin = 2f + (marginResource.HasValue ? marginResource.Value : 3f); // Allow for changes in X position based on whether text is aligned to left or right edge of screen float marginX = FanDirection == GannFanDirection.DownLeft || FanDirection == GannFanDirection.UpLeft ? margin : -2 * margin; SharpDX.Vector2 endVec = new SharpDX.Vector2((float)textEndPoint.X, (float)textEndPoint.Y); SharpDX.Matrix3x2 transformMatrix = SharpDX.Matrix3x2.Translation(endVec); RenderTarget.Transform = transformMatrix; RenderTarget.DrawTextLayout(new SharpDX.Vector2(marginX + margin, margin), textLayout, gannAngle.Stroke.BrushDX, SharpDX.Direct2D1.DrawTextOptions.NoSnap); RenderTarget.Transform = SharpDX.Matrix3x2.Identity; textFormat.Dispose(); textLayout.Dispose(); } }