增加ChartuseUtc参数设置显示时间是否用UTC时间

This commit is contained in:
monitor1394
2025-10-31 08:39:29 +08:00
parent 2cb82526bc
commit f1c9a3ac4b
12 changed files with 42 additions and 33 deletions

View File

@@ -80,6 +80,7 @@ slug: /changelog
## master ## master
* (2025.10.30) 增加`Chart``useUtc`参数设置显示时间是否用UTC时间
* (2025.10.30) 优化`Candlestick`对时间轴的支持 * (2025.10.30) 优化`Candlestick`对时间轴的支持
* (2025.10.30) 增加`Scatter``ignore`支持设置忽略数据 * (2025.10.30) 增加`Scatter``ignore`支持设置忽略数据
* (2025.10.24) 优化`Sankey`的线条绘制排序 * (2025.10.24) 优化`Sankey`的线条绘制排序

View File

@@ -26,6 +26,7 @@ namespace XCharts.Editor
protected SerializedProperty m_Settings; protected SerializedProperty m_Settings;
protected SerializedProperty m_Theme; protected SerializedProperty m_Theme;
protected SerializedProperty m_ChartName; protected SerializedProperty m_ChartName;
protected SerializedProperty m_UseUtc;
protected SerializedProperty m_DebugInfo; protected SerializedProperty m_DebugInfo;
protected SerializedProperty m_RaycastTarget; protected SerializedProperty m_RaycastTarget;
@@ -49,6 +50,7 @@ namespace XCharts.Editor
m_Script = serializedObject.FindProperty("m_Script"); m_Script = serializedObject.FindProperty("m_Script");
m_EnableTextMeshPro = serializedObject.FindProperty("m_EnableTextMeshPro"); m_EnableTextMeshPro = serializedObject.FindProperty("m_EnableTextMeshPro");
m_ChartName = serializedObject.FindProperty("m_ChartName"); m_ChartName = serializedObject.FindProperty("m_ChartName");
m_UseUtc = serializedObject.FindProperty("m_UseUtc");
m_Theme = serializedObject.FindProperty("m_Theme"); m_Theme = serializedObject.FindProperty("m_Theme");
m_Settings = serializedObject.FindProperty("m_Settings"); m_Settings = serializedObject.FindProperty("m_Settings");
m_DebugInfo = serializedObject.FindProperty("m_DebugInfo"); m_DebugInfo = serializedObject.FindProperty("m_DebugInfo");
@@ -124,6 +126,7 @@ namespace XCharts.Editor
{ {
EditorGUILayout.PropertyField(m_Script); EditorGUILayout.PropertyField(m_Script);
EditorGUILayout.PropertyField(m_ChartName); EditorGUILayout.PropertyField(m_ChartName);
EditorGUILayout.PropertyField(m_UseUtc);
EditorGUILayout.PropertyField(m_RaycastTarget); EditorGUILayout.PropertyField(m_RaycastTarget);
if (XChartsMgr.IsRepeatChartName(m_Chart, m_ChartName.stringValue)) if (XChartsMgr.IsRepeatChartName(m_Chart, m_ChartName.stringValue))
{ {

View File

@@ -85,7 +85,7 @@ namespace XCharts.Runtime
float scaleAngle = AxisHelper.GetScaleWidth(axis, total, i + 1, null); float scaleAngle = AxisHelper.GetScaleWidth(axis, total, i + 1, null);
bool inside = axis.axisLabel.inside; bool inside = axis.axisLabel.inside;
var labelName = AxisHelper.GetLabelName(axis, total, i, axis.context.minValue, axis.context.maxValue, var labelName = AxisHelper.GetLabelName(axis, total, i, axis.context.minValue, axis.context.maxValue,
null, isPercentStack); null, isPercentStack, chart.useUtc);
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform,
new Vector2(scaleAngle, txtHig), axis, new Vector2(scaleAngle, txtHig), axis,
chart.theme.axis, labelName, Color.clear); chart.theme.axis, labelName, Color.clear);

View File

@@ -290,7 +290,7 @@ namespace XCharts
if (context.labelObjectList[i] != null) if (context.labelObjectList[i] != null)
{ {
var index = i < showData.Count ? showData[i].index : i; var index = i < showData.Count ? showData[i].index : i;
var text = AxisHelper.GetLabelName(axis, coordinateWidth, index, destMinValue, destMaxValue, dataZoom, forcePercent, i); var text = AxisHelper.GetLabelName(axis, coordinateWidth, index, destMinValue, destMaxValue, dataZoom, forcePercent, chart.useUtc, i);
context.labelObjectList[i].SetText(text); context.labelObjectList[i].SetText(text);
} }
} }
@@ -322,7 +322,7 @@ namespace XCharts
{ {
if (context.labelObjectList[i] != null) if (context.labelObjectList[i] != null)
{ {
var text = AxisHelper.GetLabelName(axis, coordinateWidth, i, destMinValue, destMaxValue, dataZoom, forcePercent); var text = AxisHelper.GetLabelName(axis, coordinateWidth, i, destMinValue, destMaxValue, dataZoom, forcePercent, chart.useUtc);
context.labelObjectList[i].SetText(text); context.labelObjectList[i].SetText(text);
} }
} }
@@ -364,7 +364,7 @@ namespace XCharts
{ {
var lastCount = axis.context.labelValueList.Count; var lastCount = axis.context.labelValueList.Count;
axis.context.tickValue = DateTimeUtil.UpdateTimeAxisDateTimeList(axis.context.labelValueList, axis.context.tickValue = DateTimeUtil.UpdateTimeAxisDateTimeList(axis.context.labelValueList,
axis.context.minValue, axis.context.maxValue, axis.splitNumber, axis.ceilRate); axis.context.minValue, axis.context.maxValue, axis.splitNumber, axis.ceilRate, !chart.useUtc);
if (axis.context.labelValueList.Count != lastCount) if (axis.context.labelValueList.Count != lastCount)
axis.SetAllDirty(); axis.SetAllDirty();
@@ -454,7 +454,7 @@ namespace XCharts
label.SetTextActive(false); label.SetTextActive(false);
return; return;
} }
if(content == null) if (content == null)
{ {
content = label.text.GetText(); content = label.text.GetText();
} }
@@ -465,12 +465,12 @@ namespace XCharts
if (i == 0) if (i == 0)
{ {
var dist = GetLabelPosition(0, 1).x - pos.x; var dist = GetLabelPosition(0, 1).x - pos.x;
label.SetTextActive(axis.IsNeedShowLabel(i,0,content) && dist > label.text.GetPreferredWidth()); label.SetTextActive(axis.IsNeedShowLabel(i, 0, content) && dist > label.text.GetPreferredWidth());
} }
else if (i == axis.context.labelValueList.Count - 1) else if (i == axis.context.labelValueList.Count - 1)
{ {
var dist = pos.x - GetLabelPosition(0, i - 1).x; var dist = pos.x - GetLabelPosition(0, i - 1).x;
label.SetTextActive(axis.IsNeedShowLabel(i,0,content) && dist > label.text.GetPreferredWidth()); label.SetTextActive(axis.IsNeedShowLabel(i, 0, content) && dist > label.text.GetPreferredWidth());
} }
} }
else else
@@ -478,12 +478,12 @@ namespace XCharts
if (i == 0) if (i == 0)
{ {
var dist = GetLabelPosition(0, 1).y - pos.y; var dist = GetLabelPosition(0, 1).y - pos.y;
label.SetTextActive(axis.IsNeedShowLabel(i,0,content) && dist > label.text.GetPreferredHeight()); label.SetTextActive(axis.IsNeedShowLabel(i, 0, content) && dist > label.text.GetPreferredHeight());
} }
else if (i == axis.context.labelValueList.Count - 1) else if (i == axis.context.labelValueList.Count - 1)
{ {
var dist = pos.y - GetLabelPosition(0, i - 1).y; var dist = pos.y - GetLabelPosition(0, i - 1).y;
label.SetTextActive(axis.IsNeedShowLabel(i,0,content) && dist > label.text.GetPreferredHeight()); label.SetTextActive(axis.IsNeedShowLabel(i, 0, content) && dist > label.text.GetPreferredHeight());
} }
} }
} }
@@ -552,7 +552,7 @@ namespace XCharts
var labelName = AxisHelper.GetLabelName(axis, axisLength, sortIndex, var labelName = AxisHelper.GetLabelName(axis, axisLength, sortIndex,
axis.context.destMinValue, axis.context.destMinValue,
axis.context.destMaxValue, axis.context.destMaxValue,
dataZoom, isPercentStack, i); dataZoom, isPercentStack, chart.useUtc, i);
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, var label = ChartHelper.AddAxisLabelObject(splitNumber, i,
ChartCached.GetAxisLabelName(i), ChartCached.GetAxisLabelName(i),
@@ -671,7 +671,7 @@ namespace XCharts
var labelName = AxisHelper.GetLabelName(axis, axisLength, sortIndex, var labelName = AxisHelper.GetLabelName(axis, axisLength, sortIndex,
axis.context.destMinValue, axis.context.destMinValue,
axis.context.destMaxValue, axis.context.destMaxValue,
dataZoom, isPercentStack, i); dataZoom, isPercentStack, chart.useUtc, i);
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, var label = ChartHelper.AddAxisLabelObject(splitNumber, i,
ChartCached.GetAxisLabelName(i), ChartCached.GetAxisLabelName(i),

View File

@@ -116,7 +116,7 @@ namespace XCharts.Runtime
/// <param name="dataZoom"></param> /// <param name="dataZoom"></param>
/// <returns></returns> /// <returns></returns>
public static string GetLabelName(Axis axis, float coordinateWidth, int index, double minValue, double maxValue, public static string GetLabelName(Axis axis, float coordinateWidth, int index, double minValue, double maxValue,
DataZoom dataZoom, bool forcePercent, int sortIndex = -1) DataZoom dataZoom, bool forcePercent, bool useUtc, int sortIndex = -1)
{ {
int split = GetSplitNumber(axis, coordinateWidth, dataZoom); int split = GetSplitNumber(axis, coordinateWidth, dataZoom);
if (sortIndex == -1) sortIndex = index; if (sortIndex == -1) sortIndex = index;
@@ -161,7 +161,7 @@ namespace XCharts.Runtime
return string.Empty; return string.Empty;
var value = axis.GetLabelValue(index); var value = axis.GetLabelValue(index);
return axis.axisLabel.GetFormatterDateTime(sortIndex, axis.context.labelValueList.Count, value, minValue, maxValue); return axis.axisLabel.GetFormatterDateTime(sortIndex, axis.context.labelValueList.Count, value, minValue, maxValue, !useUtc);
} }
var showData = axis.GetDataList(dataZoom); var showData = axis.GetDataList(dataZoom);
int dataCount = showData.Count; int dataCount = showData.Count;

View File

@@ -114,7 +114,7 @@ namespace XCharts.Runtime
var inside = axis.axisLabel.inside; var inside = axis.axisLabel.inside;
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series); var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
var labelName = AxisHelper.GetLabelName(axis, radius, i, axis.context.minValue, axis.context.maxValue, var labelName = AxisHelper.GetLabelName(axis, radius, i, axis.context.minValue, axis.context.maxValue,
null, isPercentStack); null, isPercentStack, chart.useUtc);
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform,
new Vector2(labelWidth, txtHig), axis, chart.theme.axis, labelName, Color.clear); new Vector2(labelWidth, txtHig), axis, chart.theme.axis, labelName, Color.clear);

View File

@@ -485,10 +485,10 @@ namespace XCharts.Runtime
private static bool isDateFormatter = false; private static bool isDateFormatter = false;
private static string newFormatter = null; private static string newFormatter = null;
public string GetFormatterDateTime(int labelIndex, int totalIndex, double value, double minValue, double maxValue) public string GetFormatterDateTime(int labelIndex, int totalIndex, double value, double minValue, double maxValue, bool local)
{ {
var timestamp = value; var timestamp = value;
var dateTime = DateTimeUtil.GetDateTime(timestamp); var dateTime = DateTimeUtil.GetDateTime(timestamp, local);
var dateString = string.Empty; var dateString = string.Empty;
if (string.IsNullOrEmpty(numericFormatter) || numericFormatter.Equals("f2")) if (string.IsNullOrEmpty(numericFormatter) || numericFormatter.Equals("f2"))
{ {
@@ -501,7 +501,7 @@ namespace XCharts.Runtime
if (DateTimeUtil.IsDateOrTimeRegex(numericFormatter, ref isDateFormatter, ref newFormatter)) if (DateTimeUtil.IsDateOrTimeRegex(numericFormatter, ref isDateFormatter, ref newFormatter))
{ {
if (isDateFormatter) if (isDateFormatter)
dateString = ChartCached.NumberToDateStr(timestamp, newFormatter); dateString = ChartCached.NumberToDateStr(timestamp, newFormatter, local);
else else
dateString = ChartCached.NumberToTimeStr(timestamp, newFormatter); dateString = ChartCached.NumberToTimeStr(timestamp, newFormatter);
} }

View File

@@ -268,7 +268,7 @@ namespace XCharts.Runtime
} }
else if (axis.IsTime()) else if (axis.IsTime())
{ {
label.SetText(axis.indicatorLabel.GetFormatterDateTime(0, 0, axis.context.pointerValue, axis.context.minValue, axis.context.maxValue)); label.SetText(axis.indicatorLabel.GetFormatterDateTime(0, 0, axis.context.pointerValue, axis.context.minValue, axis.context.maxValue, !chart.useUtc));
} }
else else
{ {
@@ -356,7 +356,7 @@ namespace XCharts.Runtime
if (isTriggerAxis) if (isTriggerAxis)
{ {
var index = serie.context.dataZoomStartIndex + (int)yAxis.context.pointerValue; var index = serie.context.dataZoomStartIndex + (int)yAxis.context.pointerValue;
if(serie.useSortData) index = yAxis.context.sortedDataIndices[index]; if (serie.useSortData) index = yAxis.context.sortedDataIndices[index];
serie.context.pointerEnter = true; serie.context.pointerEnter = true;
serie.context.pointerAxisDataIndexs.Add(index); serie.context.pointerAxisDataIndexs.Add(index);
serie.context.pointerItemDataIndex = index; serie.context.pointerItemDataIndex = index;
@@ -376,7 +376,7 @@ namespace XCharts.Runtime
if (isTriggerAxis) if (isTriggerAxis)
{ {
var index = serie.context.dataZoomStartIndex + (int)xAxis.context.pointerValue; var index = serie.context.dataZoomStartIndex + (int)xAxis.context.pointerValue;
if(serie.useSortData) index = xAxis.context.sortedDataIndices[index]; if (serie.useSortData) index = xAxis.context.sortedDataIndices[index];
if (chart.isTriggerOnClick) if (chart.isTriggerOnClick)
{ {
if (serie.insertDataToHead) if (serie.insertDataToHead)
@@ -616,7 +616,7 @@ namespace XCharts.Runtime
var serieData = serie.GetSerieData(serie.context.pointerItemDataIndex); var serieData = serie.GetSerieData(serie.context.pointerItemDataIndex);
if (serieData != null) if (serieData != null)
{ {
tooltip.context.data.title = DateTimeUtil.GetDefaultDateTimeString((int)serieData.GetData(0), axisRange); tooltip.context.data.title = DateTimeUtil.GetDefaultDateTimeString((int)serieData.GetData(0), axisRange, !chart.useUtc);
} }
} }
serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category, serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category,

View File

@@ -31,6 +31,11 @@ namespace XCharts.Runtime
} }
} }
/// <summary> /// <summary>
/// Whether to use UTC time for the chart.
/// ||图表的时间是否都显示为UTC时间。
/// </summary>
public bool useUtc { get { return m_UseUtc; } set { m_UseUtc = value; } }
/// <summary>
/// The theme. /// The theme.
/// ||</summary> /// ||</summary>
public ThemeStyle theme { get { return m_Theme; } set { m_Theme = value; } } public ThemeStyle theme { get { return m_Theme; } set { m_Theme = value; } }

View File

@@ -16,6 +16,7 @@ namespace XCharts.Runtime
public partial class BaseChart : BaseGraph, ISerializationCallbackReceiver public partial class BaseChart : BaseGraph, ISerializationCallbackReceiver
{ {
[SerializeField] protected string m_ChartName; [SerializeField] protected string m_ChartName;
[SerializeField] protected bool m_UseUtc = true;
[SerializeField] protected ThemeStyle m_Theme = new ThemeStyle(); [SerializeField] protected ThemeStyle m_Theme = new ThemeStyle();
[SerializeField] protected Settings m_Settings; [SerializeField] protected Settings m_Settings;
[SerializeField] protected DebugInfo m_DebugInfo = new DebugInfo(); [SerializeField] protected DebugInfo m_DebugInfo = new DebugInfo();

View File

@@ -100,9 +100,9 @@ namespace XCharts.Runtime
return NumberToStr(value, numericFormatter); return NumberToStr(value, numericFormatter);
} }
public static string NumberToDateStr(double timestamp, string formatter) public static string NumberToDateStr(double timestamp, string formatter, bool local = false)
{ {
var dt = NumberToDateTime(timestamp); var dt = NumberToDateTime(timestamp, local);
try try
{ {
return dt.ToString(formatter, ci); return dt.ToString(formatter, ci);
@@ -132,11 +132,11 @@ namespace XCharts.Runtime
} }
} }
public static DateTime NumberToDateTime(double timestamp) public static DateTime NumberToDateTime(double timestamp, bool local = false)
{ {
if (!s_TimestampToDateTimeDict.ContainsKey(timestamp)) if (!s_TimestampToDateTimeDict.ContainsKey(timestamp))
{ {
s_TimestampToDateTimeDict[timestamp] = DateTimeUtil.GetDateTime(timestamp); s_TimestampToDateTimeDict[timestamp] = DateTimeUtil.GetDateTime(timestamp, local);
} }
return s_TimestampToDateTimeDict[timestamp]; return s_TimestampToDateTimeDict[timestamp];
} }

View File

@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using UnityEngine;
namespace XCharts.Runtime namespace XCharts.Runtime
{ {
@@ -145,7 +144,7 @@ namespace XCharts.Runtime
/// <param name="minTimestamp"></param> /// <param name="minTimestamp"></param>
/// <param name="maxTimestamp"></param> /// <param name="maxTimestamp"></param>
/// <param name="splitNumber"></param> /// <param name="splitNumber"></param>
internal static float UpdateTimeAxisDateTimeList(List<double> list, double minTimestamp, double maxTimestamp, int splitNumber, double ceilRate) internal static float UpdateTimeAxisDateTimeList(List<double> list, double minTimestamp, double maxTimestamp, int splitNumber, double ceilRate, bool local)
{ {
var range = maxTimestamp - minTimestamp; var range = maxTimestamp - minTimestamp;
if (range <= 0) if (range <= 0)
@@ -153,8 +152,8 @@ namespace XCharts.Runtime
list.Clear(); list.Clear();
return 0; return 0;
} }
var dtMin = GetDateTime(minTimestamp); var dtMin = GetDateTime(minTimestamp, local);
var dtMax = GetDateTime(maxTimestamp); var dtMax = GetDateTime(maxTimestamp, local);
int tick; int tick;
if (ceilRate != 0) if (ceilRate != 0)
{ {
@@ -179,7 +178,7 @@ namespace XCharts.Runtime
if (range >= ONE_YEAR * MIN_TIME_SPLIT_NUMBER) if (range >= ONE_YEAR * MIN_TIME_SPLIT_NUMBER)
{ {
var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_YEAR) : (int)Math.Max(range / (splitNumber * ONE_YEAR), 1); var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_YEAR) : (int)Math.Max(range / (splitNumber * ONE_YEAR), 1);
var dtStart = GetDateTime(GetFirstMaxValue(list, minTimestamp)); var dtStart = GetDateTime(GetFirstMaxValue(list, minTimestamp), local);
dtStart = new DateTime(dtStart.Year, dtStart.Month, 1); dtStart = new DateTime(dtStart.Year, dtStart.Month, 1);
while (dtStart > dtMin) while (dtStart > dtMin)
{ {
@@ -193,14 +192,14 @@ namespace XCharts.Runtime
list.Clear(); list.Clear();
while (dtStart.Ticks < dtMax.Ticks) while (dtStart.Ticks < dtMax.Ticks)
{ {
list.Add(DateTimeUtil.GetTimestamp(dtStart)); list.Add(DateTimeUtil.GetTimestamp(dtStart, local));
dtStart = dtStart.AddYears(num); dtStart = dtStart.AddYears(num);
} }
} }
else if (range >= ONE_MONTH * MIN_TIME_SPLIT_NUMBER) else if (range >= ONE_MONTH * MIN_TIME_SPLIT_NUMBER)
{ {
var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_MONTH) : (int)Math.Max(range / (splitNumber * ONE_MONTH), 1); var num = splitNumber <= 0 ? GetSplitNumber(range, ONE_MONTH) : (int)Math.Max(range / (splitNumber * ONE_MONTH), 1);
var dtStart = GetDateTime(GetFirstMaxValue(list, minTimestamp)); var dtStart = GetDateTime(GetFirstMaxValue(list, minTimestamp), local);
dtStart = new DateTime(dtStart.Year, dtStart.Month, 1); dtStart = new DateTime(dtStart.Year, dtStart.Month, 1);
while (dtStart > dtMin) while (dtStart > dtMin)
{ {
@@ -214,7 +213,7 @@ namespace XCharts.Runtime
list.Clear(); list.Clear();
while (dtStart.Ticks < dtMax.Ticks) while (dtStart.Ticks < dtMax.Ticks)
{ {
list.Add(DateTimeUtil.GetTimestamp(dtStart)); list.Add(DateTimeUtil.GetTimestamp(dtStart, local));
dtStart = dtStart.AddMonths(num); dtStart = dtStart.AddMonths(num);
} }
} }