Beispiel #1
0
 public void DrawBezier(DUIPen pen, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
 {
     pen.RenderTarget = this.target;
     if (pen.IsDefaultStyleProperties)
     {
         using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
             using (SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open())
             {
                 geometrySink.BeginFigure(DxConvert.ToVector2(x1, y1), SharpDX.Direct2D1.FigureBegin.Hollow);
                 geometrySink.AddBezier(new SharpDX.Direct2D1.BezierSegment()
                 {
                     Point1 = DxConvert.ToVector2(x2, y2), Point2 = DxConvert.ToVector2(x3, y3), Point3 = DxConvert.ToVector2(x4, y4)
                 });
                 geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
                 geometrySink.Close();
                 this.target.RenderTarget.DrawGeometry(pathGeometry, pen, pen.Width);
             }
     }
     else
     {
         using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
             using (SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open())
             {
                 geometrySink.BeginFigure(DxConvert.ToVector2(x1, y1), SharpDX.Direct2D1.FigureBegin.Hollow);
                 geometrySink.AddBezier(new SharpDX.Direct2D1.BezierSegment()
                 {
                     Point1 = DxConvert.ToVector2(x2, y2), Point2 = DxConvert.ToVector2(x3, y3), Point3 = DxConvert.ToVector2(x4, y4)
                 });
                 geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
                 geometrySink.Close();
                 this.target.RenderTarget.DrawGeometry(pathGeometry, pen, pen.Width, pen);
             }
     }
 }
Beispiel #2
0
        protected override void OnStateChange()
        {
            base.OnStateChange();
            if (State == State.SetDefaults)
            {
                ArrowPathGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                SharpDX.Direct2D1.GeometrySink geometrySink = ArrowPathGeometry.Open();
                LineType = ChartLineType.ArrowLine;
                Name     = "Labeled Arrow Line";

                // create our arrow directx geometry.
                // just make a static size we will scale when drawing
                // all relative to top of line
                // nudge up y slightly to cover up top of stroke (instead of using zero),
                // half the stroke will hide any overlap
                float           arrowWidth = 6f;
                SharpDX.Vector2 top        = new SharpDX.Vector2(0, Stroke.Width * 0.5f);
                geometrySink.BeginFigure(top, SharpDX.Direct2D1.FigureBegin.Filled);
                geometrySink.AddLine(new SharpDX.Vector2(arrowWidth, -arrowWidth));
                geometrySink.AddLine(new SharpDX.Vector2(-arrowWidth, -arrowWidth));
                geometrySink.AddLine(top);                // cap off figure
                geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                geometrySink.Close();
            }
        }
Beispiel #3
0
        private SharpDX.Direct2D1.PathGeometry CreatePathGeometry(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale, double pixelAdjust)
        {
            List <SharpDX.Vector2> vectors = new List <SharpDX.Vector2>();
            Vector pixelAdjustVec          = new Vector(pixelAdjust, pixelAdjust);

            for (int i = 0; i < ChartAnchors.Count; i++)
            {
                Point p = ChartAnchors[i].GetPoint(chartControl, chartPanel, chartScale);
                vectors.Add((p + pixelAdjustVec).ToVector2());

                if (i + 1 < ChartAnchors.Count)
                {
                    Point p2 = ChartAnchors[i + 1].GetPoint(chartControl, chartPanel, chartScale);
                    vectors.Add((p2 + pixelAdjustVec).ToVector2());
                }
            }

            SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
            SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open();

            geometrySink.BeginFigure(vectors[0], SharpDX.Direct2D1.FigureBegin.Filled);
            geometrySink.AddLines(vectors.ToArray());
            geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
            geometrySink.Close();             // calls dispose for you

            return(pathGeometry);
        }
Beispiel #4
0
        public void FillPolygon(DUIBrush brush, PointF[] points)
        {
            bool closed = true;

            if (points == null)
            {
                return;
            }
            if (points.Length < 3)
            {
                return;
            }
            brush.RenderTarget = this.target;
            using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
                using (SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open())
                {
                    geometrySink.SetFillMode(SharpDX.Direct2D1.FillMode.Alternate);
                    geometrySink.BeginFigure(DxConvert.ToVector2(points[0]), SharpDX.Direct2D1.FigureBegin.Filled);
                    for (int i = 1; i < points.Length; i++)
                    {
                        geometrySink.AddLine(DxConvert.ToVector2(points[i]));
                    }
                    geometrySink.EndFigure(closed ? SharpDX.Direct2D1.FigureEnd.Closed : SharpDX.Direct2D1.FigureEnd.Open);
                    geometrySink.Close();
                    this.target.RenderTarget.FillGeometry(pathGeometry, brush);
                }
        }
Beispiel #5
0
        public void DrawPolygon(DUIPen pen, PointF[] points)
        {
            bool closed = true;

            if (points == null)
            {
                return;
            }
            if (points.Length < (closed ? 3 : 2))
            {
                return;
            }
            pen.RenderTarget = this.target;
            if (pen.IsDefaultStyleProperties)
            {
                using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
                    using (SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open())
                    {
                        geometrySink.BeginFigure(DxConvert.ToVector2(points[0]), SharpDX.Direct2D1.FigureBegin.Filled);
                        for (int i = 1; i < points.Length; i++)
                        {
                            geometrySink.AddLine(DxConvert.ToVector2(points[i]));
                        }
                        geometrySink.EndFigure(closed ? SharpDX.Direct2D1.FigureEnd.Closed : SharpDX.Direct2D1.FigureEnd.Open);
                        geometrySink.Close();
                        this.target.RenderTarget.DrawGeometry(pathGeometry, pen, pen.Width);
                    }
            }
            else
            {
                using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
                    using (SharpDX.Direct2D1.GeometrySink geometrySink = pathGeometry.Open())
                    {
                        geometrySink.BeginFigure(DxConvert.ToVector2(points[0]), SharpDX.Direct2D1.FigureBegin.Filled);
                        for (int i = 1; i < points.Length; i++)
                        {
                            geometrySink.AddLine(DxConvert.ToVector2(points[i]));
                        }
                        geometrySink.EndFigure(closed ? SharpDX.Direct2D1.FigureEnd.Closed : SharpDX.Direct2D1.FigureEnd.Open);
                        geometrySink.Close();
                        this.target.RenderTarget.DrawGeometry(pathGeometry, pen, pen.Width, pen);
                    }
            }
        }
Beispiel #6
0
 public void DrawImage(DUIImage image, PointF[] polygon, GraphicsUnit srcUnit, float opacity)
 {
     image.RenderTarget = this.target;
     using (DirectUI.Common.DUIBitmapBrush dbs = new DirectUI.Common.DUIBitmapBrush(image, DUIExtendMode.Clamp, opacity))
         using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
             using (SharpDX.Direct2D1.GeometrySink gs1 = pathGeometry.Open())
             {
                 dbs.RenderTarget = this.target;
                 gs1.SetFillMode(SharpDX.Direct2D1.FillMode.Alternate);
                 gs1.BeginFigure(DxConvert.ToVector2(polygon[0]), SharpDX.Direct2D1.FigureBegin.Filled);
                 for (int i = 1; i < polygon.Length; i++)
                 {
                     gs1.AddLine(DxConvert.ToVector2(polygon[i]));
                 }
                 gs1.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                 gs1.Close();
                 this.target.RenderTarget.FillGeometry(pathGeometry, dbs);
             }
 }
Beispiel #7
0
        private void DrawFigure(SharpDXFigure figure)
        {
            SharpDX.Direct2D1.PathGeometry geometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
            SharpDX.Direct2D1.GeometrySink sink     = geometry.Open();

            sink.BeginFigure(figure.Points[0], new SharpDX.Direct2D1.FigureBegin());

            for (int i = 0; i < figure.Points.Length; i++)
            {
                sink.AddLine(figure.Points[i]);
            }

            sink.AddLine(figure.Points[0]);

            sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
            sink.Close();

            RenderTarget.FillGeometry(geometry, dxmBrushes[figure.Color].DxBrush);
            geometry.Dispose();
            sink.Dispose();
        }
Beispiel #8
0
        public void DrawImage(DUIImage image, PointF[] destTriangle, PointF[] srcTriangle, GraphicsUnit srcUnit, float opacity)
        {
            PointF t1 = destTriangle[0];
            PointF t2 = destTriangle[1];
            PointF t3 = destTriangle[2];

            image.RenderTarget = this.target;
            using (DirectUI.Common.DUIBitmapBrush dbs = new DirectUI.Common.DUIBitmapBrush(image, DUIExtendMode.Clamp, opacity))
                using (SharpDX.Direct2D1.PathGeometry pathGeometry = new SharpDX.Direct2D1.PathGeometry(this.target.RenderTarget.Factory))
                    using (SharpDX.Direct2D1.GeometrySink gs1 = pathGeometry.Open())
                    {
                        dbs.RenderTarget = this.target;
                        gs1.SetFillMode(SharpDX.Direct2D1.FillMode.Alternate);
                        gs1.BeginFigure(DxConvert.ToVector2(t1), SharpDX.Direct2D1.FigureBegin.Filled);
                        gs1.AddLine(DxConvert.ToVector2(t2));
                        gs1.AddLine(DxConvert.ToVector2(t3));
                        gs1.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                        gs1.Close();
                        dbs.Transform = MatrixTools.ThreePointsAffine(srcTriangle, destTriangle);
                        this.target.RenderTarget.FillGeometry(pathGeometry, dbs);
                    }
        }
        public void DrawPathGeometrySink(List <System.Drawing.Point> Points, System.Drawing.Color LineColor, float LineWidth, System.Drawing.Drawing2D.DashStyle dashStyle, bool CloseGeometry = false)
        {
            SharpDX.Direct2D1.PathGeometry pg   = new SharpDX.Direct2D1.PathGeometry(D2Drender.Factory);
            SharpDX.Direct2D1.GeometrySink sink = pg.Open();
            for (int i = 0; i < Points.Count; i++)
            {
                if (i == 0)
                {
                    sink.BeginFigure(utils.Point2Raw(Points[0]), SharpDX.Direct2D1.FigureBegin.Hollow);
                }
                else
                {
                    sink.AddLine(utils.Point2Raw(Points[i]));
                }
            }
            if (Points.Count > 0)
            {
                sink.EndFigure(CloseGeometry?SharpDX.Direct2D1.FigureEnd.Closed:SharpDX.Direct2D1.FigureEnd.Open);
            }
            sink.Close();
            SharpDX.Direct2D1.StrokeStyleProperties ssProps = new SharpDX.Direct2D1.StrokeStyleProperties();
            ssProps.StartCap   = SharpDX.Direct2D1.CapStyle.Flat;
            ssProps.EndCap     = SharpDX.Direct2D1.CapStyle.Flat;
            ssProps.DashOffset = 0.1f;
            switch (dashStyle)
            {
            case System.Drawing.Drawing2D.DashStyle.Dash: ssProps.DashStyle = SharpDX.Direct2D1.DashStyle.Dash; break;

            case System.Drawing.Drawing2D.DashStyle.DashDot: ssProps.DashStyle = SharpDX.Direct2D1.DashStyle.DashDot; break;

            case System.Drawing.Drawing2D.DashStyle.DashDotDot: ssProps.DashStyle = SharpDX.Direct2D1.DashStyle.DashDotDot; break;

            case System.Drawing.Drawing2D.DashStyle.Dot: ssProps.DashStyle = SharpDX.Direct2D1.DashStyle.Dot; break;

            case System.Drawing.Drawing2D.DashStyle.Solid: ssProps.DashStyle = SharpDX.Direct2D1.DashStyle.Solid; break;
            }
            SharpDX.Direct2D1.StrokeStyle LineStyle = new SharpDX.Direct2D1.StrokeStyle(D2Drender.Factory, ssProps);
            D2Drender.DrawGeometry(pg, utils.SoildBrush2Raw(LineColor), LineWidth, LineStyle);
        }
Beispiel #10
0
        private void UpdateArcGeometry(ChartControl chartControl, ChartPanel chartPanel, ChartScale chartScale)
        {
            Point startPoint = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point endPoint   = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);

            if (arcGeometry != null && startPoint == cachedStartPoint && endPoint == cachedEndPoint)
            {
                return;
            }

            cachedEndPoint   = endPoint;
            cachedStartPoint = startPoint;

            if (arcGeometry != null && !arcGeometry.IsDisposed)
            {
                arcGeometry.Dispose();
            }

            Vector lineVec = endPoint - startPoint;
            float  width   = Math.Abs((float)lineVec.X);
            float  height  = Math.Abs((float)lineVec.Y);

            SharpDX.Direct2D1.ArcSegment arcSegment = new SharpDX.Direct2D1.ArcSegment
            {
                ArcSize        = SharpDX.Direct2D1.ArcSize.Small,
                Point          = new SharpDX.Vector2((float)endPoint.X, (float)endPoint.Y),
                SweepDirection = SharpDX.Direct2D1.SweepDirection.CounterClockwise,
                Size           = new SharpDX.Size2F(width, height)
            };

            // Create the arc between the line two end points
            arcGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
            SharpDX.Direct2D1.GeometrySink geometrySink = arcGeometry.Open();
            geometrySink.BeginFigure(new SharpDX.Vector2((float)startPoint.X, (float)startPoint.Y), SharpDX.Direct2D1.FigureBegin.Filled);
            geometrySink.AddArc(arcSegment);
            geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
            geometrySink.Close();
        }
        public void DrawPathGeometrySink(List <System.Drawing.Point> Points, System.Drawing.Color LineColor, float LineWidth, bool CloseGeometry = false)
        {
            SharpDX.Direct2D1.PathGeometry pg   = new SharpDX.Direct2D1.PathGeometry(D2Drender.Factory);
            SharpDX.Direct2D1.GeometrySink sink = pg.Open();
            for (int i = 0; i < Points.Count; i++)
            {
                if (i == 0)
                {
                    sink.BeginFigure(utils.Point2Raw(Points[0]), SharpDX.Direct2D1.FigureBegin.Hollow);
                }
                else
                {
                    sink.AddLine(utils.Point2Raw(Points[i]));
                }
            }
            if (Points.Count > 0)
            {
                sink.EndFigure(CloseGeometry ? SharpDX.Direct2D1.FigureEnd.Closed : SharpDX.Direct2D1.FigureEnd.Open);
            }
            sink.Close();

            D2Drender.DrawGeometry(pg, utils.SoildBrush2Raw(LineColor), LineWidth);
        }
        public void FillPathGeometrySink(List <System.Drawing.Point> Points, System.Drawing.Color FillColor)
        {
            SharpDX.Direct2D1.PathGeometry pg   = new SharpDX.Direct2D1.PathGeometry(D2Drender.Factory);
            SharpDX.Direct2D1.GeometrySink sink = pg.Open();
            for (int i = 0; i < Points.Count; i++)
            {
                if (i == 0)
                {
                    sink.BeginFigure(utils.Point2Raw(Points[0]), SharpDX.Direct2D1.FigureBegin.Filled);
                }
                else
                {
                    sink.AddLine(utils.Point2Raw(Points[i]));
                }
            }
            if (Points.Count > 0)
            {
                sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
            }
            sink.Close();

            D2Drender.FillGeometry(pg, utils.SoildBrush2Raw(FillColor));
        }
Beispiel #13
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (Anchors.All(a => a.IsEditing))
            {
                return;
            }

            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

            ChartPanel chartPanel           = chartControl.ChartPanels[PanelIndex];
            Point      anchorStartPoint     = StartAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorEndPoint       = EndAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      anchorExtensionPoint = ExtensionAnchor.GetPoint(chartControl, chartPanel, chartScale);
            Point      midPointExtension    = new Point((anchorExtensionPoint.X + anchorEndPoint.X) / 2, (anchorExtensionPoint.Y + anchorEndPoint.Y) / 2);

            if (CalculationMethod == AndrewsPitchforkCalculationMethod.Schiff)
            {
                anchorStartPoint = new Point(anchorStartPoint.X, (anchorStartPoint.Y + anchorEndPoint.Y) / 2);
            }
            else if (CalculationMethod == AndrewsPitchforkCalculationMethod.ModifiedSchiff)
            {
                anchorStartPoint = new Point((anchorEndPoint.X + anchorStartPoint.X) / 2, (anchorEndPoint.Y + anchorStartPoint.Y) / 2);
            }

            AnchorLineStroke.RenderTarget      = RenderTarget;
            RetracementLineStroke.RenderTarget = RenderTarget;

            // Align to full pixel to avoid unneeded aliasing
            double strokePixAdj   = AnchorLineStroke.Width % 2 == 0 ? 0.5d : 0d;
            Vector pixelAdjustVec = new Vector(strokePixAdj, strokePixAdj);

            SharpDX.Vector2         startVec = (anchorStartPoint + pixelAdjustVec).ToVector2();
            SharpDX.Vector2         endVec   = (anchorEndPoint + pixelAdjustVec).ToVector2();
            SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : AnchorLineStroke.BrushDX;

            SharpDX.Vector2 startOriginVec = (StartAnchor.GetPoint(chartControl, chartPanel, chartScale) + pixelAdjustVec).ToVector2();

            RenderTarget.DrawLine(startOriginVec, endVec, tmpBrush, AnchorLineStroke.Width, AnchorLineStroke.StrokeStyle);

            // Is second anchor set yet? Check both so we correctly re-draw during extension anchor editing
            if (ExtensionAnchor.IsEditing && EndAnchor.IsEditing)
            {
                return;
            }

            SharpDX.Vector2 extVector = anchorExtensionPoint.ToVector2();
            tmpBrush = IsInHitTest ? chartControl.SelectionBrush : RetracementLineStroke.BrushDX;
            RenderTarget.DrawLine(endVec, extVector, tmpBrush, RetracementLineStroke.Width, RetracementLineStroke.StrokeStyle);

            // If we're doing a hit test pass, don't draw price levels at all, we dont want those to count for
            // hit testing
            if (IsInHitTest || PriceLevels == null || !PriceLevels.Any())
            {
                return;
            }

            SetAllPriceLevelsRenderTarget();

            // Calculate total y range for % calculation on each level
            double totalPriceRange = EndAnchor.Price - ExtensionAnchor.Price;
            double startPrice      = ExtensionAnchor.Price;
            float  minLevelY       = float.MaxValue;
            float  maxLevelY       = float.MinValue;

            // Store values to use in correct render order
            Point  lastEndPoint   = new Point(0, 0);
            Point  lastStartPoint = new Point(0, 0);
            Stroke lastStroke     = null;
            List <Tuple <PriceLevel, Point> > textPoints = new List <Tuple <PriceLevel, Point> >();

            foreach (PriceLevel priceLevel in PriceLevels.Where(pl => pl.IsVisible && pl.Stroke != null).OrderBy(pl => pl.Value))
            {
                double levelPrice = (startPrice + ((priceLevel.Value / 100) * totalPriceRange));
                float  pixelY     = chartScale.GetYByValue(levelPrice);
                float  pixelX     = anchorExtensionPoint.X > anchorEndPoint.X ?
                                    priceLevel.Value >= 0 ? (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100)))) : (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100))):
                                    priceLevel.Value >= 0 ? (float)(anchorExtensionPoint.X + ((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.Value / 100))) : (float)(anchorExtensionPoint.X - (Math.Abs((anchorEndPoint.X - anchorExtensionPoint.X) * (priceLevel.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);
                if (priceLevel.Value == 50)
                {
                    RenderTarget.DrawLine(startVec, maxLevelPoint.ToVector2(), priceLevel.Stroke.BrushDX, priceLevel.Stroke.Width, priceLevel.Stroke.StrokeStyle);
                }
                else
                {
                    RenderTarget.DrawLine(startPoint.ToVector2(), maxLevelPoint.ToVector2(), priceLevel.Stroke.BrushDX, priceLevel.Stroke.Width, priceLevel.Stroke.StrokeStyle);
                }

                if (lastStroke == null)
                {
                    lastStroke = new Stroke();
                }
                else
                {
                    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 (lastEndPoint.Y != maxLevelPoint.Y && lastEndPoint.X != maxLevelPoint.X)
                    {
                        double boundaryX;
                        double boundaryY;

                        if (lastEndPoint.Y <= ChartPanel.Y || lastEndPoint.Y >= ChartPanel.Y + ChartPanel.H)
                        {
                            boundaryY = lastEndPoint.Y;
                            boundaryX = maxLevelPoint.X;
                        }
                        else
                        {
                            boundaryY = maxLevelPoint.Y;
                            boundaryX = lastEndPoint.X;
                        }
                        sink.AddLine(new SharpDX.Vector2((float)boundaryX, (float)boundaryY));
                    }
                    sink.AddLine(maxLevelPoint.ToVector2());
                    sink.AddLine(startPoint.ToVector2());
                    sink.AddLine(lastStartPoint.ToVector2());
                    sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                    sink.Close();
                    RenderTarget.FillGeometry(lineGeometry, lastStroke.BrushDX);
                    lineGeometry.Dispose();
                }

                if (IsTextDisplayed)
                {
                    textPoints.Add(new Tuple <PriceLevel, Point>(priceLevel, maxLevelPoint));
                }

                priceLevel.Stroke.CopyTo(lastStroke);
                lastStroke.Opacity = PriceLevelOpacity;
                lastStartPoint     = startPoint;
                lastEndPoint       = maxLevelPoint;
                minLevelY          = Math.Min(pixelY, minLevelY);
                maxLevelY          = Math.Max(pixelY, maxLevelY);
            }

            // Render text last so it's on top of the price level colors
            if (IsTextDisplayed)
            {
                foreach (Tuple <PriceLevel, Point> textPoint in textPoints)
                {
                    DrawPriceLevelText(0, 0, textPoint.Item2, textPoint.Item1, chartPanel);
                }
            }
        }
Beispiel #14
0
        protected override void OnRender(Gui.Chart.ChartControl chartControl, Gui.Chart.ChartScale chartScale)
        {
            if (Bars == null || chartControl == null || startIndex == int.MinValue)
            {
                return;
            }

            IsValidDataPointAt(Bars.Count - 1 - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 1 : 0));             // Make sure indicator is calculated until last (existing) bar
            int preDiff = 1;

            for (int i = ChartBars.FromIndex - 1; i >= 0; i--)
            {
                if (i - Displacement < startIndex || i - Displacement > Bars.Count - 1 - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 1 : 0))
                {
                    break;
                }

                bool isHigh = zigZagHighZigZags.IsValidDataPointAt(i - Displacement);
                bool isLow  = zigZagLowZigZags.IsValidDataPointAt(i - Displacement);

                if (isHigh || isLow)
                {
                    break;
                }

                preDiff++;
            }

            preDiff -= (Displacement < 0 ? Displacement : 0 - Displacement);

            int postDiff = 0;

            for (int i = ChartBars.ToIndex; i <= zigZagHighZigZags.Count; i++)
            {
                if (i - Displacement < startIndex || i - Displacement > Bars.Count - 1 - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 1 : 0))
                {
                    break;
                }

                bool isHigh = zigZagHighZigZags.IsValidDataPointAt(i - Displacement);
                bool isLow  = zigZagLowZigZags.IsValidDataPointAt(i - Displacement);

                if (isHigh || isLow)
                {
                    break;
                }

                postDiff++;
            }

            postDiff += (Displacement < 0 ? 0 - Displacement : Displacement);

            int    lastIdx   = -1;
            double lastValue = -1;

            SharpDX.Direct2D1.PathGeometry g    = null;
            SharpDX.Direct2D1.GeometrySink sink = null;

            for (int idx = ChartBars.FromIndex - preDiff; idx <= ChartBars.ToIndex + postDiff; idx++)
            {
                if (idx < startIndex || idx > Bars.Count - (Calculate == NinjaTrader.NinjaScript.Calculate.OnBarClose ? 2 : 1) || idx < Math.Max(BarsRequiredToPlot - Displacement, Displacement))
                {
                    continue;
                }

                bool isHigh = zigZagHighZigZags.IsValidDataPointAt(idx);
                bool isLow  = zigZagLowZigZags.IsValidDataPointAt(idx);

                if (!isHigh && !isLow)
                {
                    continue;
                }

                double value = isHigh ? zigZagHighZigZags.GetValueAt(idx) : zigZagLowZigZags.GetValueAt(idx);

                if (lastIdx >= startIndex)
                {
                    float x1 = (chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && idx + Displacement >= ChartBars.Count
                                                ? chartControl.GetXByTime(ChartBars.GetTimeByBarIdx(chartControl, idx + Displacement))
                                                : chartControl.GetXByBarIndex(ChartBars, idx + Displacement));
                    float y1 = chartScale.GetYByValue(value);

                    if (sink == null)
                    {
                        float x0 = (chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && lastIdx + Displacement >= ChartBars.Count
                                                ? chartControl.GetXByTime(ChartBars.GetTimeByBarIdx(chartControl, lastIdx + Displacement))
                                                : chartControl.GetXByBarIndex(ChartBars, lastIdx + Displacement));
                        float y0 = chartScale.GetYByValue(lastValue);
                        g    = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                        sink = g.Open();
                        sink.BeginFigure(new SharpDX.Vector2(x0, y0), SharpDX.Direct2D1.FigureBegin.Hollow);
                    }
                    sink.AddLine(new SharpDX.Vector2(x1, y1));
                }

                // Save as previous point
                lastIdx   = idx;
                lastValue = value;
            }

            if (sink != null)
            {
                sink.EndFigure(SharpDX.Direct2D1.FigureEnd.Open);
                sink.Close();
            }

            if (g != null)
            {
                var oldAntiAliasMode = RenderTarget.AntialiasMode;
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
                RenderTarget.DrawGeometry(g, Plots[0].BrushDX, Plots[0].Width, Plots[0].StrokeStyle);
                RenderTarget.AntialiasMode = oldAntiAliasMode;
                g.Dispose();
                RemoveDrawObject("NinjaScriptInfo");
            }
            else
            {
                Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.ZigZagDeviationValueError, TextPosition.BottomRight);
            }
        }
Beispiel #15
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (Series1 == null)
            {
                return;
            }

            NinjaScriptBase nsb       = AttachedTo.ChartObject as NinjaScriptBase;
            ChartBars       chartBars = (AttachedTo.ChartObject as Gui.NinjaScript.IChartBars).ChartBars;

            if (nsb == null || chartBars == null || Math.Abs(Series1.Count - chartBars.Count) > 1)
            {
                return;
            }

            int startBarIdx;
            int endBarIdx;

            if (chartControl.BarSpacingType == BarSpacingType.TimeBased)
            {
                startBarIdx = chartBars.GetBarIdxByTime(chartControl, StartAnchor.Time);
                endBarIdx   = chartBars.GetBarIdxByTime(chartControl, EndAnchor.Time);
            }
            else
            {
                startBarIdx = StartAnchor.DrawnOnBar - StartAnchor.BarsAgo;
                endBarIdx   = EndAnchor.DrawnOnBar - EndAnchor.BarsAgo;

                if (startBarIdx == endBarIdx)
                {
                    startBarIdx = chartBars.GetBarIdxByTime(chartControl, StartAnchor.Time);
                    endBarIdx   = chartBars.GetBarIdxByTime(chartControl, EndAnchor.Time);
                }
            }

            int startIdx = Math.Min(startBarIdx, endBarIdx);
            int endIdx   = Math.Max(startBarIdx, endBarIdx);

            // Now cap start/end by visibly painted bars!
            // If you dont do this it will absolutely crush performance on larger regions
            int firstVisibleIdx = Math.Max(nsb.BarsRequiredToPlot + Displacement, chartBars.GetBarIdxByTime(chartControl, chartControl.GetTimeByX(0)) - 1);
            int lastVisibleIdx  = Math.Max(chartBars.ToIndex, chartBars.GetBarIdxByTime(chartControl, chartControl.LastTimePainted)) + 1;

            // Update indicies for displacement
            startIdx = Math.Max(0, Math.Max(firstVisibleIdx, startIdx + Displacement));
            endIdx   = Math.Max(0, Math.Min(endIdx + Displacement, lastVisibleIdx));

            // we're completely not visible
            if (startIdx > lastVisibleIdx || endIdx < firstVisibleIdx)
            {
                return;
            }

            /* NOTE: Calling GetValueAt() on an ISeries<double> interface with a concrete
             * type of NinjaScriptBase will get the *bar* value which is not what we want,
             * in this case, default to first values (indicator) series */
            ISeries <double> series1Adjusted = Series1;
            ISeries <double> series2Adjusted = Series2;

            NinjaScriptBase series1NsBase = Series1 as NinjaScriptBase;

            if (series1NsBase != null)
            {
                series1Adjusted = series1NsBase.Value;
            }

            if (series1Adjusted == null)
            {
                return;
            }

            NinjaScriptBase series2NsBase = Series2 as NinjaScriptBase;

            if (series2NsBase != null)
            {
                series2Adjusted = series2NsBase.Value;
            }

            // take care to wind the points correctly so our geometry builds as a solid, not flipped inside out
            SharpDX.Vector2[] points;
            SharpDX.Vector2[] points2 = new SharpDX.Vector2[0];
            int pointIdx  = 0;
            int pointIdx2 = 0;

            if (series2Adjusted == null)
            {
                points = new SharpDX.Vector2[endIdx - startIdx + 1 + 2];
                for (int i = startIdx; i <= endIdx; ++i)
                {
                    if (i < Math.Max(0, Displacement) || i > Math.Max(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1) + Displacement, endIdx))
                    {
                        continue;
                    }

                    int    displacedIndex = Math.Min(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1), Math.Max(0, i - Displacement));
                    double seriesValue    = series1Adjusted.GetValueAt(displacedIndex);
                    float  y = chartScale.GetYByValue(seriesValue);
                    float  x = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i >= chartBars.Count                                                    //i is already displaced
                                                ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, i))
                                                : chartControl.GetXByBarIndex(chartBars, i);

                    double pixXAdjust     = x % 1 != 0 ? 0 : 0.5d;
                    double pixYAdjust     = y % 1 != 0 ? 0 : 0.5d;
                    Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust);

                    Point adjusted = new Point(x, y) + pixelAdjustVec;
                    points[pointIdx] = adjusted.ToVector2();
                    ++pointIdx;
                }

                // cap it end->start
                points[pointIdx].X = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && endIdx >= chartBars.Count
                                        ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, endIdx))
                                        : chartControl.GetXByBarIndex(chartBars, endIdx);
                points[pointIdx++].Y = chartScale.GetYByValue(Math.Max(chartScale.MinValue, Math.Min(chartScale.MaxValue, Price)));

                points[pointIdx].X = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && startIdx >= chartBars.Count
                                        ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, startIdx))
                                        : chartControl.GetXByBarIndex(chartBars, startIdx);
                points[pointIdx++].Y = chartScale.GetYByValue(Math.Max(chartScale.MinValue, Math.Min(chartScale.MaxValue, Price)));
            }
            else
            {
                points  = new SharpDX.Vector2[endIdx - startIdx + 1];
                points2 = new SharpDX.Vector2[endIdx - startIdx + 1];
                // fill clockwise from series1, the	counter clockwise for series 2 for correct point poly winding
                for (int i = startIdx; i <= endIdx; ++i)
                {
                    if (i < Math.Max(0, Displacement) || i > Math.Max(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1) + Displacement, endIdx))
                    {
                        continue;
                    }

                    int   displacedIndex = Math.Min(chartBars.Count - (nsb.Calculate == Calculate.OnBarClose ? 2 : 1), Math.Max(0, i - Displacement));
                    float x = chartControl.BarSpacingType == BarSpacingType.TimeBased || chartControl.BarSpacingType == BarSpacingType.EquidistantMulti && i >= chartBars.Count                                                     //i is already displaced
                                                ? chartControl.GetXByTime(chartBars.GetTimeByBarIdx(chartControl, i))
                                                : chartControl.GetXByBarIndex(chartBars, i);
                    if (!series1Adjusted.IsValidDataPointAt(displacedIndex))
                    {
                        continue;
                    }
                    double seriesValue = series1Adjusted.GetValueAt(displacedIndex);
                    float  y           = chartScale.GetYByValue(seriesValue);

                    double pixXAdjust = x % 1 != 0 ? 0 : 0.5d;
                    double pixYAdjust = y % 1 != 0 ? 0 : 0.5d;

                    Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust);

                    Point adjusted = new Point(x, y) + pixelAdjustVec;
                    points[pointIdx] = adjusted.ToVector2();
                    ++pointIdx;
                    if (!series2Adjusted.IsValidDataPointAt(displacedIndex))
                    {
                        continue;
                    }
                    seriesValue        = series2Adjusted.GetValueAt(displacedIndex);
                    y                  = chartScale.GetYByValue(seriesValue);
                    pixYAdjust         = y % 1 != 0 ? 0 : 0.5d;
                    pixelAdjustVec     = new Vector(pixXAdjust, pixYAdjust);
                    adjusted           = new Point(x, y) + pixelAdjustVec;
                    points2[pointIdx2] = adjusted.ToVector2();
                    ++pointIdx2;
                }
            }

            if (pointIdx + pointIdx2 > 2)
            {
                RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;

                if (OutlineStroke != null)
                {
                    OutlineStroke.RenderTarget = RenderTarget;
                }

                if (AreaBrush != null)
                {
                    if (areaBrushDevice.Brush == null)
                    {
                        Brush brushCopy = areaBrush.Clone();
                        brushCopy.Opacity     = areaOpacity / 100d;
                        areaBrushDevice.Brush = brushCopy;
                    }
                    areaBrushDevice.RenderTarget = RenderTarget;
                }

                SharpDX.Direct2D1.PathGeometry polyGeo = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                SharpDX.Direct2D1.GeometrySink geoSink = polyGeo.Open();
                double pixXAdjust     = points[0].X % 1 != 0 ? 0 : 0.5d;
                double pixYAdjust     = points[0].Y % 1 != 0 ? 0 : 0.5d;
                Vector pixelAdjustVec = new Vector(pixXAdjust, pixYAdjust);
                Point  startPt        = new Point(points[0].X, points[0].Y) + pixelAdjustVec;

                geoSink.BeginFigure(startPt.ToVector2(), SharpDX.Direct2D1.FigureBegin.Filled);
                geoSink.SetFillMode(SharpDX.Direct2D1.FillMode.Winding);

                // NOTE: We skip our first point since that is where the path will start
                for (int i = 1; i < pointIdx; i++)
                {
                    geoSink.AddLine(points[i]);
                }
                for (int i = pointIdx2 - 1; i >= 0; i--)
                {
                    geoSink.AddLine(points2[i]);
                }
                geoSink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                geoSink.Close();

                SharpDX.Direct2D1.Brush tmpBrush = IsInHitTest ? chartControl.SelectionBrush : areaBrushDevice == null ? null : areaBrushDevice.BrushDX;
                if (tmpBrush != null)
                {
                    RenderTarget.FillGeometry(polyGeo, tmpBrush);
                }

                tmpBrush = IsInHitTest ? chartControl.SelectionBrush : OutlineStroke == null ? null : OutlineStroke.BrushDX;
                if (tmpBrush != null)
                {
                    RenderTarget.DrawGeometry(polyGeo, OutlineStroke.BrushDX, OutlineStroke.Width);
                }

                polyGeo.Dispose();
            }
        }
Beispiel #16
0
        public override void OnRender(ChartControl chartControl, ChartScale chartScale)
        {
            if (firstTime && DrawingState == DrawingState.Normal)
            {
                firstTime = false;
                Cbi.License.Log("Path");
            }

            RenderTarget.AntialiasMode = SharpDX.Direct2D1.AntialiasMode.PerPrimitive;
            Stroke outlineStroke = OutlineStroke;

            outlineStroke.RenderTarget = RenderTarget;
            ChartPanel chartPanel      = chartControl.ChartPanels[PanelIndex];
            double     strokePixAdjust = outlineStroke.Width % 2 == 0 ? 0.5d : 0d;
            Vector     pixelAdjustVec  = new Vector(strokePixAdjust, strokePixAdjust);

            SharpDX.Direct2D1.PathGeometry polyGeo  = CreatePathGeometry(chartControl, chartPanel, chartScale, strokePixAdjust);
            SharpDX.Direct2D1.Brush        tmpBrush = IsInHitTest ? chartControl.SelectionBrush : outlineStroke.BrushDX;

            RenderTarget.DrawGeometry(polyGeo, tmpBrush, outlineStroke.Width, outlineStroke.StrokeStyle);
            polyGeo.Dispose();

            if (PathBegin == PathToolCapMode.Arrow || PathEnd == PathToolCapMode.Arrow)
            {
                Point[] points = GetPathAnchorPoints(chartControl, chartScale);

                if (points.Length > 1)
                {
                    if (arrowPathGeometry == null)
                    {
                        arrowPathGeometry = new SharpDX.Direct2D1.PathGeometry(Core.Globals.D2DFactory);
                        SharpDX.Direct2D1.GeometrySink geometrySink = arrowPathGeometry.Open();
                        float           arrowWidth = 6f;
                        SharpDX.Vector2 top        = new SharpDX.Vector2(0, outlineStroke.Width * 0.5f);

                        geometrySink.BeginFigure(top, SharpDX.Direct2D1.FigureBegin.Filled);
                        geometrySink.AddLine(new SharpDX.Vector2(arrowWidth, -arrowWidth));
                        geometrySink.AddLine(new SharpDX.Vector2(-arrowWidth, -arrowWidth));
                        geometrySink.AddLine(top);                        // cap off figure
                        geometrySink.EndFigure(SharpDX.Direct2D1.FigureEnd.Closed);
                        geometrySink.Close();
                    }

                    if (PathBegin == PathToolCapMode.Arrow)
                    {
                        Vector lineVector = points[0] - points[1];

                        lineVector.Normalize();

                        Point             pointAdjusted    = points[0] + pixelAdjustVec;
                        SharpDX.Vector2   pointVec         = pointAdjusted.ToVector2();
                        float             vectorAngle      = -(float)Math.Atan2(lineVector.X, lineVector.Y);
                        Vector            adjustVector     = lineVector * 5;
                        SharpDX.Vector2   arrowPointVec    = new SharpDX.Vector2((float)(pointVec.X + adjustVector.X), (float)(pointVec.Y + adjustVector.Y));
                        SharpDX.Matrix3x2 transformMatrix2 = SharpDX.Matrix3x2.Rotation(vectorAngle, SharpDX.Vector2.Zero) * SharpDX.Matrix3x2.Scaling((float)Math.Max(1.0f, outlineStroke.Width * .45) + 0.25f) * SharpDX.Matrix3x2.Translation(arrowPointVec);
                        RenderTarget.Transform = transformMatrix2;

                        RenderTarget.FillGeometry(arrowPathGeometry, tmpBrush);
                        RenderTarget.Transform = SharpDX.Matrix3x2.Identity;
                    }

                    if (PathEnd == PathToolCapMode.Arrow)
                    {
                        Vector lineVector = points[points.Length - 1] - points[points.Length - 2];

                        lineVector.Normalize();

                        Point             pointAdjusted    = points[points.Length - 1] + pixelAdjustVec;
                        SharpDX.Vector2   pointVec         = pointAdjusted.ToVector2();
                        float             vectorAngle      = -(float)Math.Atan2(lineVector.X, lineVector.Y);
                        Vector            adjustVector     = lineVector * 5;
                        SharpDX.Vector2   arrowPointVec    = new SharpDX.Vector2((float)(pointVec.X + adjustVector.X), (float)(pointVec.Y + adjustVector.Y));
                        SharpDX.Matrix3x2 transformMatrix2 = SharpDX.Matrix3x2.Rotation(vectorAngle, SharpDX.Vector2.Zero) * SharpDX.Matrix3x2.Scaling((float)Math.Max(1.0f, outlineStroke.Width * .45) + 0.25f) * SharpDX.Matrix3x2.Translation(arrowPointVec);
                        RenderTarget.Transform = transformMatrix2;

                        RenderTarget.FillGeometry(arrowPathGeometry, tmpBrush);

                        RenderTarget.Transform = SharpDX.Matrix3x2.Identity;
                    }
                }
            }

            if (ShowCount)
            {
                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;

                for (int i = 1; i < ChartAnchors.Count; i++)
                {
                    Point p  = ChartAnchors[i - 1].GetPoint(chartControl, chartPanel, chartScale);
                    Point p1 = ChartAnchors[i].GetPoint(chartControl, chartPanel, chartScale);

                    if (i + 1 < ChartAnchors.Count)
                    {
                        Point  p2 = ChartAnchors[i + 1].GetPoint(chartControl, chartPanel, chartScale);
                        Vector v1 = p - p1;

                        v1.Normalize();

                        Vector v2 = p2 - p1;

                        v2.Normalize();

                        Vector vector = v1 + v2;

                        vector.Normalize();

                        SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, i.ToString(), textFormat, 250, textFormat.FontSize);
                        Point textPoint = p1 - vector * textFormat.FontSize;
                        textPoint.X -= textLayout.Metrics.Width / 2f;
                        textPoint.Y -= textLayout.Metrics.Height / 2f;

                        RenderTarget.DrawTextLayout((textPoint + pixelAdjustVec).ToVector2(), textLayout, outlineStroke.BrushDX, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
                        textLayout.Dispose();
                    }
                    else
                    {
                        SharpDX.DirectWrite.TextLayout textLayout = new SharpDX.DirectWrite.TextLayout(Core.Globals.DirectWriteFactory, i.ToString(), textFormat, 250, textFormat.FontSize);
                        Vector vector = (p - p1);

                        vector.Normalize();

                        Point textPoint = p1 - vector * textFormat.FontSize;
                        textPoint.X -= textLayout.Metrics.Width / 2f;
                        textPoint.Y -= textLayout.Metrics.Height / 2f;

                        RenderTarget.DrawTextLayout((textPoint + pixelAdjustVec).ToVector2(), textLayout, outlineStroke.BrushDX, SharpDX.Direct2D1.DrawTextOptions.NoSnap);
                        textLayout.Dispose();
                    }
                }

                textFormat.Dispose();
            }
        }
Beispiel #17
0
        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();
            }
        }