From 9535715556b5f91101f5219c3557474390075b04 Mon Sep 17 00:00:00 2001 From: Sean Date: Sun, 13 Jul 2025 20:36:04 -0400 Subject: [PATCH] Commit Latest --- .../Renderers/BollingerBandRenderer.cs | 65 ++++++++++++++++--- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/PortfolioManager/Renderers/BollingerBandRenderer.cs b/PortfolioManager/Renderers/BollingerBandRenderer.cs index eb4983f..de177ae 100644 --- a/PortfolioManager/Renderers/BollingerBandRenderer.cs +++ b/PortfolioManager/Renderers/BollingerBandRenderer.cs @@ -17,6 +17,8 @@ using ScottPlot.Avalonia; using ScottPlot.Plottables; using SkiaSharp; using MarketData.Numerical; +using MarketData; +using Avalonia.Controls.Platform; namespace PortfolioManager.Renderers { @@ -27,14 +29,15 @@ namespace PortfolioManager.Renderers public TextPlot() { } - public TextPlot(SKRect boundingRect) + public TextPlot(String markerText,SKRect boundingRect,Coordinates coordinates) { BoundingRect = boundingRect; + Coordinates = coordinates; + MarkerText = markerText; } - public Coordinates Coordinates { get; set; } - public SKRect BoundingRect { get; set; } + public String MarkerText { get; set; } } public class TextPlots : List @@ -43,18 +46,39 @@ namespace PortfolioManager.Renderers { } - public bool pointInRects(Coordinates coordinates) + /// + /// The coordinate system is based on (0,0) in the upper left + /// + /// + /// + public bool PointInRects(String markerText,Coordinates coordinates,ref Coordinates adjustedCoordinates,double factor) { foreach(TextPlot textPlot in this) { - if(coordinates.X > textPlot.BoundingRect.Left && coordinates.X < textPlot.BoundingRect.Right && - coordinates.Y > textPlot.BoundingRect.Bottom && coordinates.Y < textPlot.BoundingRect.Top) + if(Math.Round(coordinates.X,2) >= Math.Round(textPlot.BoundingRect.Left,2) && Math.Round(coordinates.X,2) <= Math.Round(textPlot.BoundingRect.Right,2) && + Math.Round(coordinates.Y,2) >= Math.Round(textPlot.BoundingRect.Top,2) && Math.Round(coordinates.Y,2) <= Math.Round(textPlot.BoundingRect.Bottom,2)) { + MDTrace.WriteLine(LogLevel.DEBUG,$"The text {markerText} at Point:{coordinates.X}:{coordinates.Y} is within Rect:L({textPlot.BoundingRect.Left}),T({textPlot.BoundingRect.Top}),R({textPlot.BoundingRect.Right}),B({textPlot.BoundingRect.Bottom}) with text {textPlot.MarkerText} which is plotted at Coordinates:X:{textPlot.Coordinates.X} Y:{textPlot.Coordinates.Y}"); + SKRect lowestRect = FindLowestAdjacentRect(textPlot.BoundingRect); + adjustedCoordinates.Y = textPlot.Coordinates.Y - factor; + adjustedCoordinates.X = coordinates.X; return true; } } return false; } + + /// + /// Find the Rectangle with the highest Bottom that lies within the X-plane + /// + /// + private SKRect FindLowestAdjacentRect(SKRect rect) + { + List adjacentRects = this.Where(x=> rect.Left>=x.BoundingRect.Left && rect.Right<=x.BoundingRect.Right).Select(x=>x.BoundingRect).ToList(); + if(null == adjacentRects || 0==adjacentRects.Count)return new SKRect(){Left=0,Top=0,Right=0,Bottom=0}; + adjacentRects = adjacentRects.OrderByDescending(x=>x.Bottom).ToList(); + return adjacentRects[0]; + } } // ********************************************************************************************************************************************* @@ -250,8 +274,13 @@ namespace PortfolioManager.Renderers coordinates = new Coordinates(dates[0].ToOADate() - offsets.Offset(OffsetDictionary.OffsetType.HorizontalOffset3PC), values[0] - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)); + Coordinates adjCoordinates = new Coordinates(){X=coordinates.X,Y=coordinates.Y}; + if(textPlots.PointInRects(sb.ToString(),coordinates,ref adjCoordinates,offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC))) + { + coordinates.Y = adjCoordinates.Y; + } SKRect markerRect = new SKRect(){Left=(float)coordinates.X,Top=(float)coordinates.Y,Right=(float)coordinates.X+image.Width,Bottom=(float)coordinates.Y+image.Height}; - textPlots.Add(new TextPlot(markerRect)); + textPlots.Add(new TextPlot(sb.ToString(),markerRect,coordinates)); imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image); } @@ -304,8 +333,13 @@ namespace PortfolioManager.Renderers Coordinates coordinates = new Coordinates(limit.EffectiveDate.ToOADate(), limit.StopPrice - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)); + Coordinates adjCoordinates = new Coordinates(){X=coordinates.X,Y=coordinates.Y}; + if(textPlots.PointInRects(sb.ToString(),coordinates,ref adjCoordinates,offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC))) + { + coordinates.Y = adjCoordinates.Y; + } SKRect markerRect = new SKRect(){Left=(float)coordinates.X,Top=(float)coordinates.Y,Right=(float)coordinates.X+image.Width,Bottom=(float)coordinates.Y+image.Height}; - textPlots.Add(new TextPlot(markerRect)); + textPlots.Add(new TextPlot(sb.ToString(),markerRect,coordinates)); ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image); } @@ -325,8 +359,14 @@ namespace PortfolioManager.Renderers Coordinates coordinates = new Coordinates(latestPrice.Date.ToOADate() - offsets.Offset(OffsetDictionary.OffsetType.HorizontalOffset3PC), stopLimit.StopPrice - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)); + + Coordinates adjCoordinates = new Coordinates(){X=coordinates.X,Y=coordinates.Y}; + if(textPlots.PointInRects(sb.ToString(),coordinates,ref adjCoordinates,offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC))) + { + coordinates.Y = adjCoordinates.Y; + } SKRect markerRect = new SKRect(){Left=(float)coordinates.X,Top=(float)coordinates.Y,Right=(float)coordinates.X+image.Width,Bottom=(float)coordinates.Y+image.Height}; - textPlots.Add(new TextPlot(markerRect)); + textPlots.Add(new TextPlot(sb.ToString(),markerRect,coordinates)); ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image); } @@ -363,8 +403,13 @@ namespace PortfolioManager.Renderers Coordinates coordinates = new Coordinates(portfolioTrade.TradeDate.ToOADate(), portfolioTrade.Price - offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC)); + Coordinates adjCoordinates = new Coordinates(){X=coordinates.X,Y=coordinates.Y}; + if(textPlots.PointInRects(sb.ToString(),coordinates,ref adjCoordinates,offsets.Offset(OffsetDictionary.OffsetType.VerticalOffset6P5PC))) + { + coordinates.Y = adjCoordinates.Y; + } SKRect markerRect = new SKRect(){Left=(float)coordinates.X,Top=(float)coordinates.Y,Right=(float)coordinates.X+image.Width,Bottom=(float)coordinates.Y+image.Height}; - textPlots.Add(new TextPlot(markerRect)); + textPlots.Add(new TextPlot(sb.ToString(),markerRect,coordinates)); ImageMarker imageMarker = Plotter.Plot.Add.ImageMarker(coordinates, image); }