This commit is contained in:
2024-02-23 06:53:16 -05:00
commit dbdccce727
1094 changed files with 57645 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Text;
namespace DataDisplay.Common
{
public class DrawingHelper
{
private DrawingHelper()
{
}
public static void DrawIsoTriangle(SKCanvas canvas, SKPoint origin, int length, SKPaint paintStroke, SKPaint paintFill)
{
SKPath path = new SKPath();
float lengthF = (float)length;
float hLength = lengthF / 2f;
float height = (float)Math.Sqrt(Math.Pow(lengthF, 2) - Math.Pow(hLength, 2));
height/=1.15f; // reduce the height by 15%
path.MoveTo(origin.X, origin.Y);
path.LineTo(origin.X - hLength, origin.Y + height);
path.LineTo(origin.X + hLength, origin.Y + height);
path.LineTo(origin.X, origin.Y);
path.Close();
canvas.DrawPath(path, paintStroke);
canvas.DrawPath(path, paintFill);
}
}
}

View File

@@ -0,0 +1,162 @@
using MarketData.Utils;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace DataDisplay.Common
{
public class GridLines
{
public delegate Type GetXDataType();
public delegate Type GetYDataType();
public delegate String XDataFormatter(Object data); // custom formatter for XData
public delegate String YDataFormatter(Object data); // custom formatter for YData
private SKPaint paintGrid=new SKPaint{Style=SKPaintStyle.Stroke,Color=new SKColor((uint)SKColors.LightGray),StrokeWidth=1f};
private SKPaint paintAxis=new SKPaint{Style=SKPaintStyle.Stroke,Color=new SKColor((uint)SKColors.Black),StrokeWidth=3f};
private SKPaint paintHorizontalLabelText=new SKPaint{TextSize=24f,IsAntialias=true,Color=new SKColor((uint)SKColors.Black),IsStroke=false,Typeface=SKTypeface.FromFamilyName("Calibri",SKFontStyleWeight.Bold,SKFontStyleWidth.Normal,SKFontStyleSlant.Upright)}; // dates
private SKPaint paintVerticalLabelText=new SKPaint{TextSize=24f,IsAntialias=true,Color=new SKColor((uint)SKColors.Black),IsStroke=false,Typeface=SKTypeface.FromFamilyName("Calibri",SKFontStyleWeight.Bold,SKFontStyleWidth.Normal,SKFontStyleSlant.Upright)}; // values
private GetXDataType getXDataType=null;
private GetYDataType getYDataType=null;
private XDataFormatter xDataFormatter;
private YDataFormatter yDataFormatter;
private Dictionary<String,String> uniqueVerticalLabels;
private Dictionary<String,String> uniqueHorizontalLabels;
public GridLines(double xGridLines,double yGridLines)
{
XGridLines=xGridLines;
YGridLines=yGridLines;
uniqueVerticalLabels=new Dictionary<String,String>();
uniqueHorizontalLabels=new Dictionary<String,String>();
}
public double XGridLines{get;private set;}
public double YGridLines{get;private set;}
public GetXDataType AssignXDataType
{
get{return getXDataType;}
set{getXDataType=value;}
}
public GetYDataType AssignGetYDataType
{
get{return getYDataType;}
set{getYDataType=value;}
}
public XDataFormatter AssignXDataFormatter
{
get{return xDataFormatter;}
set{xDataFormatter=value;}
}
public YDataFormatter AssignYDataFormatter
{
get{return yDataFormatter;}
set{yDataFormatter=value;}
}
public void Render(SKCanvas canvas,PointMapping pointMapping,SKPaint axisPaint=null,SKPaint gridPaint=null)
{
if(null==axisPaint)axisPaint=paintAxis;
if(null==gridPaint)gridPaint=paintGrid;
SKPoint p1;
SKPoint p2;
double xLineFactor = pointMapping.XRange/XGridLines;
double yLineFactor = pointMapping.YRange/YGridLines;
if(0==xLineFactor)xLineFactor=.01;
if(0==yLineFactor)yLineFactor=.01;
// Draw horizontal line grid - the labels go along the left
for (double yIndex = pointMapping.YDataExtentMin; yIndex <= pointMapping.YDataExtent+.05; yIndex += yLineFactor)
{
p1 = pointMapping.MapPoint(new SKPoint((float)pointMapping.XDataExtentMin, (float)yIndex));
p2 = pointMapping.MapPoint(new SKPoint((float)pointMapping.XDataExtent, (float)yIndex));
if(yIndex==pointMapping.YDataExtentMin)canvas.DrawPoints(SKPointMode.Polygon, new SKPoint[] { p1, p2 }, axisPaint);
else canvas.DrawPoints(SKPointMode.Polygon, new SKPoint[] { p1, p2 }, gridPaint);
p1.X=0f;
DisplayXAxisLabel(canvas,pointMapping,p1,yIndex);
}
// Draw vertical line grid - the labels go along the bottom
for (double xIndex = pointMapping.XDataExtentMin; xIndex <= pointMapping.XDataExtent+.05; xIndex += xLineFactor)
{
p1 = pointMapping.MapPoint(new SKPoint((float)xIndex,(float)pointMapping.YDataExtentMin));
p2 = pointMapping.MapPoint(new SKPoint((float)xIndex, (float)pointMapping.YDataExtent));
if(xIndex==pointMapping.XDataExtentMin)canvas.DrawPoints(SKPointMode.Polygon, new SKPoint[] { p1, p2 }, axisPaint);
else canvas.DrawPoints(SKPointMode.Polygon, new SKPoint[] { p1, p2 }, gridPaint);
p1.Y=(float)pointMapping.Height;
DisplayYAxisLabel(canvas,pointMapping,p1,xIndex);
}
}
// The labels along the left of the chart
private void DisplayXAxisLabel(SKCanvas canvas,PointMapping pointMapping,SKPoint p1,double yIndex)
{
String strLabel;
double percentage=(yIndex - pointMapping.YDataExtentMin) / pointMapping.YRange;
Type dataType=typeof(double);
if(null!=getYDataType)dataType=getYDataType();
if(dataType.Equals(typeof(DateTime)))
{
DateTime axisDate=new DateTime((long)((pointMapping.YDataExtentMin+(pointMapping.YRange*percentage))*10000000000.0));
if(null!=yDataFormatter)strLabel=yDataFormatter(axisDate);
else strLabel=Utility.DateTimeToStringMMSYY(axisDate);
}
else if(dataType.Equals(typeof(double)))
{
double value=pointMapping.YDataExtentMin+(pointMapping.YRange*percentage);
if(null!=yDataFormatter)strLabel=yDataFormatter(value);
else
{
if(value>=1000)strLabel=Utility.FormatNumber(value,0,true);
else strLabel=Utility.FormatNumber(value,2,true);
}
}
else
{
double value=pointMapping.YDataExtentMin+(pointMapping.YRange*percentage);
strLabel=Utility.FormatNumber(value,0,true);
}
if(uniqueVerticalLabels.ContainsKey(strLabel))return;
uniqueVerticalLabels.Add(strLabel,strLabel);
if(null!=strLabel)canvas.DrawText(strLabel, p1, paintVerticalLabelText);
}
// The labels along the bottom of the chart
private void DisplayYAxisLabel(SKCanvas canvas,PointMapping pointMapping,SKPoint p1,double xIndex)
{
String strLabel=null;
double percentage=(xIndex-pointMapping.XDataExtentMin)/pointMapping.XRange;
Type dataType=typeof(double);
if(null!=getXDataType())dataType=getXDataType();
if (dataType.Equals(typeof(DateTime)))
{
DateTime axisDate=new DateTime((long)((pointMapping.XDataExtentMin+(pointMapping.XRange*percentage))*10000000000.0));
if(null!=xDataFormatter)strLabel=xDataFormatter(axisDate);
else strLabel=Utility.DateTimeToStringMMSYY(axisDate);
}
else if(dataType.Equals(typeof(double)))
{
double value=pointMapping.XDataExtentMin+(pointMapping.XRange*percentage);
if(null!=xDataFormatter)strLabel=xDataFormatter(value);
else
{
if(value>=1000)strLabel=Utility.FormatNumber(value,0,true);
else strLabel=Utility.FormatNumber(value,2,true);
}
}
else
{
double value=pointMapping.XDataExtentMin+(pointMapping.XRange*percentage);
strLabel=Utility.FormatNumber(value,0,true);
}
if(uniqueHorizontalLabels.ContainsKey(strLabel))return;
uniqueHorizontalLabels.Add(strLabel,strLabel);
if(null!=strLabel)canvas.DrawText(strLabel, p1, paintHorizontalLabelText);
}
}
}

View File

@@ -0,0 +1,50 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Text;
namespace DataDisplay.Common
{
public class PointMapping
{
public PointMapping(double width,double height,double xDataExtent,double xDataExtentMin,double yDataExtent,double yDataExtentMin,double xMarginExtent=0.00,double yMarginExtent=0.00)
{
Width=width;
Height=height;
XMargin=xMarginExtent;
YMargin=yMarginExtent;
XDataExtent=xDataExtent;
XDataExtentMin=xDataExtentMin;
YDataExtent=yDataExtent;
YDataExtentMin=yDataExtentMin;
XScalingFactor=(Width-(XMargin*2))/(XDataExtent-XDataExtentMin);
YScalingFactor=(Height-(YMargin*2))/(YDataExtent-YDataExtentMin);
}
// MapPoint will both scale the given point and translate the given point from an upper left origin system to a bottom left origin system
public SKPoint MapPoint(SKPoint sourcePoint)
{
SKPoint mappedPoint=new SKPoint((float)((sourcePoint.X-XDataExtentMin)*XScalingFactor),(float)(Height-((sourcePoint.Y-YDataExtentMin)*YScalingFactor)));
mappedPoint.X+=(float)XMargin; // offset by the xMargin
mappedPoint.Y-=(float)YMargin; // offset by the yMargin
return mappedPoint;
}
// TranslatePoint will only translate the given point from an upper left origin system to a bottom left origin system
public SKPoint TranslatePoint(SKPoint sourcePoint)
{
SKPoint mappedPoint=new SKPoint((float)sourcePoint.X,(float)(Height-sourcePoint.Y-1));
return mappedPoint;
}
public double Width{get;private set;}
public double Height{get;private set;}
public double XDataExtent{get;private set;}
public double XDataExtentMin{get;private set;}
public double XRange{get{return XDataExtent-XDataExtentMin;}}
public double YDataExtent{get;private set;}
public double YDataExtentMin{get;private set;}
public double YRange{get{return YDataExtent-YDataExtentMin;}}
public double XMargin{get;private set;}
public double YMargin{get;private set;}
public double XScalingFactor{get;private set;}
public double YScalingFactor{get;private set;}
}
}