163 lines
6.9 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|