增加对自定义Chart的支持

This commit is contained in:
monitor1394
2021-04-22 18:55:56 +08:00
parent 9284ba3eac
commit 2f9af18fd0
17 changed files with 177 additions and 43 deletions

View File

@@ -57,6 +57,7 @@ namespace XCharts
private StringBuilder sb = new StringBuilder(); private StringBuilder sb = new StringBuilder();
private bool m_BaseFoldout; private bool m_BaseFoldout;
private bool m_CustomFoldout;
protected bool m_ShowAllComponent; protected bool m_ShowAllComponent;
protected Dictionary<string, bool> m_Flodouts = new Dictionary<string, bool>(); protected Dictionary<string, bool> m_Flodouts = new Dictionary<string, bool>();
@@ -130,7 +131,20 @@ namespace XCharts
EditorGUILayout.PropertyField(m_ChartName); EditorGUILayout.PropertyField(m_ChartName);
} }
BlockEnd(); BlockEnd();
var fileds = m_Chart.GetCustomChartInspectorShowFileds();
if (fileds != null && fileds.Length > 0)
{
BlockStart();
m_CustomFoldout = EditorGUILayout.Foldout(m_CustomFoldout, "Custom", true);
if (m_CustomFoldout)
{
foreach (var filed in fileds)
{
EditorGUILayout.PropertyField(serializedObject.FindProperty(filed));
}
}
BlockEnd();
}
BlockField(m_Theme); BlockField(m_Theme);
BlockField(m_Settings); BlockField(m_Settings);
BlockField(m_Background); BlockField(m_Background);

View File

@@ -208,6 +208,18 @@ namespace XCharts
PropertyField(prop, "m_Label"); PropertyField(prop, "m_Label");
PropertyField(prop, "m_Emphasis"); PropertyField(prop, "m_Emphasis");
break; break;
case SerieType.Custom:
var fileds = chart.GetCustomSerieInspectorShowFileds();
if (fileds != null && fileds.Length > 0)
{
foreach (var filed in fileds)
{
PropertyField(prop, filed);
}
}
PropertyField(prop, "m_ItemStyle");
PropertyField(prop, "m_Label");
break;
} }
PropertyField(prop, "m_Animation"); PropertyField(prop, "m_Animation");
DrawData(pos, prop, serieType, ref m_DrawRect); DrawData(pos, prop, serieType, ref m_DrawRect);

View File

@@ -56,7 +56,7 @@ namespace XCharts
return name; return name;
} }
private static void AddChart<T>(string chartName) where T : BaseChart public static void AddChart<T>(string chartName) where T : BaseChart
{ {
var parent = GetParent(); var parent = GetParent();
if (parent == null) return; if (parent == null) return;

View File

@@ -719,5 +719,24 @@ namespace XCharts
{ {
return SeriesHelper.ContainsSerie(m_Series, serieType); return SeriesHelper.ContainsSerie(m_Series, serieType);
} }
public virtual bool AddDefaultCustomSerie(string serieName)
{
return false;
}
public virtual string[] GetCustomSerieInspectorShowFileds()
{
return null;
}
public virtual string[] GetCustomChartInspectorShowFileds()
{
return null;
}
public int GetLegendRealShowNameIndex(string name)
{
return m_LegendRealShowName.IndexOf(name);
}
} }
} }

View File

@@ -68,6 +68,10 @@ namespace XCharts
/// 甘特图。甘特图的data至少包含两个数据[start, end] /// 甘特图。甘特图的data至少包含两个数据[start, end]
/// </summary> /// </summary>
Gantt, Gantt,
/// <summary>
/// 自定义。
/// </summary>
Custom,
} }
/// <summary> /// <summary>
@@ -277,6 +281,7 @@ namespace XCharts
[SerializeField] private bool m_ClickOffset = true; [SerializeField] private bool m_ClickOffset = true;
[SerializeField] private RoseType m_RoseType = RoseType.None; [SerializeField] private RoseType m_RoseType = RoseType.None;
[FormerlySerializedAs("m_Gap")]
[SerializeField] private float m_Space; [SerializeField] private float m_Space;
[SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.45f }; [SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.45f };
[SerializeField] private float[] m_Radius = new float[2] { 0, 80 }; [SerializeField] private float[] m_Radius = new float[2] { 0, 80 };
@@ -301,6 +306,10 @@ namespace XCharts
[SerializeField] private float m_WaveSpeed = 5f; [SerializeField] private float m_WaveSpeed = 5f;
[SerializeField] private float m_WaveOffset = 0f; [SerializeField] private float m_WaveOffset = 0f;
[SerializeField] private RadarType m_RadarType = RadarType.Multiple; [SerializeField] private RadarType m_RadarType = RadarType.Multiple;
[SerializeField] private float m_Left;
[SerializeField] private float m_Right;
[SerializeField] private float m_Top;
[SerializeField] private float m_Bottom;
[SerializeField] private List<SerieData> m_Data = new List<SerieData>(); [SerializeField] private List<SerieData> m_Data = new List<SerieData>();
@@ -590,6 +599,11 @@ namespace XCharts
get { return m_Space; } get { return m_Space; }
set { if (PropertyUtil.SetStruct(ref m_Space, value)) SetVerticesDirty(); } set { if (PropertyUtil.SetStruct(ref m_Space, value)) SetVerticesDirty(); }
} }
public float gap
{
get { return m_Space; }
set { if (PropertyUtil.SetStruct(ref m_Space, value)) SetVerticesDirty(); }
}
/// <summary> /// <summary>
/// the center of chart. /// the center of chart.
/// 中心点。 /// 中心点。
@@ -882,6 +896,42 @@ namespace XCharts
set { if (PropertyUtil.SetStruct(ref m_WaveSpeed, value)) SetVerticesDirty(); } set { if (PropertyUtil.SetStruct(ref m_WaveSpeed, value)) SetVerticesDirty(); }
} }
/// <summary> /// <summary>
/// Distance between component and the left side of the container.
/// 组件离容器左侧的距离。
/// </summary>
public float left
{
get { return m_Left; }
set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); }
}
/// <summary>
/// Distance between component and the right side of the container.
/// 组件离容器右侧的距离。
/// </summary>
public float right
{
get { return m_Right; }
set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); }
}
/// <summary>
/// Distance between component and the top side of the container.
/// 组件离容器上侧的距离。
/// </summary>
public float top
{
get { return m_Top; }
set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); }
}
/// <summary>
/// Distance between component and the bottom side of the container.
/// 组件离容器下侧的距离。
/// </summary>
public float bottom
{
get { return m_Bottom; }
set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); }
}
/// <summary>
/// 系列中的数据内容数组。SerieData可以设置1到n维数据。 /// 系列中的数据内容数组。SerieData可以设置1到n维数据。
/// </summary> /// </summary>
public List<SerieData> data { get { return m_Data; } } public List<SerieData> data { get { return m_Data; } }
@@ -981,6 +1031,10 @@ namespace XCharts
public Painter runtimeCanvas { get; internal set; } public Painter runtimeCanvas { get; internal set; }
internal float runtimeCheckValue { get; set; } internal float runtimeCheckValue { get; set; }
public int runtimeGridIndex { get; internal set; } public int runtimeGridIndex { get; internal set; }
public float runtimeX { get; internal set; }
public float runtimeY { get; internal set; }
public float runtimeWidth { get; internal set; }
public float runtimeHeight { get; internal set; }
public bool nameDirty { get { return m_NameDirty; } } public bool nameDirty { get { return m_NameDirty; } }
private void SetNameDirty() private void SetNameDirty()

View File

@@ -187,7 +187,7 @@ namespace XCharts
/// 饼图数据项的偏移半径 /// 饼图数据项的偏移半径
/// </summary> /// </summary>
public float runtimePieOffsetRadius { get; internal set; } public float runtimePieOffsetRadius { get; internal set; }
public Vector3 runtimePosition { get; internal set; } public Vector3 runtimePosition { get; set; }
/// <summary> /// <summary>
/// 绘制区域。 /// 绘制区域。
/// </summary> /// </summary>

View File

@@ -23,8 +23,8 @@ namespace XCharts
private static Regex s_RegexNewLine = new Regex(@"[\\|/]+n", RegexOptions.IgnoreCase); private static Regex s_RegexNewLine = new Regex(@"[\\|/]+n", RegexOptions.IgnoreCase);
private static Regex s_RegexForAxisLabel = new Regex(@"{value(:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); private static Regex s_RegexForAxisLabel = new Regex(@"{value(:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase);
private static Regex s_RegexSubForAxisLabel = new Regex(@"(value)|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); private static Regex s_RegexSubForAxisLabel = new Regex(@"(value)|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase);
private static Regex s_RegexForSerieLabel = new Regex(@"{[a-d](:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase); private static Regex s_RegexForSerieLabel = new Regex(@"{[a-d|\.](:[c-g|x|p|r]\d*)?}", RegexOptions.IgnoreCase);
private static Regex s_RegexSubForSerieLabel = new Regex(@"([a-d])|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase); private static Regex s_RegexSubForSerieLabel = new Regex(@"(\.)|([a-d])|([c-g|x|p|r]\d*)", RegexOptions.IgnoreCase);
/// <summary> /// <summary>
/// 替换字符串中的通配符,支持的通配符有{.}、{a}、{b}、{c}、{d}。 /// 替换字符串中的通配符,支持的通配符有{.}、{a}、{b}、{c}、{d}。
@@ -214,7 +214,7 @@ namespace XCharts
} }
public static void ReplaceSerieLabelContent(ref string content, string numericFormatter, float value, float total, public static void ReplaceSerieLabelContent(ref string content, string numericFormatter, float value, float total,
string serieName, string dataName) string serieName, string dataName, Color color)
{ {
var mc = s_RegexForSerieLabel.Matches(content); var mc = s_RegexForSerieLabel.Matches(content);
foreach (var m in mc) foreach (var m in mc)
@@ -228,7 +228,11 @@ namespace XCharts
{ {
numericFormatter = args[1].ToString(); numericFormatter = args[1].ToString();
} }
if (p == 'a' || p == 'A') if (p == '.')
{
content = content.Replace(old, ChartCached.ColorToDotStr(color));
}
else if (p == 'a' || p == 'A')
{ {
content = content.Replace(old, serieName); content = content.Replace(old, serieName);
} }

View File

@@ -85,5 +85,47 @@ namespace XCharts
} }
return true; return true;
} }
/// <summary>
/// 更新运行时中心点和半径
/// </summary>
/// <param name="chartWidth"></param>
/// <param name="chartHeight"></param>
public static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
{
if (serie.center.Length < 2) return;
var centerX = serie.center[0] <= 1 ? chartWidth * serie.center[0] : serie.center[0];
var centerY = serie.center[1] <= 1 ? chartHeight * serie.center[1] : serie.center[1];
serie.runtimeCenterPos = chartPosition + new Vector3(centerX, centerY);
var minWidth = Mathf.Min(chartWidth, chartHeight);
serie.runtimeInsideRadius = serie.radius[0] <= 1 ? minWidth * serie.radius[0] : serie.radius[0];
serie.runtimeOutsideRadius = serie.radius[1] <= 1 ? minWidth * serie.radius[1] : serie.radius[1];
}
public static void UpdateRect(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
{
if (serie.left != 0 || serie.right != 0 || serie.top != 0 || serie.bottom != 0)
{
var runtimeLeft = serie.left <= 1 ? serie.left * chartWidth : serie.left;
var runtimeBottom = serie.bottom <= 1 ? serie.bottom * chartHeight : serie.bottom;
var runtimeTop = serie.top <= 1 ? serie.top * chartHeight : serie.top;
var runtimeRight = serie.right <= 1 ? serie.right * chartWidth : serie.right;
serie.runtimeX = chartPosition.x + runtimeLeft;
serie.runtimeY = chartPosition.y + runtimeBottom;
serie.runtimeWidth = chartWidth - runtimeLeft - runtimeRight;
serie.runtimeHeight = chartHeight - runtimeTop - runtimeBottom;
serie.runtimeCenterPos = new Vector3(serie.runtimeX + serie.runtimeWidth / 2,
serie.runtimeY + serie.runtimeHeight / 2);
}
else
{
serie.runtimeX = chartPosition.x;
serie.runtimeY = chartPosition.y;
serie.runtimeWidth = chartWidth;
serie.runtimeHeight = chartHeight;
serie.runtimeCenterPos = chartPosition + new Vector3(chartWidth / 2, chartHeight / 2);
}
}
} }
} }

View File

@@ -86,7 +86,7 @@ namespace XCharts
protected GameObject m_SerieLabelRoot; protected GameObject m_SerieLabelRoot;
private Theme m_CheckTheme = 0; private Theme m_CheckTheme = 0;
private List<IDrawSerie> m_DrawSeries = new List<IDrawSerie>(); protected List<IDrawSerie> m_DrawSeries = new List<IDrawSerie>();
protected override void InitComponent() protected override void InitComponent()
{ {
@@ -170,13 +170,13 @@ namespace XCharts
m_Painter.Refresh(); m_Painter.Refresh();
} }
internal void RefreshPainter(int index) public void RefreshPainter(int index)
{ {
var painter = GetPainter(index); var painter = GetPainter(index);
RefreshPainter(painter); RefreshPainter(painter);
} }
internal void RefreshPainter(Serie serie) public void RefreshPainter(Serie serie)
{ {
RefreshPainter(GetPainterIndexBySerie(serie)); RefreshPainter(GetPainterIndexBySerie(serie));
} }

View File

@@ -1697,11 +1697,13 @@ namespace XCharts
if (anyPercentStack && isPercentStack) if (anyPercentStack && isPercentStack)
{ {
var tempTotal = GetSameStackTotalValue(serie.stack, j); var tempTotal = GetSameStackTotalValue(serie.stack, j);
content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, tempTotal, serieLabel); content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, tempTotal,
serieLabel, theme.GetColor(i));
} }
else else
{ {
content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
serieLabel, theme.GetColor(i));
} }
serieData.SetLabelActive(value != 0 && serieData.labelPosition != Vector3.zero); serieData.SetLabelActive(value != 0 && serieData.labelPosition != Vector3.zero);
var invert = serieLabel.autoOffset var invert = serieLabel.autoOffset

View File

@@ -544,7 +544,8 @@ namespace XCharts
{ {
var value = serieData.data[1]; var value = serieData.data[1];
var total = serie.yTotal; var total = serie.yTotal;
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
serieLabel, serieColor);
if (serieData.labelObject.SetText(content)) chart.RefreshPainter(serie); if (serieData.labelObject.SetText(content)) chart.RefreshPainter(serie);
} }
else else

View File

@@ -102,7 +102,8 @@ namespace XCharts
SerieLabelHelper.ResetLabel(serieData.labelObject.label, serieLabel, chart.theme, i); SerieLabelHelper.ResetLabel(serieData.labelObject.label, serieLabel, chart.theme, i);
serieData.SetLabelActive(serieData.labelPosition != Vector3.zero); serieData.SetLabelActive(serieData.labelPosition != Vector3.zero);
serieData.labelObject.SetLabelPosition(serieLabel.offset); serieData.labelObject.SetLabelPosition(serieLabel.offset);
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, max, serieLabel); var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, max,
serieLabel, Color.clear);
if (serieData.labelObject.SetText(content)) if (serieData.labelObject.SetText(content))
{ {
chart.RefreshPainter(serie); chart.RefreshPainter(serie);

View File

@@ -179,7 +179,7 @@ namespace XCharts
else return null; else return null;
} }
internal static SerieLabel GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false) public static SerieLabel GetSerieLabel(Serie serie, SerieData serieData, bool highlight = false)
{ {
if (highlight) if (highlight)
{ {
@@ -272,22 +272,6 @@ namespace XCharts
else return null; else return null;
} }
/// <summary>
/// 更新运行时中心点和半径
/// </summary>
/// <param name="chartWidth"></param>
/// <param name="chartHeight"></param>
internal static void UpdateCenter(Serie serie, Vector3 chartPosition, float chartWidth, float chartHeight)
{
if (serie.center.Length < 2) return;
var centerX = serie.center[0] <= 1 ? chartWidth * serie.center[0] : serie.center[0];
var centerY = serie.center[1] <= 1 ? chartHeight * serie.center[1] : serie.center[1];
serie.runtimeCenterPos = chartPosition + new Vector3(centerX, centerY);
var minWidth = Mathf.Min(chartWidth, chartHeight);
serie.runtimeInsideRadius = serie.radius[0] <= 1 ? minWidth * serie.radius[0] : serie.radius[0];
serie.runtimeOutsideRadius = serie.radius[1] <= 1 ? minWidth * serie.radius[1] : serie.radius[1];
}
internal static string GetNumericFormatter(Serie serie, SerieData serieData) internal static string GetNumericFormatter(Serie serie, SerieData serieData)
{ {
var itemStyle = SerieHelper.GetItemStyle(serie, serieData); var itemStyle = SerieHelper.GetItemStyle(serie, serieData);

View File

@@ -6,11 +6,10 @@
/************************************************/ /************************************************/
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UI;
namespace XCharts namespace XCharts
{ {
internal static class SerieLabelHelper public static class SerieLabelHelper
{ {
public static void CheckLabel(Serie serie, ref bool m_ReinitLabel, ref bool m_UpdateLabelText) public static void CheckLabel(Serie serie, ref bool m_ReinitLabel, ref bool m_UpdateLabelText)
{ {
@@ -90,7 +89,7 @@ namespace XCharts
} }
public static string GetFormatterContent(Serie serie, SerieData serieData, public static string GetFormatterContent(Serie serie, SerieData serieData,
float dataValue, float dataTotal, SerieLabel serieLabel = null) float dataValue, float dataTotal, SerieLabel serieLabel, Color color)
{ {
if (serieLabel == null) if (serieLabel == null)
{ {
@@ -105,7 +104,7 @@ namespace XCharts
{ {
var content = serieLabel.formatter; var content = serieLabel.formatter;
FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, dataValue, FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, dataValue,
dataTotal, serieName, dataName); dataTotal, serieName, dataName, color);
return content; return content;
} }
} }
@@ -117,7 +116,7 @@ namespace XCharts
if (serieData.labelObject == null) return; if (serieData.labelObject == null) return;
var value = serieData.GetData(1); var value = serieData.GetData(1);
var total = serie.max; var total = serie.max;
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear);
serieData.labelObject.SetText(content); serieData.labelObject.SetText(content);
serieData.labelObject.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset); serieData.labelObject.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset);
if (!ChartHelper.IsClearColor(serie.label.textStyle.color)) if (!ChartHelper.IsClearColor(serie.label.textStyle.color))
@@ -141,7 +140,7 @@ namespace XCharts
} }
var value = serieData.GetData(0); var value = serieData.GetData(0);
var total = serieData.GetData(1); var total = serieData.GetData(1);
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear);
serieData.SetLabelActive(true); serieData.SetLabelActive(true);
serieData.labelObject.SetText(content); serieData.labelObject.SetText(content);
serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, i)); serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, i));
@@ -176,7 +175,7 @@ namespace XCharts
} }
var value = serieData.GetData(1); var value = serieData.GetData(1);
var total = serie.max - serie.min; var total = serie.max - serie.min;
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total); var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, null, Color.clear);
serieData.SetLabelActive(true); serieData.SetLabelActive(true);
serieData.labelObject.SetText(content); serieData.labelObject.SetText(content);
serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, colorIndex)); serieData.labelObject.SetLabelColor(GetLabelColor(serie, theme, colorIndex));
@@ -295,7 +294,7 @@ namespace XCharts
} }
} }
internal static Vector3 GetRealLabelPosition(SerieData serieData, SerieLabel label) public static Vector3 GetRealLabelPosition(SerieData serieData, SerieLabel label)
{ {
if (label.position == SerieLabel.Position.Outside && label.lineType != SerieLabel.LineType.HorizontalLine) if (label.position == SerieLabel.Position.Outside && label.lineType != SerieLabel.LineType.HorizontalLine)
{ {

View File

@@ -146,7 +146,8 @@ namespace XCharts
else else
{ {
string content = itemFormatter; string content = itemFormatter;
FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value, total, serie.name, sd.name); FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value, total, serie.name,
sd.name, theme.GetColor(i));
sb.Append(content); sb.Append(content);
} }
} }
@@ -180,10 +181,10 @@ namespace XCharts
else else
{ {
string content = itemFormatter2; string content = itemFormatter2;
FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value2, total2, serie.name, serieData.name); FormatterHelper.ReplaceSerieLabelContent(ref content, numericFormatter, value2, total2, serie.name,
serieData.name, theme.GetColor(serie.index));
sb.Append(content); sb.Append(content);
} }
break; break;
} }
} }

View File

@@ -29,6 +29,7 @@ namespace XCharts
case SerieType.Ring: AddDefaultRingSerie(chart, serieName); break; case SerieType.Ring: AddDefaultRingSerie(chart, serieName); break;
case SerieType.Candlestick: AddDefaultCandlestickSerie(chart, serieName); break; case SerieType.Candlestick: AddDefaultCandlestickSerie(chart, serieName); break;
case SerieType.Gantt: AddDefaultCategoryGanttSerie(chart, serieName); break; case SerieType.Gantt: AddDefaultCategoryGanttSerie(chart, serieName); break;
case SerieType.Custom: chart.AddDefaultCustomSerie(serieName); break;
default: Debug.LogError("AddDefaultSerie: not support serieType yet:" + serieType); break; default: Debug.LogError("AddDefaultSerie: not support serieType yet:" + serieType); break;
} }
} }

View File

@@ -12,7 +12,7 @@ namespace XCharts
{ {
public static class DateTimeUtil public static class DateTimeUtil
{ {
private static readonly DateTime k_DateTime1970 = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); private static readonly DateTime k_DateTime1970 = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Local);
public static int GetTimestamp() public static int GetTimestamp()
{ {