Init
This commit is contained in:
32
DataDisplay/Common/DrawingHelper.cs
Normal file
32
DataDisplay/Common/DrawingHelper.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
162
DataDisplay/Common/GridLines.cs
Normal file
162
DataDisplay/Common/GridLines.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
50
DataDisplay/Common/PointMapping.cs
Normal file
50
DataDisplay/Common/PointMapping.cs
Normal 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;}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user