Files
Navigator/DataDisplay/Common/GridLines.cs
2024-02-23 06:53:16 -05:00

163 lines
6.9 KiB
C#

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);
}
}
}