diff --git a/Assets/XCharts/Editor/Windows/XChartsEditor.cs b/Assets/XCharts/Editor/Windows/XChartsEditor.cs index bbd68173..4d335e95 100644 --- a/Assets/XCharts/Editor/Windows/XChartsEditor.cs +++ b/Assets/XCharts/Editor/Windows/XChartsEditor.cs @@ -153,6 +153,13 @@ namespace XCharts AddChart("CandlestickChart"); } + [MenuItem("XCharts/ParallelChart", priority = 55)] + [MenuItem("GameObject/XCharts/ParallelChart", priority = 55)] + public static void ParallelChart() + { + AddChart("ParallelChart"); + } + [MenuItem("XCharts/Themes Reload")] public static void ReloadTheme() { diff --git a/Assets/XCharts/Runtime/Chart/ParallelChart.cs b/Assets/XCharts/Runtime/Chart/ParallelChart.cs index 2d22b024..64186be1 100644 --- a/Assets/XCharts/Runtime/Chart/ParallelChart.cs +++ b/Assets/XCharts/Runtime/Chart/ParallelChart.cs @@ -5,6 +5,7 @@ /* */ /************************************************/ +using System.Collections.Generic; using UnityEngine; namespace XCharts @@ -19,19 +20,20 @@ namespace XCharts protected override void Reset() { base.Reset(); - AddChartComponentWhenNoExist(); - AddChartComponentWhenNoExist(); - - var tooltip = GetChartComponent(); - tooltip.type = Tooltip.Type.Shadow; - tooltip.trigger = Tooltip.Trigger.Axis; - RemoveData(); + AddChartComponent(); + + for (int i = 0; i < 3; i++) + { + var valueAxis = AddChartComponent(); + valueAxis.type = Axis.AxisType.Value; + } + var categoryAxis = AddChartComponent(); + categoryAxis.type = Axis.AxisType.Category; + categoryAxis.position = Axis.AxisPosition.Right; + categoryAxis.data = new List() { "x1", "x2", "x3", "x4", "x5" }; + Parallel.AddDefaultSerie(this, GenerateDefaultSerieName()); - // for (int i = 0; i < 5; i++) - // { - // AddXAxisData("x" + (i + 1)); - // } } #endif } diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index 9d7c763e..5232a888 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -42,8 +42,7 @@ namespace XCharts if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue) { chart.m_IsPlayingAnimation = true; - var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse; - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck); + axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); axis.context.xOffset = 0; axis.context.yOffset = 0; axis.context.lastCheckInverse = axis.inverse; @@ -53,7 +52,7 @@ namespace XCharts chart.RefreshChart(); } } - if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation) + if (!chart.m_IsPlayingAnimation) { UpdateAxisLabelText(axis); chart.RefreshChart(); @@ -63,7 +62,7 @@ namespace XCharts internal void UpdateAxisLabelText(AngleAxis axis) { var runtimeWidth = 360; - axis.UpdateLabelText(runtimeWidth, null, false, 500); + axis.UpdateLabelText(runtimeWidth, null, false); } private void InitAngleAxis(AngleAxis axis) diff --git a/Assets/XCharts/Runtime/Component/Axis/Axis.cs b/Assets/XCharts/Runtime/Component/Axis/Axis.cs index e226a20b..708831a7 100644 --- a/Assets/XCharts/Runtime/Component/Axis/Axis.cs +++ b/Assets/XCharts/Runtime/Component/Axis/Axis.cs @@ -664,8 +664,16 @@ namespace XCharts { if (context.minMaxRange == 0) return 0; + + if (IsCategory() && boundaryGap) + { + var each = axisLength / data.Count; + return (float)(each * (value + 0.5f)); + } else + { return axisLength * (float)((value - context.minValue) / context.minMaxRange); + } } /// @@ -718,15 +726,13 @@ namespace XCharts /// 更新刻度标签文字 /// /// - internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent, float duration) + internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent) { - var minValue = GetCurrMinValue(duration); - var maxValue = GetCurrMaxValue(duration); for (int i = 0; i < context.labelObjectList.Count; i++) { if (context.labelObjectList[i] != null) { - var text = AxisHelper.GetLabelName(this, coordinateWidth, i, minValue, maxValue, dataZoom, forcePercent); + var text = AxisHelper.GetLabelName(this, coordinateWidth, i, context.minValue, context.maxValue, dataZoom, forcePercent); context.labelObjectList[i].SetText(text); } } @@ -740,20 +746,10 @@ namespace XCharts return Vector3.zero; } - internal bool UpdateMinValue(double value, bool check) + internal void UpdateMinMaxValue(double minValue, double maxValue) { - return context.UpdateMinValue(value, check); - } - - internal bool UpdateMaxValue(double value, bool check) - { - return context.UpdateMaxValue(value, check); - } - - internal void UpdateMinMaxValue(double minValue, double maxValue, bool check) - { - UpdateMinValue(minValue, check); - UpdateMaxValue(maxValue, check); + context.minValue = minValue; + context.maxValue = maxValue; double tempRange = maxValue - minValue; if (context.minMaxRange != tempRange) { @@ -765,32 +761,6 @@ namespace XCharts } } - public double GetCurrMinValue(float duration) - { - return context.GetCurrMinValue(duration); - } - - public double GetCurrMaxValue(float duration) - { - return context.GetCurrMaxValue(duration); - } - - public bool IsValueChanging(float duration) - { - if (!Application.isPlaying) - return false; - - if (GetCurrMinValue(duration) != context.minValue - || GetCurrMaxValue(duration) != context.maxValue) - { - return true; - } - else - { - return false; - } - } - public float GetLogValue(double value) { if (value <= 0 || value == 1) diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs b/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs index 6db4d029..b5d2483a 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs @@ -13,36 +13,26 @@ namespace XCharts { public class AxisContext : MainComponentContext { + internal Orient orient { get; set; } + public float x { get; internal set; } + public float y { get; internal set; } + public float width { get; internal set; } + public float height { get; internal set; } + public Vector3 position { get; internal set; } + public float left { get; internal set; } + public float right { get; internal set; } + public float bottom { get; internal set; } + public float top { get; internal set; } /// /// the current minimun value. /// 当前最小值。 /// - public double minValue - { - get { return m_RuntimeMinValue; } - internal set - { - m_RuntimeMinValue = value; - m_RuntimeLastMinValue = value; - m_RuntimeMinValueUpdateTime = Time.time; - m_RuntimeMinValueChanged = true; - } - } + public double minValue { get; internal set; } /// /// the current maximum value. /// 当前最大值。 /// - public double maxValue - { - get { return m_RuntimeMaxValue; } - internal set - { - m_RuntimeMaxValue = value; - m_RuntimeLastMaxValue = value; - m_RuntimeMaxValueUpdateTime = Time.time; - m_RuntimeMaxValueChanged = false; - } - } + public double maxValue { get; internal set; } /// /// the x offset of zero position. /// 坐标轴原点在X轴的偏移。 @@ -70,16 +60,6 @@ namespace XCharts private int filterStart; private int filterEnd; private int filterMinShow; - private double m_RuntimeMinValue; - private double m_RuntimeLastMinValue; - private bool m_RuntimeMinValueChanged; - private float m_RuntimeMinValueUpdateTime; - private double m_RuntimeMaxValue; - private double m_RuntimeLastMaxValue; - private bool m_RuntimeMaxValueChanged; - private float m_RuntimeMaxValueUpdateTime; - private bool m_RuntimeMinValueFirstChanged = true; - private bool m_RuntimeMaxValueFirstChanged = true; private List m_AxisLabelList = new List(); private List m_LabelValueList = new List(); @@ -91,123 +71,6 @@ namespace XCharts m_RuntimeData.Clear(); } - internal bool UpdateMinValue(double value, bool check) - { - if (value != maxValue) - { - if (check && Application.isPlaying) - { - if (m_RuntimeMinValueFirstChanged) - { - m_RuntimeMinValueFirstChanged = false; - } - else - { - m_RuntimeLastMinValue = minValue; - m_RuntimeMinValueChanged = true; - m_RuntimeMinValueUpdateTime = Time.time; - } - minValue = value; - } - else - { - minValue = value; - m_RuntimeLastMinValue = value; - m_RuntimeMinValueUpdateTime = Time.time; - m_RuntimeMinValueChanged = true; - } - return true; - } - else - { - return false; - } - } - - internal bool UpdateMaxValue(double value, bool check) - { - if (value != maxValue) - { - if (check && Application.isPlaying) - { - if (m_RuntimeMaxValueFirstChanged) - { - m_RuntimeMaxValueFirstChanged = false; - } - else - { - m_RuntimeLastMaxValue = maxValue; - m_RuntimeMaxValueChanged = true; - m_RuntimeMaxValueUpdateTime = Time.time; - } - maxValue = value; - } - else - { - maxValue = value; - m_RuntimeLastMaxValue = value; - m_RuntimeMaxValueUpdateTime = Time.time; - m_RuntimeMaxValueChanged = false; - } - - return true; - } - else - { - return false; - } - } - - public double GetCurrMinValue(float duration) - { - if (!Application.isPlaying || !m_RuntimeMinValueChanged) - return minValue; - - if (minValue == 0 && maxValue == 0) - return 0; - - var time = Time.time - m_RuntimeMinValueUpdateTime; - if (time == 0) - return minValue; - - var total = duration / 1000; - if (duration > 0 && time <= total) - { - var curr = MathUtil.Lerp(m_RuntimeLastMinValue, minValue, time / total); - return curr; - } - else - { - m_RuntimeMinValueChanged = false; - return minValue; - } - } - - public double GetCurrMaxValue(float duration) - { - if (!Application.isPlaying || !m_RuntimeMaxValueChanged) - return maxValue; - - if (minValue == 0 && maxValue == 0) - return 0; - - var time = Time.time - m_RuntimeMaxValueUpdateTime; - if (time == 0) - return maxValue; - - var total = duration / 1000; - if (duration > 0 && time < total) - { - var curr = MathUtil.Lerp(m_RuntimeLastMaxValue, maxValue, time / total); - return curr; - } - else - { - m_RuntimeMaxValueChanged = false; - return maxValue; - } - } - private List m_EmptyFliter = new List(); /// /// 更新dataZoom对应的类目数据列表 diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs index bf4e922a..5b029c6b 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs @@ -134,8 +134,7 @@ namespace XCharts m_LastInterval = axis.interval; chart.m_IsPlayingAnimation = true; - var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse; - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck); + axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); axis.context.xOffset = 0; axis.context.yOffset = 0; axis.context.lastCheckInverse = axis.inverse; @@ -181,7 +180,7 @@ namespace XCharts } } - if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation) + if ( !chart.m_IsPlayingAnimation) { UpdateAxisLabelText(axis); chart.RefreshChart(); @@ -198,7 +197,7 @@ namespace XCharts var isPercentStack = SeriesHelper.IsPercentStack(chart.series); var dataZoom = chart.GetDataZoomOfAxis(axis); - axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack, 500); + axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack); } internal static void UpdateAxisTickValueList(Axis axis) diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs b/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs index 01753289..2e5ad8cd 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AxisTick.cs @@ -68,7 +68,7 @@ namespace XCharts m_Show = true, m_AlignWithLabel = false, m_Inside = false, - m_ShowStartTick = false, + m_ShowStartTick = true, m_ShowEndTick = true }; return tick; diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs index 76f92226..4fa27ce2 100644 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs +++ b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxis.cs @@ -15,12 +15,10 @@ namespace XCharts [ComponentHandler(typeof(ParallelAxisHander), true)] public class ParallelAxis : Axis { - public new ParallelAxisContext context = new ParallelAxisContext(); - public override void SetDefaultValue() { m_Show = true; - m_Type = AxisType.Category; + m_Type = AxisType.Value; m_Min = 0; m_Max = 0; m_SplitNumber = 0; @@ -35,6 +33,6 @@ namespace XCharts iconStyle.show = false; } - + } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisContext.cs b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisContext.cs deleted file mode 100644 index 64213942..00000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisContext.cs +++ /dev/null @@ -1,22 +0,0 @@ -/************************************************/ -/* */ -/* Copyright (c) 2018 - 2021 monitor1394 */ -/* https://github.com/monitor1394 */ -/* */ -/************************************************/ - -using UnityEngine; - -namespace XCharts -{ - public class ParallelAxisContext : AxisContext, IRectContext - { - internal ParallelCoord parallel { get; set; } - internal Orient orient { get; set; } - public float x { get; internal set; } - public float y { get; internal set; } - public float width { get; internal set; } - public float height { get; internal set; } - public Vector3 position { get; internal set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisContext.cs.meta b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisContext.cs.meta deleted file mode 100644 index 428aa2bf..00000000 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b92542e13620d417d819e8573b430dc8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs index 26111b75..602a60c9 100644 --- a/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs +++ b/Assets/XCharts/Runtime/Component/Axis/ParallelAxis/ParallelAxisHander.cs @@ -14,6 +14,8 @@ namespace XCharts internal sealed class ParallelAxisHander : AxisHandler { private Orient m_Orient; + private ParallelCoord m_Parallel; + protected override Orient orient { get { return m_Orient; } } public override void InitComponent() @@ -24,8 +26,6 @@ namespace XCharts public override void Update() { UpdateContext(component); - UpdateAxisMinMaxValue(component.index, component); - //UpdatePointerValue(component); } public override void DrawBase(VertexHelper vh) @@ -43,19 +43,19 @@ namespace XCharts return; m_Orient = parallel.orient; - axis.context.parallel = parallel; + m_Parallel = parallel; var axisCount = chart.GetChartComponentNum(); if (m_Orient == Orient.Horizonal) { - var each = parallel.context.height / (axisCount - 1); + var each = axisCount > 1 ? parallel.context.height / (axisCount - 1) : 0; axis.context.x = parallel.context.x; axis.context.y = parallel.context.y + (axis.index) * each; axis.context.width = parallel.context.width; } else { - var each = parallel.context.width / (axisCount - 1); + var each = axisCount > 1 ? parallel.context.width / (axisCount - 1) : 0; axis.context.x = parallel.context.x + (axis.index) * each; axis.context.y = parallel.context.y; axis.context.width = parallel.context.height; @@ -103,7 +103,7 @@ namespace XCharts protected override Vector3 GetLabelPosition(float scaleWid, int i) { - if (component.context.parallel == null) + if (m_Parallel == null) return Vector3.zero; return GetLabelPosition(i, m_Orient, component, null, @@ -119,7 +119,7 @@ namespace XCharts { if (AxisHelper.NeedShowSplit(axis)) { - if (axis.context.parallel == null) + if (m_Parallel == null) return; var dataZoom = chart.GetDataZoomOfAxis(axis); @@ -137,7 +137,7 @@ namespace XCharts { if (AxisHelper.NeedShowSplit(axis)) { - if (axis.context.parallel == null) + if (m_Parallel == null) return; var dataZoom = chart.GetDataZoomOfAxis(axis); @@ -154,7 +154,7 @@ namespace XCharts { if (axis.show && axis.axisLine.show) { - if (axis.context.parallel == null) + if (m_Parallel == null) return; DrawAxisLine(vh, axis, diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index 84bc9232..bca293dd 100644 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -41,8 +41,7 @@ namespace XCharts if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue) { chart.m_IsPlayingAnimation = true; - var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse; - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck); + axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); axis.context.xOffset = 0; axis.context.yOffset = 0; axis.context.lastCheckInverse = axis.inverse; @@ -53,7 +52,7 @@ namespace XCharts chart.RefreshChart(); } } - if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation) + if (!chart.m_IsPlayingAnimation) { UpdateAxisLabelText(axis); chart.RefreshChart(); @@ -63,7 +62,7 @@ namespace XCharts internal void UpdateAxisLabelText(RadiusAxis axis) { var polar = chart.GetChartComponent(axis.polarIndex); - axis.UpdateLabelText(polar.context.radius, null, false, 500); + axis.UpdateLabelText(polar.context.radius, null, false); } private void InitRadiusAxis(RadiusAxis axis) diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs index 8ee4c648..b9437ba9 100644 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs +++ b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs @@ -26,8 +26,6 @@ namespace XCharts [SerializeField] private float m_Width = 0; [SerializeField] private float m_Height = 50; - public new SingleAxisContext context = new SingleAxisContext(); - /// /// Orientation of the axis. By default, it's 'Horizontal'. You can set it to be 'Vertical' to make a vertical axis. /// 坐标轴朝向。默认为水平朝向。 diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisContext.cs b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisContext.cs deleted file mode 100644 index 31a3e1d8..00000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisContext.cs +++ /dev/null @@ -1,24 +0,0 @@ -/************************************************/ -/* */ -/* Copyright (c) 2018 - 2021 monitor1394 */ -/* https://github.com/monitor1394 */ -/* */ -/************************************************/ - -using UnityEngine; - -namespace XCharts -{ - public class SingleAxisContext : AxisContext, IRectContext - { - public float x { get; internal set; } - public float y { get; internal set; } - public float width { get; internal set; } - public float height { get; internal set; } - public Vector3 position { get; internal set; } - public float left { get; internal set; } - public float right { get; internal set; } - public float bottom { get; internal set; } - public float top { get; internal set; } - } -} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisContext.cs.meta b/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisContext.cs.meta deleted file mode 100644 index d2403894..00000000 --- a/Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxisContext.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 435915ad1c7fc41bb8362244d7bae638 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs b/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs index 161e979f..498c1480 100644 --- a/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs +++ b/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs @@ -555,6 +555,10 @@ namespace XCharts public float GetCurrDetail() { +#if UNITY_EDITOR + if (!Application.isPlaying) + return m_DestDetailProgress; +#endif return m_CurrDetailProgress; } diff --git a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs b/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs index 06a297b5..debc6a27 100644 --- a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs +++ b/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs @@ -6,7 +6,6 @@ /************************************************/ using UnityEngine; -using UnityEngine.UI; using System; using System.Collections.Generic; using System.Text; @@ -73,7 +72,7 @@ namespace XCharts s_Sb.Length = 0; s_Sb.AppendFormat("fps : {0:f0} / {1:f0}\n", fps, avgFps); s_Sb.AppendFormat("data : {0}\n", m_Chart.GetAllSerieDataCount()); - s_Sb.AppendFormat("refresh : {0}", refreshCount); + s_Sb.AppendFormat("draw : {0}", refreshCount); m_Label.SetText(s_Sb.ToString()); } } diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs index 248a878a..0007b0b2 100644 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs +++ b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs @@ -132,13 +132,26 @@ namespace XCharts for (int i = 0; i < component.context.parallelAxes.Count; i++) { var axis = component.context.parallelAxes[i]; - var tempMinValue = m_SerieDimMin[i]; - var tempMaxValue = m_SerieDimMax[i]; - AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); - m_SerieDimMin[i] = tempMinValue; - m_SerieDimMax[i] = tempMaxValue; - } + if (axis.IsCategory()) + { + m_SerieDimMax[i] = axis.data.Count > 0 ? axis.data.Count - 1 : 0; + m_SerieDimMin[i] = 0; + } + else if (axis.minMaxType == Axis.AxisMinMaxType.Custom) + { + m_SerieDimMin[i] = axis.min; + m_SerieDimMax[i] = axis.max; + } + else if (m_SerieDimMax.ContainsKey(i)) + { + var tempMinValue = m_SerieDimMin[i]; + var tempMaxValue = m_SerieDimMax[i]; + AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); + m_SerieDimMin[i] = tempMinValue; + m_SerieDimMax[i] = tempMaxValue; + } + } for (int i = 0; i < component.context.parallelAxes.Count; i++) { if (m_SerieDimMax.ContainsKey(i)) @@ -156,8 +169,7 @@ namespace XCharts m_LastInterval = axis.interval; chart.m_IsPlayingAnimation = true; - var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse; - axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck); + axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); axis.context.xOffset = 0; axis.context.yOffset = 0; axis.context.lastCheckInverse = axis.inverse; diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.cs b/Assets/XCharts/Runtime/Internal/BaseChart.cs index 3e8bf74f..93d4f045 100644 --- a/Assets/XCharts/Runtime/Internal/BaseChart.cs +++ b/Assets/XCharts/Runtime/Internal/BaseChart.cs @@ -138,7 +138,11 @@ namespace XCharts GetChartComponent().text = GetType().Name; - m_Theme.sharedTheme.CopyTheme(ThemeType.Default); + if (m_Theme.sharedTheme != null) + m_Theme.sharedTheme.CopyTheme(ThemeType.Default); + else + m_Theme.sharedTheme = XCThemeMgr.GetTheme(ThemeType.Default); + m_Settings = null; var sizeDelta = rectTransform.sizeDelta; if (sizeDelta.x < 580 && sizeDelta.y < 300) diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs index 66c37140..c1f569a2 100644 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs +++ b/Assets/XCharts/Runtime/Internal/Utilities/ChartHelper.cs @@ -498,100 +498,6 @@ namespace XCharts posList.Add(ep); } - public static void GetBezierList(ref List<Vector3> posList, Vector3 sp, Vector3 ep, - Vector3 lsp, Vector3 nep, float smoothness = 2f, float k = 2.0f) - { - float dist = Mathf.Abs(sp.x - ep.x); - Vector3 cp1, cp2; - var dir = (ep - sp).normalized; - var diff = dist / k; - if (lsp == sp) - { - cp1 = sp + dist / k * dir * 1; - cp1.y = sp.y; - cp1 = sp; - } - else - { - cp1 = sp + (ep - lsp).normalized * diff; - } - if (nep == ep) cp2 = ep; - else cp2 = ep - (nep - sp).normalized * diff; - dist = Vector3.Distance(sp, ep); - int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness)); - if (segment < 1) segment = (int)(dist / 0.5f); - if (segment < 4) segment = 4; - GetBezierList2(ref posList, sp, ep, segment, cp1, cp2); - if (posList.Count < 2) - { - posList.Clear(); - posList.Add(sp); - posList.Add(ep); - } - } - - public static void GetBezierListVertical(ref List<Vector3> posList, Vector3 sp, Vector3 ep, - float smoothness = 2f, float k = 2.0f) - { - Vector3 dir = (ep - sp).normalized; - float dist = Vector3.Distance(sp, ep); - Vector3 cp1 = sp + dist / k * dir * 1; - Vector3 cp2 = sp + dist / k * dir * (k - 1); - cp1.x = sp.x; - cp2.x = ep.x; - int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness)); - GetBezierList2(ref posList, sp, ep, segment, cp1, cp2); - if (posList.Count < 2) - { - posList.Clear(); - posList.Add(sp); - posList.Add(ep); - } - } - - public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp) - { - List<Vector3> list = new List<Vector3>(); - for (int i = 0; i < segment; i++) - { - list.Add(GetBezier(i / (float)segment, sp, cp, ep)); - } - list.Add(ep); - return list; - } - - public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, int segment, Vector3 cp, - Vector3 cp2) - { - posList.Clear(); - if (posList.Capacity < segment + 1) - { - posList.Capacity = segment + 1; - } - for (int i = 0; i < segment; i++) - { - posList.Add((GetBezier2(i / (float)segment, sp, cp, cp2, ep))); - } - posList.Add(ep); - } - - public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep) - { - Vector3 aa = sp + (cp - sp) * t; - Vector3 bb = cp + (ep - cp) * t; - return aa + (bb - aa) * t; - } - - public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep) - { - t = Mathf.Clamp01(t); - var oneMinusT = 1f - t; - return oneMinusT * oneMinusT * oneMinusT * sp + - 3f * oneMinusT * oneMinusT * t * p1 + - 3f * oneMinusT * t * t * p2 + - t * t * t * ep; - } - public static bool IsValueEqualsColor(Color32 color1, Color32 color2) { return color1.a == color2.a && @@ -896,70 +802,7 @@ namespace XCharts } - //获取两直线交点 - public static Vector3 GetIntersection(Vector3 lineAStart, Vector3 lineAEnd, Vector3 lineBStart, - Vector3 lineBEnd) - { - float x1 = lineAStart.x, y1 = lineAStart.y; - float x2 = lineAEnd.x, y2 = lineAEnd.y; - float x3 = lineBStart.x, y3 = lineBStart.y; - float x4 = lineBEnd.x, y4 = lineBEnd.y; - if (x1 == x2 && x3 == x4 && x1 == x3) - { - return Vector3.zero; - } - if (y1 == y2 && y3 == y4 && y1 == y3) - { - return Vector3.zero; - } - if (x1 == x2 && x3 == x4) - { - return Vector3.zero; - } - if (y1 == y2 && y3 == y4) - { - return Vector3.zero; - } - float x, y; - if (x1 == x2) - { - float m2 = (y4 - y3) / (x4 - x3); - float c2 = -m2 * x3 + y3; - x = x1; - y = c2 + m2 * x1; - } - else if (x3 == x4) - { - float m1 = (y2 - y1) / (x2 - x1); - float c1 = -m1 * x1 + y1; - x = x3; - y = c1 + m1 * x3; - } - else - { - float m1 = (y2 - y1) / (x2 - x1); - float c1 = -m1 * x1 + y1; - float m2 = (y4 - y3) / (x4 - x3); - float c2 = -m2 * x3 + y3; - x = (c1 - c2) / (m2 - m1); - y = c2 + m2 * x; - } - - if (IsInsideLine(lineAStart, lineAEnd, x, y) && - IsInsideLine(lineBStart, lineBEnd, x, y)) - { - return new Vector3(x, y, 0); - } - return Vector3.zero; - } - - private static bool IsInsideLine(Vector3 start, Vector3 end, float x, float y) - { - return ((x >= start.x && x <= end.x) - || (x >= end.x && x <= start.x)) - && ((y >= start.y && y <= end.y) - || (y >= end.y && y <= start.y)); - } + public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle) { diff --git a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs b/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs index ae7e6cd4..3b93c2bd 100644 --- a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs @@ -124,8 +124,8 @@ namespace XCharts var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series, serie.stack); bool dataChanging = false; float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration); - double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration); + double xMinValue = xAxis.context.minValue; + double xMaxValue = xAxis.context.maxValue; var isAllBarEnd = true; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; @@ -266,10 +266,10 @@ namespace XCharts var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series, serie.stack); bool dataChanging = false; float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration); - double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration); - double yMinValue = yAxis.GetCurrMinValue(dataChangeDuration); - double yMaxValue = yAxis.GetCurrMaxValue(dataChangeDuration); + double xMinValue = xAxis.context.minValue; + double xMaxValue = xAxis.context.maxValue; + double yMinValue = yAxis.context.minValue; + double yMaxValue = yAxis.context.maxValue; var isAllBarEnd = true; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs index 30d81b2c..72d857cd 100644 --- a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs @@ -42,8 +42,8 @@ namespace XCharts bool dataChanging = false; float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double yMinValue = yAxis.GetCurrMinValue(dataChangeDuration); - double yMaxValue = yAxis.GetCurrMaxValue(dataChangeDuration); + double yMinValue = yAxis.context.minValue; + double yMaxValue = yAxis.context.maxValue; var isAllBarEnd = true; var isYAxis = false; serie.containerIndex = grid.index; diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs index d862b037..9623488f 100644 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -562,10 +562,10 @@ namespace XCharts return 0; } float xDataHig, yDataHig; - double xMinValue = xAxis.GetCurrMinValue(duration); - double xMaxValue = xAxis.GetCurrMaxValue(duration); - double yMinValue = yAxis.GetCurrMinValue(duration); - double yMaxValue = yAxis.GetCurrMaxValue(duration); + double xMinValue = xAxis.context.minValue; + double xMaxValue = xAxis.context.maxValue; + double yMinValue = yAxis.context.minValue; + double yMaxValue = yAxis.context.maxValue; if (xAxis.IsValue() || xAxis.IsLog() || xAxis.IsTime()) { var axisLineWidth = xAxis.axisLine.GetWidth(chart.theme.axis.lineWidth); @@ -690,8 +690,8 @@ namespace XCharts var rate = LineHelper.GetDataAverageRate(serie, grid, maxCount, true); var dataChanging = false; float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration); - double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration); + double xMinValue = xAxis.context.minValue; + double xMaxValue = xAxis.context.maxValue; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; @@ -1171,7 +1171,8 @@ namespace XCharts var eindex = 0; var sp = LineHelper.GetStartPos(points, ref sindex, serie.ignoreLineBreak); var ep = LineHelper.GetEndPos(points, ref eindex, serie.ignoreLineBreak); - var cross = ChartHelper.GetIntersection(lp, np, zeroPos, aep); + var cross = Vector3.zero; + UGLHelper.GetIntersection(lp, np, zeroPos, aep, ref cross); if (cross == Vector3.zero || smoothDownPoints.Count <= 3) { @@ -1194,13 +1195,15 @@ namespace XCharts var axisUpEnd = axisUpStart + (isYAxis ? Vector3.up * grid.context.height : Vector3.right * grid.context.width); var axisDownStart = zeroPos - (isYAxis ? Vector3.right : Vector3.up) * axisLineWidth; var axisDownEnd = axisDownStart + (isYAxis ? Vector3.up * grid.context.height : Vector3.right * grid.context.width); - var luPos = ChartHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd); + var luPos = Vector3.zero; + UGLHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd, ref cross); var ecount = smoothPoints.Count - 2; if (ecount < 0) ecount = 0; sp1 = smoothPoints[0]; ep1 = smoothPoints[ecount]; - var rdPos = ChartHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd); + var rdPos = Vector3.zero; + UGLHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd, ref rdPos); if ((isYAxis && lp.x >= zeroPos.x) || (!isYAxis && lp.y >= zeroPos.y)) { @@ -1471,9 +1474,9 @@ namespace XCharts } if (isYAxis) - ChartHelper.GetBezierListVertical(ref bezierPoints, lp, np, settings.lineSmoothness, settings.lineSmoothStyle); + UGLHelper.GetBezierListVertical(ref bezierPoints, lp, np, settings.lineSmoothness, settings.lineSmoothStyle); else - ChartHelper.GetBezierList(ref bezierPoints, lp, np, llp, nnp, settings.lineSmoothness, settings.lineSmoothStyle); + UGLHelper.GetBezierList(ref bezierPoints, lp, np, llp, nnp, settings.lineSmoothness, settings.lineSmoothStyle); Vector3 start, to; if (serie.lineType == LineType.SmoothDash) diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs index 51413522..1d0c842a 100644 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ b/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs @@ -34,9 +34,8 @@ namespace XCharts var startAngle = m_AngleAxis.startAngle; var radius = m_Polar.context.radius; - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var min = m_RadiusAxis.GetCurrMinValue(dataChangeDuration); - var max = m_RadiusAxis.GetCurrMaxValue(dataChangeDuration); + var min = m_RadiusAxis.context.minValue; + var max = m_RadiusAxis.context.maxValue; var firstSerieData = datas[0]; var startPos = GetPolarPos(m_Polar, m_AngleAxis, firstSerieData, min, max, radius); var nextPos = Vector3.zero; diff --git a/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs b/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs index a9e50c52..0e83660f 100644 --- a/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs +++ b/Assets/XCharts/Runtime/Serie/Parallel/Parallel.cs @@ -5,6 +5,7 @@ /* */ /************************************************/ +using System.Collections.Generic; using UnityEngine; namespace XCharts @@ -19,13 +20,20 @@ namespace XCharts public static void AddDefaultSerie(BaseChart chart, string serieName) { var serie = chart.AddSerie<Parallel>(serieName); - serie.itemStyle.show = true; - serie.itemStyle.borderWidth = 1; - serie.itemStyle.borderColor = Color.clear; - serie.emphasis.show = true; - serie.emphasis.itemStyle.show = true; - serie.emphasis.itemStyle.borderWidth = 1; - serie.emphasis.itemStyle.borderColor = Color.black; + serie.lineStyle.width = 0.8f; + serie.lineStyle.opacity = 0.6f; + + for (int i = 0; i < 100; i++) + { + var data = new List<double>(){ + Random.Range(0f,50f), + Random.Range(0f,100f), + Random.Range(0f,1000f), + Random.Range(0,5), + }; + serie.AddData(data, "data" + i); + } + chart.RefreshChart(); } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs b/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs index 5b01d0cd..793bc192 100644 --- a/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Parallel/ParallelHandler.cs @@ -5,6 +5,7 @@ /* */ /************************************************/ +using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using XUGL; @@ -14,6 +15,8 @@ namespace XCharts [UnityEngine.Scripting.Preserve] internal sealed class ParallelHandler : SerieHandler<Parallel> { + private List<Vector3> m_Points = new List<Vector3>(); + public override void Update() { base.Update(); @@ -28,36 +31,11 @@ namespace XCharts private void UpdateSerieContext() { - if (!chart.isPointerInChart) - return; - - var themeSymbolSize = chart.theme.serie.lineSymbolSize; - - serie.context.pointerItemDataIndex = -1; - serie.context.pointerEnter = false; - - foreach (var serieData in serie.data) - { - var dist = Vector3.Distance(chart.pointerPos, serieData.runtimePosition); - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize); - - if (dist <= symbolSize) - { - serie.context.pointerItemDataIndex = serieData.index; - serie.context.pointerEnter = true; - serieData.highlighted = true; - chart.RefreshTopPainter(); - } - else - { - serieData.highlighted = false; - } - } } private void DrawParallelSerie(VertexHelper vh, int colorIndex, Parallel serie) { + if (!serie.show) return; if (serie.animation.HasFadeOut()) return; var parallel = chart.GetChartComponent<ParallelCoord>(serie.parallelIndex); @@ -69,40 +47,90 @@ namespace XCharts return; var animationIndex = serie.animation.GetCurrIndex(); - var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - var dataChanging = false; var isHorizonal = parallel.orient == Orient.Horizonal; var lineColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false); var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - float currDetailProgress = parallel.context.x; - float totalDetailProgress = parallel.context.x + parallel.context.width; - if (serie.animation.alongWithLinePath) - { - //TODO: - } - serie.animation.InitProgress(0, currDetailProgress, totalDetailProgress); + float currDetailProgress = !isHorizonal + ? parallel.context.x + : parallel.context.y; + + float totalDetailProgress = !isHorizonal + ? parallel.context.x + parallel.context.width + : parallel.context.y + parallel.context.height; + + serie.animation.InitProgress(serie.showDataDimension, currDetailProgress, totalDetailProgress); serie.animation.SetDataFinish(0); serie.dataPoints.Clear(); serie.containerIndex = parallel.index; serie.containterInstanceId = parallel.instanceId; - Vector3 sp, np; + var currProgress = serie.animation.GetCurrDetail(); + var isSmooth = serie.lineType == LineType.Smooth; foreach (var serieData in serie.data) { - sp = GetPos(parallel, 0, serieData.data[0], isHorizonal); + m_Points.Clear(); var count = Mathf.Min(axisCount, serieData.data.Count); - for (int i = 1; i < count; i++) + var lp = Vector3.zero; + for (int i = 0; i < count; i++) { - np = GetPos(parallel, i, serieData.data[i], isHorizonal); - UGL.DrawLine(vh, sp, np, lineWidth, lineColor); - sp = np; + if (animationIndex >= 0 && i > animationIndex) continue; + var pos = GetPos(parallel, i, serieData.data[i], isHorizonal); + if (!isHorizonal) + { + if (isSmooth) + { + m_Points.Add(pos); + } + else if (pos.x <= currProgress) + { + m_Points.Add(pos); + serie.animation.SetDataFinish(i); + } + else + { + var currProgressStart = new Vector3(currProgress, parallel.context.y - 50); + var currProgressEnd = new Vector3(currProgress, parallel.context.y + parallel.context.height + 50); + var intersectionPos = Vector3.zero; + + if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) + m_Points.Add(intersectionPos); + else + m_Points.Add(pos); + break; + } + } + else + { + if (isSmooth) + { + m_Points.Add(pos); + } + else if (pos.y <= currProgress) + { + m_Points.Add(pos); + serie.animation.SetDataFinish(i); + } + else + { + var currProgressStart = new Vector3(parallel.context.x - 50, currProgress); + var currProgressEnd = new Vector3(parallel.context.x + parallel.context.width + 50, currProgress); + var intersectionPos = Vector3.zero; + + if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) + m_Points.Add(intersectionPos); + else + m_Points.Add(pos); + break; + } + } + lp = pos; } - } - if (dataChanging) - { - chart.RefreshPainter(serie); + if (isSmooth) + UGL.DrawCurves(vh, m_Points, lineWidth, lineColor, chart.settings.lineSmoothness, currProgress, isHorizonal); + else + UGL.DrawLine(vh, m_Points, lineWidth, lineColor, isSmooth); } if (!serie.animation.IsFinish()) { diff --git a/Assets/XCharts/Runtime/XUGL/UGL.cs b/Assets/XCharts/Runtime/XUGL/UGL.cs index 3c56c108..a9d05de8 100644 --- a/Assets/XCharts/Runtime/XUGL/UGL.cs +++ b/Assets/XCharts/Runtime/XUGL/UGL.cs @@ -126,6 +126,48 @@ namespace XUGL DrawTriangle(vh, dnPos, upPos1, upPos2, color); } } + + public static void DrawLine(VertexHelper vh, List<Vector3> points, float width, Color32 color, bool smooth) + { + if (points.Count < 2) return; + else if (points.Count <= 2) + { + DrawLine(vh, points[0], points[1], width, color); + } + else if (smooth) + { + DrawCurves(vh, points, width, color, 2); + } + else + { + var lineLT = Vector3.zero; + var lineLB = Vector3.zero; + var ltp = Vector3.zero; + var lbp = Vector3.zero; + var ntp = Vector3.zero; + var nbp = Vector3.zero; + var itp = Vector3.zero; + var ibp = Vector3.zero; + for (int i = 1; i < points.Count - 1; i++) + { + UGLHelper.GetLinePoints(points[i - 1], points[i], points[i + 1], width, + ref ltp, ref lbp, ref ntp, ref nbp, ref itp, ref ibp); + + if (i == 1) + { + lineLT = ltp; + lineLB = lbp; + } + + DrawQuadrilateral(vh, lineLB, ibp, itp, lineLT, color); + + lineLT = itp; + lineLB = ibp; + } + DrawQuadrilateral(vh, lineLB, nbp, ntp, lineLT, color); + } + } + /// <summary> /// Draw a dash line. 画虚线 /// </summary> @@ -1619,17 +1661,58 @@ namespace XUGL var dist = Vector3.Distance(sp, ep); var segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness)); UGLHelper.GetBezierList2(ref s_CurvesPosList, sp, ep, segment, cp1, cp2); - if (s_CurvesPosList.Count > 1) + DrawCurvesInternal(vh, s_CurvesPosList, lineWidth, lineColor); + } + + public static void DrawCurves(VertexHelper vh, List<Vector3> points, float width, Color32 color, + float smoothness, float currProgress = float.PositiveInfinity, bool isYAxis = false) + { + for (int i = 0; i < points.Count - 1; i++) { - var start = s_CurvesPosList[0]; + var sp = points[i]; + var ep = points[i + 1]; + var lsp = i > 0 ? points[i - 1] : sp; + var nep = i < points.Count - 2 ? points[i + 2] : ep; + if (currProgress != float.PositiveInfinity) + { + var smoothness2 = 0f; + if (isYAxis) + smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f; + else + smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f; + + UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2); + } + else + { + UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness); + } + DrawCurvesInternal(vh, s_CurvesPosList, width, color, currProgress, isYAxis); + } + } + + private static void DrawCurvesInternal(VertexHelper vh, List<Vector3> curvesPosList, float lineWidth, + Color32 lineColor, float currProgress = float.PositiveInfinity, bool isYAxis = false) + { + if (curvesPosList.Count > 1) + { + var start = curvesPosList[0]; var to = Vector3.zero; - var dir = s_CurvesPosList[1] - start; + var dir = curvesPosList[1] - start; var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth; var startUp = start - diff; var startDn = start + diff; - for (int i = 1; i < s_CurvesPosList.Count; i++) + for (int i = 1; i < curvesPosList.Count; i++) { - to = s_CurvesPosList[i]; + to = curvesPosList[i]; + if (currProgress != float.PositiveInfinity) + { + if (isYAxis && to.y > currProgress) + break; + if (!isYAxis && to.x > currProgress) + break; + } + diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth; var toUp = to - diff; var toDn = to + diff; diff --git a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs b/Assets/XCharts/Runtime/XUGL/UGLHelper.cs index 49be2332..3cb96ca3 100644 --- a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs +++ b/Assets/XCharts/Runtime/XUGL/UGLHelper.cs @@ -14,53 +14,66 @@ namespace XUGL { public static bool IsValueEqualsColor(Color32 color1, Color32 color2) { - return color1.a == color2.a && - color1.b == color2.b && - color1.g == color2.g && - color1.r == color2.r; + return color1.a == color2.a + && color1.b == color2.b + && color1.g == color2.g + && color1.r == color2.r; } public static bool IsValueEqualsColor(Color color1, Color color2) { - return color1.a == color2.a && - color1.b == color2.b && - color1.g == color2.g && - color1.r == color2.r; + return color1.a == color2.a + && color1.b == color2.b + && color1.g == color2.g + && color1.r == color2.r; } public static bool IsValueEqualsString(string str1, string str2) { - if (str1 == null && str2 == null) return true; - else if (str1 != null && str2 != null) return str1.Equals(str2); + if (str1 == null && str2 == null) + return true; + else if (str1 != null && str2 != null) + return str1.Equals(str2); else return false; } public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2) { - return v1.x == v2.x && v1.y == v2.y; + return v1.x == v2.x + && v1.y == v2.y; } public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2) { - return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z; + return v1.x == v2.x + && v1.y == v2.y + && v1.z == v2.z; } public static bool IsValueEqualsList<T>(List<T> list1, List<T> list2) { - if (list1 == null || list2 == null) return false; - if (list1.Count != list2.Count) return false; + if (list1 == null || list2 == null) + return false; + + if (list1.Count != list2.Count) + return false; + for (int i = 0; i < list1.Count; i++) { - if (list1[i] == null && list2[i] == null) { } + if (list1[i] == null && list2[i] == null) + { + } else { if (list1[i] != null) { - if (!list1[i].Equals(list2[i])) return false; + if (!list1[i].Equals(list2[i])) + return false; } else { - if (!list2[i].Equals(list1[i])) return false; + if (!list2[i].Equals(list1[i])) + return false; } } } @@ -69,17 +82,25 @@ namespace XUGL public static bool IsClearColor(Color32 color) { - return color.a == 0 && color.b == 0 && color.g == 0 && color.r == 0; + return color.a == 0 + && color.b == 0 + && color.g == 0 + && color.r == 0; } public static bool IsClearColor(Color color) { - return color.a == 0 && color.b == 0 && color.g == 0 && color.r == 0; + return color.a == 0 + && color.b == 0 + && color.g == 0 + && color.r == 0; } public static bool IsZeroVector(Vector3 pos) { - return pos.x == 0 && pos.y == 0 && pos.z == 0; + return pos.x == 0 + && pos.y == 0 + && pos.z == 0; } public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle) @@ -113,6 +134,12 @@ namespace XUGL if (segment < 1) segment = (int)(dist / 0.5f); if (segment < 4) segment = 4; GetBezierList2(ref posList, sp, ep, segment, cp1, cp2); + if (posList.Count < 2) + { + posList.Clear(); + posList.Add(sp); + posList.Add(ep); + } } public static void GetBezierListVertical(ref List<Vector3> posList, Vector3 sp, Vector3 ep, @@ -126,6 +153,12 @@ namespace XUGL cp2.x = ep.x; int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness)); GetBezierList2(ref posList, sp, ep, segment, cp1, cp2); + if (posList.Count < 2) + { + posList.Clear(); + posList.Add(sp); + posList.Add(ep); + } } public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp) @@ -139,8 +172,8 @@ namespace XUGL return list; } - public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, int segment, Vector3 cp, - Vector3 cp2) + public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, + int segment, Vector3 cp, Vector3 cp2) { posList.Clear(); if (posList.Capacity < segment + 1) @@ -180,17 +213,12 @@ namespace XUGL public static Vector3 GetVertialDire(Vector3 dire) { if (dire.x == 0) - { return new Vector3(-1, 0, 0); - } + if (dire.y == 0) - { return new Vector3(0, -1, 0); - } else - { return new Vector3(-dire.y / dire.x, 1, 0).normalized; - } } /// <summary> @@ -213,7 +241,77 @@ namespace XUGL public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false) { angle = isDegree ? angle * Mathf.Deg2Rad : angle; - return new Vector3(center.x + radius * Mathf.Sin(angle), center.y + radius * Mathf.Cos(angle)); + return new Vector3(center.x + radius * Mathf.Sin(angle), + center.y + radius * Mathf.Cos(angle)); + } + + /// <summary> + /// 获得两直线的交点 + /// </summary> + /// <param name="p1">线段1起点</param> + /// <param name="p2">线段1终点</param> + /// <param name="p3">线段2起点</param> + /// <param name="p4">线段2终点</param> + /// <param name="intersection">相交点。当不想交时默认为 Vector3.zero </param> + /// <returns>相交则返回 true, 否则返回 false</returns> + public static bool GetIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, ref Vector3 intersection) + { + intersection = Vector3.zero; + + var d = (p2.x - p1.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p4.x - p3.x); + if (d == 0) + return false; + + var u = ((p3.x - p1.x) * (p4.y - p3.y) - (p3.y - p1.y) * (p4.x - p3.x)) / d; + var v = ((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / d; + if (u < 0 || u > 1 || v < 0 || v > 1) + return false; + + intersection.x = p1.x + u * (p2.x - p1.x); + intersection.y = p1.y + u * (p2.y - p1.y); + return true; + } + + /// <summary> + /// 三个点画线段所需要的六个关键点 + /// </summary> + /// <param name="lp">上一个点</param> + /// <param name="cp">当前点</param> + /// <param name="np">下一个点</param> + /// <param name="width">线段宽度</param> + /// <param name="ltp">上一个点的上角点</param> + /// <param name="lbp">上一个点的下角点</param> + /// <param name="ntp">下一个点的上角点</param> + /// <param name="nbp">下一个点的下角点</param> + /// <param name="itp">交汇点的上角点</param> + /// <param name="ibp">交汇点的下角点</param> + internal static void GetLinePoints(Vector3 lp, Vector3 cp, Vector3 np, float width, + ref Vector3 ltp, ref Vector3 lbp, + ref Vector3 ntp, ref Vector3 nbp, + ref Vector3 itp, ref Vector3 ibp) + { + var dir1 = (cp - lp).normalized; + var dir2 = (cp - np).normalized; + var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized; + var dir2v = Vector3.Cross(dir2, Vector3.back).normalized; + + ltp = lp + dir1v * width; + lbp = lp - dir1v * width; + + ntp = np + dir2v * width; + nbp = np - dir2v * width; + + var ldist = 1.3f * Vector3.Distance(cp, lp) * dir1; + var rdist = 1.3f * Vector3.Distance(cp, np) * dir2; + + if (!UGLHelper.GetIntersection(ltp, ltp + ldist, ntp, ntp + rdist, ref itp)) + { + itp = cp + dir1v * width; + } + if (!UGLHelper.GetIntersection(lbp, lbp + ldist, nbp, nbp + rdist, ref ibp)) + { + ibp = cp - dir1v * width; + } } } } \ No newline at end of file