From a5469c0996634618586059e04ff5ed4634658441 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Wed, 8 Dec 2021 08:31:32 +0800 Subject: [PATCH] 3.0 - LineChart --- Assets/XCharts/Editor/Series/SerieEditor.cs | 2 +- .../XCharts/Editor/Utilities/EditorStyles.cs | 4 +- .../Examples/Runtime/Example10_LineChart.cs | 8 +- Assets/XCharts/Runtime/Chart/BaseChart_API.cs | 6 +- .../Axis/AngleAxis/AngleAxisHandler.cs | 3 +- .../Runtime/Component/Axis/AxisContext.cs | 11 +- .../Runtime/Component/Axis/AxisHandler.cs | 17 +- .../Runtime/Component/Axis/AxisHelper.cs | 41 +- .../Axis/RadiusAxis/RadiusAxisHandler.cs | 3 +- .../Runtime/Component/Child/SerieAnimation.cs | 34 + .../Runtime/Component/Child/SymbolStyle.cs | 28 +- .../Runtime/Component/Debug/DebugInfo.cs | 62 +- .../Runtime/Component/Mark/MarkLineHandler.cs | 2 +- .../Component/VisualMap/VisualMapHelper.cs | 34 +- .../Coord/Parallel/ParallelCoordHandler.cs | 3 +- .../Runtime/Internal/BaseChart.Draw.cs | 14 +- Assets/XCharts/Runtime/Internal/BaseChart.cs | 6 + .../Runtime/Internal/Utilities/ChartDrawer.cs | 17 +- .../Internal/Utilities/ComponentHelper.cs | 4 +- .../Runtime/Internal/Utilities/DataHelper.cs | 73 +- .../XCharts/Runtime/Serie/Bar/BarHandler.cs | 4 +- .../Serie/Candlestick/CandlestickHandler.cs | 2 +- .../Serie/Line/LineHandler.GridCoord.cs | 1741 +---------------- .../Serie/Line/LineHandler.PolarCoord.cs | 3 +- .../XCharts/Runtime/Serie/Line/LineHelper.cs | 501 ++++- .../Runtime/Serie/Radar/RadarHandler.cs | 9 +- .../Serie/Scatter/BaseScatterHandler.cs | 12 +- Assets/XCharts/Runtime/Serie/Serie.cs | 25 +- Assets/XCharts/Runtime/Serie/SerieContext.cs | 16 + Assets/XCharts/Runtime/Serie/SerieData.cs | 2 +- .../XCharts/Runtime/Serie/SerieDataContext.cs | 4 +- Assets/XCharts/Runtime/XUGL/UGL.cs | 99 +- Assets/XCharts/Runtime/XUGL/UGLHelper.cs | 32 +- ProjectSettings/QualitySettings.asset | 2 +- 34 files changed, 890 insertions(+), 1934 deletions(-) diff --git a/Assets/XCharts/Editor/Series/SerieEditor.cs b/Assets/XCharts/Editor/Series/SerieEditor.cs index a8416ba2..8a0e81b3 100644 --- a/Assets/XCharts/Editor/Series/SerieEditor.cs +++ b/Assets/XCharts/Editor/Series/SerieEditor.cs @@ -205,7 +205,7 @@ namespace XCharts var componentNum = m_IconStyle.arraySize + m_Label.arraySize + m_ItemStyle.arraySize + m_Emphasis.arraySize + m_Symbol.arraySize; var title = "Component"; - if (componentNum == 0) title += " (No Component)"; + if (componentNum == 0) title += " (None)"; m_DataComponentFoldout = ChartEditorHelper.DrawHeader(title, m_DataComponentFoldout, false, null, null, new HeaderMenuInfo("Add ItemStyle", () => { diff --git a/Assets/XCharts/Editor/Utilities/EditorStyles.cs b/Assets/XCharts/Editor/Utilities/EditorStyles.cs index a63f6d2a..80d348ca 100644 --- a/Assets/XCharts/Editor/Utilities/EditorStyles.cs +++ b/Assets/XCharts/Editor/Utilities/EditorStyles.cs @@ -7,8 +7,8 @@ namespace XCharts { public class EditorCustomStyles { - static readonly Color splitterDark = new Color(0.12f, 0.12f, 0.12f, 0.3f); - static readonly Color splitterLight = new Color(0.6f, 0.6f, 0.6f, 0.3f); + static readonly Color splitterDark = new Color(0.12f, 0.12f, 0.12f, 0.5f); + static readonly Color splitterLight = new Color(0.6f, 0.6f, 0.6f, 0.5f); static readonly Texture2D paneOptionsIconDark = (Texture2D)EditorGUIUtility.Load("Builtin Skins/DarkSkin/Images/pane options.png"); static readonly Texture2D paneOptionsIconLight = (Texture2D)EditorGUIUtility.Load("Builtin Skins/LightSkin/Images/pane options.png"); static readonly Color headerBackgroundDark = new Color(0.1f, 0.1f, 0.1f, 0.2f); diff --git a/Assets/XCharts/Examples/Runtime/Example10_LineChart.cs b/Assets/XCharts/Examples/Runtime/Example10_LineChart.cs index 2e52bd60..8fa55c9c 100644 --- a/Assets/XCharts/Examples/Runtime/Example10_LineChart.cs +++ b/Assets/XCharts/Examples/Runtime/Example10_LineChart.cs @@ -96,22 +96,22 @@ namespace XCharts.Examples yield return new WaitForSeconds(1); chart.GetChartComponent().subText = "LineTyle - 虚线"; - serie.lineType = LineType.Dash; + serie.lineStyle.type = LineStyle.Type.Dashed; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 点线"; - serie.lineType = LineType.Dot; + serie.lineStyle.type = LineStyle.Type.Dotted; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 点划线"; - serie.lineType = LineType.DashDot; + serie.lineStyle.type = LineStyle.Type.DashDot; chart.RefreshChart(); yield return new WaitForSeconds(1); chart.GetChartComponent<Title>().subText = "LineTyle - 双点划线"; - serie.lineType = LineType.DashDotDot; + serie.lineStyle.type = LineStyle.Type.DashDotDot; chart.RefreshChart(); serie.lineType = LineType.Normal; diff --git a/Assets/XCharts/Runtime/Chart/BaseChart_API.cs b/Assets/XCharts/Runtime/Chart/BaseChart_API.cs index 44d6c218..cac45a9c 100644 --- a/Assets/XCharts/Runtime/Chart/BaseChart_API.cs +++ b/Assets/XCharts/Runtime/Chart/BaseChart_API.cs @@ -400,10 +400,8 @@ namespace XCharts var tempX = xAxis.Clone(); xAxis.Copy(yAxis); yAxis.Copy(tempX); - xAxis.context.xOffset = 0; - xAxis.context.yOffset = 0; - yAxis.context.xOffset = 0; - yAxis.context.yOffset = 0; + xAxis.context.offset = 0; + yAxis.context.offset = 0; xAxis.context.minValue = 0; xAxis.context.maxValue = 0; yAxis.context.minValue = 0; diff --git a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs index 5232a888..b81f25c9 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxisHandler.cs @@ -43,8 +43,7 @@ namespace XCharts { chart.m_IsPlayingAnimation = true; axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.xOffset = 0; - axis.context.yOffset = 0; + axis.context.offset = 0; axis.context.lastCheckInverse = axis.inverse; if (updateChart) { diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs b/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs index b5d2483a..bf4d9532 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AxisContext.cs @@ -34,15 +34,10 @@ namespace XCharts /// </summary> public double maxValue { get; internal set; } /// <summary> - /// the x offset of zero position. - /// 坐标轴原点在X轴的偏移。 + /// the offset of zero position. + /// 坐标轴原点在坐标轴的偏移。 /// </summary> - public float xOffset { get; internal set; } - /// <summary> - /// the y offset of zero position. - /// 坐标轴原点在Y轴的偏移。 - /// </summary> - public float yOffset { get; internal set; } + public float offset { get; internal set; } public double minMaxRange { get; internal set; } public float scaleWidth { get; internal set; } public float startAngle { get; set; } diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs index 5b029c6b..b200ef4a 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs @@ -84,7 +84,7 @@ namespace XCharts { var yRate = axis.context.minMaxRange / grid.context.height; - var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.yOffset); + var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.offset); if (axis.context.minValue > 0) yValue += axis.context.minValue; @@ -96,7 +96,7 @@ namespace XCharts { var xRate = axis.context.minMaxRange / grid.context.width; - var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.xOffset); + var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.offset); if (axis.context.minValue > 0) xValue += axis.context.minValue; @@ -135,8 +135,7 @@ namespace XCharts chart.m_IsPlayingAnimation = true; axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.xOffset = 0; - axis.context.yOffset = 0; + axis.context.offset = 0; axis.context.lastCheckInverse = axis.inverse; UpdateAxisTickValueList(axis); @@ -146,7 +145,7 @@ namespace XCharts var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); if (grid != null && axis is XAxis && axis.IsValue()) { - axis.context.xOffset = axis.context.minValue > 0 + axis.context.offset = axis.context.minValue > 0 ? 0 : (axis.context.maxValue < 0 ? grid.context.width @@ -156,7 +155,7 @@ namespace XCharts } if (grid != null && axis is YAxis && axis.IsValue()) { - axis.context.yOffset = axis.context.minValue > 0 + axis.context.offset = axis.context.minValue > 0 ? 0 : (axis.context.maxValue < 0 ? grid.context.height @@ -443,7 +442,7 @@ namespace XCharts var axisNameTextStyle = axis.axisName.textStyle; var offset = axisNameTextStyle.offset; - var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.yOffset); + var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset); var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist); if (orient == Orient.Horizonal) @@ -555,7 +554,7 @@ namespace XCharts if (orient == Orient.Horizonal) { if (axis.axisLabel.onZero && relativedAxis != null) - axisStartY += relativedAxis.context.yOffset; + axisStartY += relativedAxis.context.offset; if (axis.IsTop()) axisStartY += relativedLength; @@ -570,7 +569,7 @@ namespace XCharts else { if (axis.axisLabel.onZero && relativedAxis != null) - axisStartX += relativedAxis.context.yOffset; + axisStartX += relativedAxis.context.offset; if (axis.IsRight()) axisStartX += relativedLength; diff --git a/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs b/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs index 865a21d2..e7620ebc 100644 --- a/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs +++ b/Assets/XCharts/Runtime/Component/Axis/AxisHelper.cs @@ -190,18 +190,21 @@ namespace XCharts if (axis.IsCategory()) { - var data = axis.GetDataList(dataZoom); + var dataCount = axis.GetDataList(dataZoom).Count; var scaleNum = 0; + if (axis.boundaryGap) { - scaleNum = data.Count % splitNum == 0 ? splitNum + 1 : splitNum + 2; + scaleNum = dataCount > 2 && dataCount % splitNum == 0 + ? splitNum + 1 + : splitNum + 2; } else { - if (data.Count < splitNum) - scaleNum = splitNum; - else - scaleNum = data.Count % splitNum == 0 ? splitNum : splitNum + 1; + if (dataCount < splitNum) scaleNum = splitNum; + else scaleNum = dataCount > 2 && dataCount % splitNum == 0 + ? splitNum + : splitNum + 1; } return scaleNum; } @@ -475,5 +478,31 @@ namespace XCharts } } + + public static float GetAxisPosition(GridCoord grid, Axis axis, float scaleWidth, double value) + { + var isY = axis is YAxis; + var gridHeight = isY ? grid.context.height : grid.context.width; + var gridXY = isY ? grid.context.y : grid.context.x; + + if (axis.IsLog()) + { + int minIndex = axis.GetLogMinIndex(); + float nowIndex = axis.GetLogValue(value); + return gridXY + (nowIndex - minIndex) / axis.splitNumber * gridHeight; + } + else if (axis.IsCategory()) + { + var categoryIndex = (int)value; + var categoryStart = gridXY + (axis.boundaryGap ? scaleWidth / 2 : 0); + return categoryStart + scaleWidth * categoryIndex; + } + else + { + var yDataHig = (axis.context.minMaxRange == 0) ? 0f : + (float)((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight); + return gridXY + yDataHig; + } + } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs index bca293dd..c04d3cd7 100644 --- a/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs +++ b/Assets/XCharts/Runtime/Component/Axis/RadiusAxis/RadiusAxisHandler.cs @@ -42,8 +42,7 @@ namespace XCharts { chart.m_IsPlayingAnimation = true; axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.xOffset = 0; - axis.context.yOffset = 0; + axis.context.offset = 0; axis.context.lastCheckInverse = axis.inverse; if (updateChart) diff --git a/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs b/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs index 498c1480..5d9eba0c 100644 --- a/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs +++ b/Assets/XCharts/Runtime/Component/Child/SerieAnimation.cs @@ -127,6 +127,7 @@ namespace XCharts private int m_DestDataProgress { get; set; } [SerializeField] private float m_CurrDetailProgress; [SerializeField] private float m_DestDetailProgress; + [SerializeField] private float m_TotalDetailProgress; private float m_CurrSymbolProgress; private Vector3 m_LinePathLastPos; private float m_LinePathCurrTotalDist = 0f; @@ -254,6 +255,7 @@ namespace XCharts m_IsInit = true; m_DestDataProgress = data; + m_TotalDetailProgress = dest - curr; if (m_FadeOut) { @@ -267,6 +269,33 @@ namespace XCharts } } + public void InitProgress(List<Vector3> paths, bool isY) + { + if (paths.Count < 1) return; + var sp = paths[0]; + var ep = paths[paths.Count - 1]; + var currDetailProgress = isY ? sp.y : sp.x; + var totalDetailProgress = isY ? ep.y : ep.x; + if (m_AlongWithLinePath) + { + currDetailProgress = 0; + totalDetailProgress = 0; + var lp = sp; + for (int i = 1; i < paths.Count; i++) + { + var np = paths[i]; + totalDetailProgress += Vector3.Distance(np, lp); + lp = np; + } + SetLinePathStartPos(sp); + } + else + { + + InitProgress(paths.Count, currDetailProgress, totalDetailProgress); + } + } + public void SetDataFinish(int dataIndex) { if (m_IsEnd) @@ -418,6 +447,11 @@ namespace XCharts return dataIndex <= m_CurrDataProgress; } + internal void CheckProgress() + { + CheckProgress(m_TotalDetailProgress); + } + internal void CheckProgress(double total) { if (IsFinish()) diff --git a/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs b/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs index 8a2d5f77..f5c19a04 100644 --- a/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs +++ b/Assets/XCharts/Runtime/Component/Child/SymbolStyle.cs @@ -18,37 +18,53 @@ namespace XCharts public enum SymbolType { /// <summary> - /// 空心圆。 + /// 不显示标记。 /// </summary> - EmptyCircle, + None, + /// <summary> + /// 自定义标记。 + /// </summary> + Custom, /// <summary> /// 圆形。 /// </summary> Circle, /// <summary> + /// 空心圆。 + /// </summary> + EmptyCircle, + /// <summary> /// 正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。 /// </summary> Rect, /// <summary> + /// 空心正方形。 + /// </summary> + EmptyRect, + /// <summary> /// 三角形。 /// </summary> Triangle, /// <summary> + /// 空心三角形。 + /// </summary> + EmptyTriangle, + /// <summary> /// 菱形。 /// </summary> Diamond, /// <summary> - /// 不显示标记。 + /// 空心菱形。 /// </summary> - None, + EmptyDiamond, /// <summary> /// 箭头。 /// </summary> Arrow, /// <summary> - /// 自定义标记。 + /// 空心箭头。 /// </summary> - Custom + EmptyArrow } /// <summary> diff --git a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs b/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs index debc6a27..f9412d2e 100644 --- a/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs +++ b/Assets/XCharts/Runtime/Component/Debug/DebugInfo.cs @@ -19,8 +19,8 @@ namespace XCharts [SerializeField] private TextStyle m_TextStyle = new TextStyle() { - fontSize = 16, - backgroundColor = new Color32(32, 32, 32, 151), + fontSize = 18, + backgroundColor = new Color32(32, 32, 32, 170), color = Color.white }; @@ -30,6 +30,7 @@ namespace XCharts private static readonly float MAXCACHE = 20; private int m_FrameCount = 0; private float m_LastTime = 0f; + private float m_LastCheckShowTime = 0f; private int m_LastRefreshCount = 0; private BaseChart m_Chart; private ChartLabel m_Label; @@ -39,6 +40,7 @@ namespace XCharts public float fps { get; private set; } public float avgFps { get; private set; } public int refreshCount { get; internal set; } + internal int clickChartCount { get; set; } public void Init(BaseChart chart) { @@ -48,7 +50,22 @@ namespace XCharts public void Update() { - if (!m_Show || m_Label == null) return; + if (clickChartCount >= 2) + { + m_Show = !m_Show; + ChartHelper.SetActive(m_Label.transform, m_Show); + clickChartCount = 0; + m_LastCheckShowTime = Time.realtimeSinceStartup; + return; + } + if (Time.realtimeSinceStartup - m_LastCheckShowTime > 0.5f) + { + m_LastCheckShowTime = Time.realtimeSinceStartup; + clickChartCount = 0; + } + if (!m_Show || m_Label == null) + return; + m_FrameCount++; if (Time.realtimeSinceStartup - m_LastTime >= INTERVAL) { @@ -70,15 +87,37 @@ namespace XCharts if (m_Label != null) { s_Sb.Length = 0; + s_Sb.AppendFormat("v{0}\n", XChartsMgr.version); s_Sb.AppendFormat("fps : {0:f0} / {1:f0}\n", fps, avgFps); - s_Sb.AppendFormat("data : {0}\n", m_Chart.GetAllSerieDataCount()); - s_Sb.AppendFormat("draw : {0}", refreshCount); + s_Sb.AppendFormat("draw : {0}\n", refreshCount); + + var dataCount = m_Chart.GetAllSerieDataCount(); + SetValueWithKInfo(s_Sb, "data", dataCount); + + var vertCount = 0; + foreach (var serie in m_Chart.series) + vertCount += serie.context.vertCount; + + SetValueWithKInfo(s_Sb, "b-vert", m_Chart.m_BasePainterVertCount); + SetValueWithKInfo(s_Sb, "s-vert", vertCount); + SetValueWithKInfo(s_Sb, "t-vert", m_Chart.m_TopPainterVertCount, false); + m_Label.SetText(s_Sb.ToString()); } } } - private float GetAvg(List<float> list) + private static void SetValueWithKInfo(StringBuilder s_Sb, string key, int value, bool newLine = true) + { + if (value >= 1000) + s_Sb.AppendFormat("{0} : {1:f1}k", key, value * 0.001f); + else + s_Sb.AppendFormat("{0} : {1}", key, value); + if (newLine) + s_Sb.Append("\n"); + } + + private static float GetAvg(List<float> list) { var total = 0f; foreach (var v in list) total += v; @@ -94,14 +133,11 @@ namespace XCharts var sizeDelta = new Vector2(100, 100); var labelGameObject = ChartHelper.AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta); - var active = m_Chart.debugModel && m_Show; - ChartHelper.SetActive(labelGameObject, active); - if (!active) - { - return null; - } - var label = ChartHelper.GetOrAddComponent<ChartLabel>(labelGameObject); + labelGameObject.transform.SetAsLastSibling(); labelGameObject.hideFlags = m_Chart.chartHideFlags; + ChartHelper.SetActive(labelGameObject, m_Show); + + var label = ChartHelper.GetOrAddComponent<ChartLabel>(labelGameObject); label.labelBackground = label; label.labelBackground.color = textStyle.backgroundColor; label.labelBackground.raycastTarget = false; diff --git a/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs b/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs index 65d6195f..9872f0c5 100644 --- a/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs +++ b/Assets/XCharts/Runtime/Component/Mark/MarkLineHandler.cs @@ -255,7 +255,7 @@ namespace XCharts var tickness = SerieHelper.GetSymbolBorder(serie, null, theme, false); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, null, false); chart.DrawClipSymbol(vh, symbol.type, symbolSize, tickness, pos, lineColor, lineColor, - symbol.gap, true, cornerRadius, grid, startPos); + ColorUtil.clearColor32, symbol.gap, true, cornerRadius, grid, startPos); } private void GetStartEndPos(Axis xAxis, Axis yAxis, GridCoord grid, double value, ref Vector3 sp, ref Vector3 ep) diff --git a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs index a381e6ea..91692342 100644 --- a/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs +++ b/Assets/XCharts/Runtime/Component/VisualMap/VisualMapHelper.cs @@ -12,13 +12,15 @@ namespace XCharts { public static class VisualMapHelper { - public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, XAxis xAxis, YAxis yAxis) + public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis) { if (!IsNeedGradient(visualMap) || !visualMap.autoMinMax) return; double min = 0; double max = 0; + var xAxis = isY ? relativedAxis : axis; + var yAxis = isY ? axis : relativedAxis; if (visualMap.dimension == 0) { min = xAxis.IsCategory() ? 0 : xAxis.context.minValue; @@ -66,8 +68,8 @@ namespace XCharts } } - public static Color32 GetLineGradientColor(VisualMap visualMap, Vector3 pos, BaseChart chart, Axis axis, - Color32 defaultColor) + public static Color32 GetLineGradientColor(VisualMap visualMap, Vector3 pos, GridCoord grid, Axis axis, + Axis relativedAxis, Color32 defaultColor) { double value = 0; double min = 0; @@ -77,7 +79,6 @@ namespace XCharts { min = axis.context.minValue; max = axis.context.maxValue; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); if (axis.IsCategory() && axis.boundaryGap) { float startX = grid.context.x + axis.context.scaleWidth / 2; @@ -90,25 +91,13 @@ namespace XCharts } else { - Axis yAxis; - if (axis is YAxis) - { - yAxis = chart.GetChartComponent<XAxis>(axis.index); - min = yAxis.context.minValue; - max = yAxis.context.maxValue; - } - else - { - yAxis = chart.GetChartComponent<YAxis>(axis.index); - min = yAxis.context.minValue; - max = yAxis.context.maxValue; - } + min = relativedAxis.context.minValue; + max = relativedAxis.context.maxValue; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - if (yAxis.IsCategory() && yAxis.boundaryGap) + if (relativedAxis.IsCategory() && relativedAxis.boundaryGap) { - float startY = grid.context.y + yAxis.context.scaleWidth / 2; - value = (int)(min + (pos.y - startY) / (grid.context.height - yAxis.context.scaleWidth) * (max - min)); + float startY = grid.context.y + relativedAxis.context.scaleWidth / 2; + value = (int)(min + (pos.y - startY) / (grid.context.height - relativedAxis.context.scaleWidth) * (max - min)); } else { @@ -145,12 +134,11 @@ namespace XCharts return color; } - public static Color32 GetLineStyleGradientColor(LineStyle lineStyle, Vector3 pos, BaseChart chart, + public static Color32 GetLineStyleGradientColor(LineStyle lineStyle, Vector3 pos, GridCoord grid, Axis axis, Color32 defaultColor) { var min = axis.context.minValue; var max = axis.context.maxValue; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); var value = min + (pos.x - grid.context.x) / grid.context.width * (max - min); var rate = (value - min) / (max - min); var color = lineStyle.GetGradientColor((float)rate, defaultColor); diff --git a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs index 0007b0b2..f2789a18 100644 --- a/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs +++ b/Assets/XCharts/Runtime/Coord/Parallel/ParallelCoordHandler.cs @@ -170,8 +170,7 @@ namespace XCharts chart.m_IsPlayingAnimation = true; axis.UpdateMinMaxValue(tempMinValue, tempMaxValue); - axis.context.xOffset = 0; - axis.context.yOffset = 0; + axis.context.offset = 0; axis.context.lastCheckInverse = axis.inverse; AxisHandler<ParallelAxis>.UpdateAxisTickValueList(axis); diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs b/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs index cc848dd9..29951d44 100644 --- a/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs +++ b/Assets/XCharts/Runtime/Internal/BaseChart.Draw.cs @@ -89,12 +89,12 @@ namespace XCharts } public void DrawClipSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness, - Vector3 pos, Color32 color, Color32 toColor, float gap, bool clip, float[] cornerRadius, GridCoord grid, + Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, float gap, bool clip, float[] cornerRadius, GridCoord grid, Vector3 startPos) { if (!IsInChart(pos)) return; if (!clip || (clip && (grid.Contains(pos)))) - DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, cornerRadius, startPos); + DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, emptyColor, gap, cornerRadius, startPos); } public void DrawClipZebraLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, float zebraWidth, @@ -106,18 +106,20 @@ namespace XCharts } public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, - float tickness, Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius) + float tickness, Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, float gap, float[] cornerRadius) { - DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, cornerRadius, Vector3.zero); + DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, emptyColor, gap, cornerRadius, Vector3.zero); } public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, - float tickness, Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius, Vector3 startPos) + float tickness, Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, float gap, float[] cornerRadius, Vector3 startPos) { var backgroundColor = theme.GetBackgroundColor(GetChartComponent<Background>()); + if (ChartHelper.IsClearColor(emptyColor)) + emptyColor = backgroundColor; var smoothness = settings.cicleSmoothness; ChartDrawer.DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, - cornerRadius, backgroundColor, smoothness, startPos); + cornerRadius, emptyColor, backgroundColor, smoothness, startPos); } public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid) diff --git a/Assets/XCharts/Runtime/Internal/BaseChart.cs b/Assets/XCharts/Runtime/Internal/BaseChart.cs index 93d4f045..8ba7167a 100644 --- a/Assets/XCharts/Runtime/Internal/BaseChart.cs +++ b/Assets/XCharts/Runtime/Internal/BaseChart.cs @@ -97,6 +97,8 @@ namespace XCharts internal protected List<string> m_LegendRealShowName = new List<string>(); protected List<Painter> m_PainterList = new List<Painter>(); internal Painter m_PainterTop; + internal int m_BasePainterVertCount; + internal int m_TopPainterVertCount; private ThemeType m_CheckTheme = 0; @@ -430,6 +432,7 @@ namespace XCharts public override void OnPointerClick(PointerEventData eventData) { + m_DebugInfo.clickChartCount++; base.OnPointerClick(eventData); foreach (var handler in m_SerieHandlers) handler.OnPointerClick(eventData); foreach (var handler in m_ComponentHandlers) handler.OnPointerClick(eventData); @@ -556,6 +559,7 @@ namespace XCharts { m_OnCustomDrawBaseCallback(vh); } + m_BasePainterVertCount = vh.currentVertCount; } protected virtual void OnDrawPainterSerie(VertexHelper vh, Painter painter) @@ -585,6 +589,7 @@ namespace XCharts { m_OnCustomDrawSerieAfterCallback(vh, serie); } + serie.context.vertCount = vh.currentVertCount; } } @@ -597,6 +602,7 @@ namespace XCharts { m_OnCustomDrawTopCallback(vh); } + m_TopPainterVertCount = vh.currentVertCount; } protected virtual void DrawPainterSerie(VertexHelper vh, Serie serie) diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs b/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs index 6b8fbc5b..5dc8dd2c 100644 --- a/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs +++ b/Assets/XCharts/Runtime/Internal/Utilities/ChartDrawer.cs @@ -18,7 +18,7 @@ namespace XCharts public static void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness, Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius, - Color32 backgroundColor, float smoothness, Vector3 startPos) + Color32 emptyColor, Color32 backgroundColor, float smoothness, Vector3 startPos) { switch (type) { @@ -38,11 +38,11 @@ namespace XCharts if (gap > 0) { UGL.DrawCricle(vh, pos, symbolSize + gap, backgroundColor, smoothness); - UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, backgroundColor, smoothness); + UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, emptyColor, smoothness); } else { - UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, backgroundColor, smoothness); + UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, emptyColor, smoothness); } break; case SymbolType.Rect: @@ -56,6 +56,17 @@ namespace XCharts UGL.DrawRoundRectangle(vh, pos, symbolSize, symbolSize, color, color, 0, cornerRadius, true); } break; + case SymbolType.EmptyRect: + if (gap > 0) + { + UGL.DrawSquare(vh, pos, symbolSize + gap, backgroundColor); + UGL.DrawBorder(vh, pos, symbolSize / 2, symbolSize / 2, tickness, color); + } + else + { + UGL.DrawBorder(vh, pos, symbolSize / 2, symbolSize / 2, tickness, color); + } + break; case SymbolType.Triangle: if (gap > 0) { diff --git a/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs index a7e22fa7..7a693bff 100644 --- a/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs +++ b/Assets/XCharts/Runtime/Internal/Utilities/ComponentHelper.cs @@ -72,7 +72,7 @@ namespace XCharts if (component is YAxis) { var yAxis = component as YAxis; - if (yAxis.IsValue() && yAxis.gridIndex == axis.gridIndex) return yAxis.context.yOffset; + if (yAxis.IsValue() && yAxis.gridIndex == axis.gridIndex) return yAxis.context.offset; } } return 0; @@ -86,7 +86,7 @@ namespace XCharts if (component is XAxis) { var xAxis = component as XAxis; - if (xAxis.IsValue() && xAxis.gridIndex == axis.gridIndex) return xAxis.context.xOffset; + if (xAxis.IsValue() && xAxis.gridIndex == axis.gridIndex) return xAxis.context.offset; } } return 0; diff --git a/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs b/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs index 94ba7059..74b41dd9 100644 --- a/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs +++ b/Assets/XCharts/Runtime/Internal/Utilities/DataHelper.cs @@ -12,7 +12,8 @@ namespace XCharts { internal static class DataHelper { - public static double DataAverage(ref List<SerieData> showData, SampleType sampleType, int minCount, int maxCount, int rate) + public static double DataAverage(ref List<SerieData> showData, SampleType sampleType, + int minCount, int maxCount, int rate) { double totalAverage = 0; if (rate > 1 && sampleType == SampleType.Peak) @@ -32,13 +33,14 @@ namespace XCharts ref bool dataChanging, Axis axis) { var inverse = axis.inverse; - double minValue = axis.context.minValue; - double MaxValue = axis.context.maxValue; + var minValue = axis.context.minValue; + var maxValue = axis.context.maxValue; if (rate <= 1 || index == minCount) { - if (showData[index].IsDataChanged()) dataChanging = true; - //Debug.LogError("sample:"+index+","+rate+","+(showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue))+","+showData[index].GetData(1)); - return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue); + if (showData[index].IsDataChanged()) + dataChanging = true; + + return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); } switch (sampleType) { @@ -48,49 +50,68 @@ namespace XCharts var count = 0; for (int i = index; i > index - rate; i--) { - count ++; - total += showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue); - if (showData[i].IsDataChanged()) dataChanging = true; + count++; + total += showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); + if (showData[i].IsDataChanged()) + dataChanging = true; } - //Debug.LogError("sample:"+index+","+rate+","+count+","+total); - if (sampleType == SampleType.Average) return total / rate; - else return total; + if (sampleType == SampleType.Average) + return total / rate; + else + return total; + case SampleType.Max: double max = double.MinValue; for (int i = index; i > index - rate; i--) { - var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue); - if (value > max) max = value; - if (showData[i].IsDataChanged()) dataChanging = true; + var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); + if (value > max) + max = value; + + if (showData[i].IsDataChanged()) + dataChanging = true; } return max; + case SampleType.Min: double min = double.MaxValue; for (int i = index; i > index - rate; i--) { - var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue); - if (value < min) min = value; - if (showData[i].IsDataChanged()) dataChanging = true; + var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); + if (value < min) + min = value; + + if (showData[i].IsDataChanged()) + dataChanging = true; } return min; + case SampleType.Peak: max = double.MinValue; min = double.MaxValue; total = 0; for (int i = index; i > index - rate; i--) { - var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue); + var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); total += value; - if (value < min) min = value; - if (value > max) max = value; - if (showData[i].IsDataChanged()) dataChanging = true; + if (value < min) + min = value; + if (value > max) + max = value; + + if (showData[i].IsDataChanged()) + dataChanging = true; } var average = total / rate; - if (average >= totalAverage) return max; - else return min; + if (average >= totalAverage) + return max; + else + return min; } - if (showData[index].IsDataChanged()) dataChanging = true; - return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue); + if (showData[index].IsDataChanged()) + dataChanging = true; + + return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue); } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs b/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs index 3b93c2bd..89b41264 100644 --- a/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Bar/BarHandler.cs @@ -150,7 +150,7 @@ namespace XCharts float pY = grid.context.y + i * categoryWidth; if (!yAxis.boundaryGap) pY -= categoryWidth / 2; - float pX = grid.context.x + xAxis.context.xOffset + axisLineWidth; + float pX = grid.context.x + xAxis.context.offset + axisLineWidth; if (isStack) { for (int n = 0; n < m_StackSerieData.Count - 1; n++) @@ -299,7 +299,7 @@ namespace XCharts { if (!xAxis.boundaryGap) pX -= categoryWidth / 2; } - float zeroY = grid.context.y + yAxis.context.yOffset; + float zeroY = grid.context.y + yAxis.context.offset; float axisLineWidth = value == 0 ? 0 : ((value < 0 ? -1 : 1) * xAxis.axisLine.GetWidth(chart.theme.axis.lineWidth)); float pY = zeroY + axisLineWidth; diff --git a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs b/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs index 72d857cd..3a934393 100644 --- a/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Candlestick/CandlestickHandler.cs @@ -68,7 +68,7 @@ namespace XCharts : itemStyle.runtimeBorderWidth); if (serieData.IsDataChanged()) dataChanging = true; float pX = grid.context.x + i * categoryWidth; - float zeroY = grid.context.y + yAxis.context.yOffset; + float zeroY = grid.context.y + yAxis.context.offset; if (!xAxis.boundaryGap) pX -= categoryWidth / 2; float pY = zeroY; var barHig = 0f; diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs index 9623488f..f76ddefe 100644 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs +++ b/Assets/XCharts/Runtime/Serie/Line/LineHandler.GridCoord.cs @@ -5,7 +5,6 @@ /* */ /************************************************/ -using System; using System.Collections.Generic; using System.Text; using UnityEngine; @@ -95,9 +94,10 @@ namespace XCharts public override void DrawSerie(VertexHelper vh) { var colorIndex = chart.GetLegendRealShowNameIndex(serie.legendName); - var yCategory = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); serie.dataPoints.Clear(); + serie.dataIgnore.Clear(); + serie.context.colorIndex = colorIndex; if (serie.IsUseCoord<PolarCoord>()) { @@ -106,10 +106,7 @@ namespace XCharts } else if (serie.IsUseCoord<GridCoord>()) { - if (yCategory) - DrawYLineSerie(vh, serie, colorIndex); - else - DrawXLineSerie(vh, serie, colorIndex); + DrawLineSerie(vh, serie); if (!SeriesHelper.IsStack(chart.series)) { @@ -205,12 +202,13 @@ namespace XCharts : symbol.GetSize(serie.data[i].data, theme.serie.lineSymbolSize); var symbolColor = SerieHelper.GetItemColor(serie, serieData, theme, serie.index, highlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, theme, serie.index, highlight); + var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, theme, serie.index, highlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); symbolSize = serie.animation.GetSysmbolSize(symbolSize); chart.DrawClipSymbol(vh, symbol.type, symbolSize, symbolBorder, serie.dataPoints[i], - symbolColor, symbolToColor, symbol.gap, clip, cornerRadius, grid, + symbolColor, symbolToColor, symbolEmptyColor, symbol.gap, clip, cornerRadius, grid, i > 0 ? serie.dataPoints[i - 1] : grid.context.position); } } @@ -262,50 +260,51 @@ namespace XCharts } } - private void DrawXLineSerie(VertexHelper vh, Line serie, int colorIndex) + private void DrawLineSerie(VertexHelper vh, Line serie) { - if (!serie.show) return; if (serie.animation.HasFadeOut()) return; - XAxis xAxis; - YAxis yAxis; + var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components); + + Axis axis; + Axis relativedAxis; GridCoord grid; - if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) + if (isY) + { + axis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); + relativedAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); + } + else + { + axis = chart.GetChartComponent<XAxis>(serie.xAxisIndex); + relativedAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex); + } + grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); + + if (axis == null) return; - if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) + if (relativedAxis == null) return; - if (!chart.TryGetChartComponent<GridCoord>(out grid, xAxis.gridIndex)) + if (grid == null) return; var visualMap = chart.GetVisualMapOfSerie(serie); - var tooltip = chart.GetChartComponent<Tooltip>(); - var dataZoom = chart.GetDataZoomOfAxis(xAxis); + var dataZoom = chart.GetDataZoomOfAxis(axis); var showData = serie.GetDataList(dataZoom); if (showData.Count <= 0) return; - var theme = chart.theme; - var highlight = serie.highlighted || serie.context.pointerEnter; + var axisLength = isY ? grid.context.height : grid.context.width; + var scaleWid = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom); - var lineColor = SerieHelper.GetLineColor(serie, theme, colorIndex, highlight); - var srcAreaColor = SerieHelper.GetAreaColor(serie, theme, colorIndex, false); - var srcAreaToColor = SerieHelper.GetAreaToColor(serie, theme, colorIndex, false); - var highlightAreaColor = SerieHelper.GetAreaColor(serie, theme, colorIndex, true); - var highlightAreaToColor = SerieHelper.GetAreaToColor(serie, theme, colorIndex, true); - var zeroPos = new Vector3(grid.context.x, grid.context.y + yAxis.context.yOffset); - var isStack = SeriesHelper.IsStack<Line>(chart.series, serie.stack); - var scaleWid = AxisHelper.GetDataWidth(xAxis, grid.context.width, showData.Count, dataZoom); - var startX = grid.context.x + (xAxis.boundaryGap ? scaleWid / 2 : 0); int maxCount = serie.maxShow > 0 ? (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) : showData.Count; - int i; - var includeLastData = false; int rate = LineHelper.GetDataAverageRate(serie, grid, maxCount, false); var totalAverage = serie.sampleAverage > 0 ? serie.sampleAverage @@ -313,1686 +312,100 @@ namespace XCharts var dataChanging = false; var dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - Color32 areaColor, areaToColor; - Vector3 lp = Vector3.zero, np = Vector3.zero, llp = Vector3.zero, nnp = Vector3.zero; - - xAxis.context.scaleWidth = scaleWid; + axis.context.scaleWidth = scaleWid; serie.containerIndex = grid.index; serie.containterInstanceId = grid.instanceId; + Serie lastSerie = null; + var isStack = SeriesHelper.IsStack<Line>(chart.series, serie.stack); if (isStack) - SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData); - - for (i = serie.minShow; i < maxCount; i += rate) { - if (i == maxCount - 1) - includeLastData = true; + lastSerie = SeriesHelper.GetLastStackSerie(chart.series, serie); + SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData); + } - if (serie.IsIgnoreValue(showData[i])) + for (int i = serie.minShow; i < maxCount; i += rate) + { + var serieData = showData[i]; + var isIgnore = serie.IsIgnoreValue(serieData); + if (isIgnore) { - serie.dataPoints.Add(Vector3.zero); - showData[i].runtimeStackHig = 0; + serieData.runtimeStackHig = 0; + serieData.runtimePosition = Vector3.zero; + if (serie.ignoreLineBreak && serie.dataIgnore.Count > 0) + { + serie.dataIgnore[serie.dataIgnore.Count - 1] = true; + } } else { - double yValue = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, - maxCount, totalAverage, i, dataChangeDuration, ref dataChanging, yAxis); - showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, grid, showData, yValue, startX, i, - scaleWid, isStack, ref np, dataChangeDuration); + var np = Vector3.zero; + var xValue = serieData.GetData(0, axis.inverse); + var relativedValue = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow, + maxCount, totalAverage, i, dataChangeDuration, ref dataChanging, relativedAxis); + + serieData.runtimeStackHig = GetDataPoint(isY, axis, relativedAxis, grid, xValue, relativedValue, + i, scaleWid, isStack, ref np); + + serieData.runtimePosition = np; - showData[i].runtimePosition = np; serie.dataPoints.Add(np); + serie.dataIgnore.Add(false); } } if (dataChanging) - { chart.RefreshPainter(serie); - } - - if (!includeLastData) - { - i = maxCount - 1; - if (serie.IsIgnoreValue(showData[i])) - { - serie.dataPoints.Add(Vector3.zero); - showData[i].runtimeStackHig = 0; - } - else - { - double yValue = showData[i].GetCurrData(1, dataChangeDuration, yAxis.inverse, - yAxis.context.minValue, yAxis.context.maxValue); - - showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, grid, showData, yValue, startX, i, - scaleWid, isStack, ref np, dataChangeDuration); - - showData[i].runtimePosition = np; - serie.dataPoints.Add(np); - } - } if (serie.dataPoints.Count <= 0) - { return; - } - var startIndex = 0; - var endIndex = serie.dataPoints.Count; - var startPos = LineHelper.GetStartPos(serie.dataPoints, ref startIndex, serie.ignoreLineBreak); - var endPos = LineHelper.GetEndPos(serie.dataPoints, ref endIndex, serie.ignoreLineBreak); - var firstLastPos = Vector3.zero; - var lastNextPos = Vector3.zero; + serie.animation.InitProgress(serie.dataPoints, isY); + serie.animation.SetDataFinish(0); - lp = startPos; - stPos1 = stPos2 = lastDir = lastDnPos = Vector3.zero; - smoothStartPosUp = smoothStartPosDn = Vector3.zero; + VisualMapHelper.AutoSetLineMinMax(visualMap, serie, isY, axis, relativedAxis); + LineHelper.UpdateSerieDrawPoints(serie, chart.settings, chart.theme, isY); + LineHelper.DrawSerieLineArea(vh, serie, lastSerie, chart.theme, isY, axis, relativedAxis, grid); + LineHelper.DrawSerieLine(vh, chart.theme, serie, visualMap, grid, axis, relativedAxis); - if (serie.minShow > 0 && serie.minShow < showData.Count) - { - i = serie.minShow - 1; + serie.context.vertCount = vh.currentVertCount; - if (serie.IsIgnoreValue(showData[i])) - { - serie.dataPoints.Add(Vector3.zero); - showData[i].runtimeStackHig = 0; - } - else - { - double yValue = showData[i].GetCurrData(1, dataChangeDuration, yAxis.inverse, - yAxis.context.minValue, yAxis.context.maxValue); - showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, grid, showData, yValue, startX, i, - scaleWid, isStack, ref firstLastPos, dataChangeDuration); - } - } - else - { - firstLastPos = lp; - } - if (serie.maxShow > 0 && serie.maxShow < showData.Count) - { - i = serie.maxShow; - - if (serie.IsIgnoreValue(showData[i])) - { - serie.dataPoints.Add(Vector3.zero); - showData[i].runtimeStackHig = 0; - } - else - { - double yValue = showData[i].GetCurrData(1, dataChangeDuration, yAxis.inverse, - yAxis.context.minValue, yAxis.context.maxValue); - showData[i].runtimeStackHig = GetDataPoint(xAxis, yAxis, grid, showData, yValue, startX, i, - scaleWid, isStack, ref lastNextPos, dataChangeDuration); - } - } - else - { - lastNextPos = endPos; - } - VisualMapHelper.AutoSetLineMinMax(visualMap, serie, xAxis, yAxis); - - float currDetailProgress = lp.x; - float totalDetailProgress = endPos.x; - if (serie.animation.alongWithLinePath) - { - currDetailProgress = 0; - totalDetailProgress = 0; - var tempLp = startPos; - for (i = startIndex + 1; i < serie.dataPoints.Count; i++) - { - np = serie.dataPoints[i]; - if (np != Vector3.zero) - { - totalDetailProgress += Vector3.Distance(np, tempLp); - tempLp = np; - } - } - serie.animation.SetLinePathStartPos(startPos); - } - - serie.animation.InitProgress(serie.dataPoints.Count, currDetailProgress, totalDetailProgress); - serie.animation.SetDataFinish(startIndex); - - - for (i = startIndex + 1; i < serie.dataPoints.Count; i++) - { - np = serie.dataPoints[i]; - serie.ClearSmoothList(i); - var isIgnoreBreak = false; - if (np == Vector3.zero) - { - if (serie.ignoreLineBreak) - isIgnoreBreak = true; - else - { - serie.animation.SetDataFinish(i); - continue; - } - } - if (!serie.animation.NeedAnimation(i)) - break; - - bool isFinish = true; - if (serie.areaStyle.tooltipHighlight && tooltip.show && i <= tooltip.runtimeDataIndex[0]) - { - areaColor = highlightAreaColor; - areaToColor = highlightAreaToColor; - } - else - { - areaColor = srcAreaColor; - areaToColor = srcAreaToColor; - } - switch (serie.lineType) - { - case LineType.Normal: - - lp = LineHelper.GetLastPos(serie.dataPoints, i, np, serie.ignoreLineBreak); - nnp = LineHelper.GetNNPos(serie.dataPoints, i, np, serie.ignoreLineBreak); - if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak = true; - isFinish = DrawNormalLine(vh, serie, xAxis, visualMap, lp, np, nnp, i, - isIgnoreBreak ? ColorUtil.clearColor32 : lineColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor, - zeroPos, startIndex); - - break; - - case LineType.Smooth: - case LineType.SmoothDash: - - llp = LineHelper.GetLLPos(serie.dataPoints, i, firstLastPos, serie.ignoreLineBreak); - nnp = LineHelper.GetNNPos(serie.dataPoints, i, lastNextPos, serie.ignoreLineBreak); - if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak = true; - isFinish = DrawSmoothLine(vh, serie, xAxis, grid, visualMap, lp, np, llp, nnp, i, - isIgnoreBreak ? ColorUtil.clearColor32 : lineColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor, - isStack, zeroPos, startIndex); - break; - - case LineType.StepStart: - case LineType.StepMiddle: - case LineType.StepEnd: - - nnp = LineHelper.GetNNPos(serie.dataPoints, i, np, serie.ignoreLineBreak); - if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak = true; - isFinish = DrawStepLine(vh, serie, xAxis, lp, np, nnp, i, - isIgnoreBreak ? ColorUtil.clearColor32 : lineColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor, - zeroPos); - break; - - case LineType.Dash: - case LineType.Dot: - case LineType.DashDot: - case LineType.DashDotDot: - - if (lp == Vector3.zero && serie.ignoreLineBreak) isIgnoreBreak = true; - DrawOtherLine(vh, serie, xAxis, lp, np, i, - isIgnoreBreak ? ColorUtil.clearColor32 : lineColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaColor, - isIgnoreBreak ? ColorUtil.clearColor32 : areaToColor, - zeroPos); - break; - } - if (isFinish) - serie.animation.SetDataFinish(i); - - if (np != Vector3.zero || serie.ignoreLineBreak) - lp = np; - } if (!serie.animation.IsFinish()) { - serie.animation.CheckProgress(totalDetailProgress - currDetailProgress); - serie.animation.CheckSymbol(serie.symbol.GetSize(null, theme.serie.lineSymbolSize)); + serie.animation.CheckProgress(); + serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize)); chart.m_IsPlayingAnimation = true; chart.RefreshPainter(serie); } } - private float GetDataPoint(Axis xAxis, Axis yAxis, GridCoord grid, List<SerieData> showData, - double yValue, float startX, int i, float scaleWid, bool isStack, ref Vector3 np, float duration, - bool isIngoreValue = false) + private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord grid, double xValue, + double yValue, int i, float scaleWid, bool isStack, ref Vector3 np) { - if (isIngoreValue) - { - np = Vector3.zero; - return 0; - } - float xDataHig, yDataHig; - 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); - double xValue = i > showData.Count - 1 - ? 0 - : showData[i].GetData(0, xAxis.inverse); - float pX = grid.context.x; - float pY = grid.context.y + axisLineWidth; + float xPos, yPos; + if (isY) + { + xPos = AxisHelper.GetAxisPosition(grid, relativedAxis, scaleWid, yValue); + yPos = AxisHelper.GetAxisPosition(grid, axis, scaleWid, xValue); if (isStack) { for (int n = 0; n < m_StackSerieData.Count - 1; n++) - { - pY += m_StackSerieData[n][i].runtimeStackHig; - } + yPos += m_StackSerieData[n][i].runtimeStackHig; } - - if (xAxis.IsLog()) - { - int minIndex = xAxis.GetLogMinIndex(); - float nowIndex = xAxis.GetLogValue(xValue); - xDataHig = (nowIndex - minIndex) / xAxis.splitNumber * grid.context.width; - } - else - { - if ((xMaxValue - xMinValue) <= 0) xDataHig = 0; - else xDataHig = (float)((xValue - xMinValue) / (xMaxValue - xMinValue)) * (grid.context.width); - } - - if (yAxis.IsLog()) - { - int minIndex = yAxis.GetLogMinIndex(); - float nowIndex = yAxis.GetLogValue(yValue); - yDataHig = (nowIndex - minIndex) / yAxis.splitNumber * grid.context.height; - } - else - { - double valueTotal = yMaxValue - yMinValue; - if (valueTotal <= 0) yDataHig = 0; - else yDataHig = (float)((yValue - yMinValue) / valueTotal) * grid.context.height; - } - - np = new Vector3(pX + xDataHig, pY + yDataHig); } else { - var axisLineWidth = yAxis.axisLine.GetWidth(chart.theme.axis.lineWidth); - float pX = startX + i * scaleWid; - float pY = grid.context.y + axisLineWidth; - + xPos = AxisHelper.GetAxisPosition(grid, axis, scaleWid, xValue); + yPos = AxisHelper.GetAxisPosition(grid, relativedAxis, scaleWid, yValue); if (isStack) { for (int n = 0; n < m_StackSerieData.Count - 1; n++) - { - pY += m_StackSerieData[n][i].runtimeStackHig; - } - } - - if (yAxis.IsLog()) - { - int minIndex = yAxis.GetLogMinIndex(); - float nowIndex = yAxis.GetLogValue(yValue); - yDataHig = (nowIndex - minIndex) / yAxis.splitNumber * grid.context.height; - } - else - { - double valueTotal = yMaxValue - yMinValue; - if (valueTotal <= 0) yDataHig = 0; - else yDataHig = (float)((yValue - yMinValue) / valueTotal * grid.context.height); - } - - np = new Vector3(pX, pY + yDataHig); - } - return yDataHig; - } - - - private void DrawYLineSerie(VertexHelper vh, Line serie, int colorIndex) - { - if (!serie.show) - return; - if (serie.animation.HasFadeOut()) - return; - - XAxis xAxis; - YAxis yAxis; - GridCoord grid; - if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) - return; - if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) - return; - if (!chart.TryGetChartComponent<GridCoord>(out grid, xAxis.gridIndex)) - return; - - var theme = chart.theme; - var visualMap = chart.GetVisualMapOfSerie(serie); - var tooltip = chart.GetChartComponent<Tooltip>(); - var dataZoom = chart.GetDataZoomOfAxis(yAxis); - var showData = serie.GetDataList(dataZoom); - - var zeroPos = new Vector3(grid.context.x + xAxis.context.xOffset, grid.context.y); - var isStack = SeriesHelper.IsStack<Line>(chart.series, serie.stack); - var lineColor = SerieHelper.GetLineColor(serie, theme, colorIndex, serie.highlighted); - var lineWidth = serie.lineStyle.GetWidth(theme.serie.lineWidth); - var srcAreaColor = SerieHelper.GetAreaColor(serie, theme, colorIndex, false); - var srcAreaToColor = SerieHelper.GetAreaToColor(serie, theme, colorIndex, false); - var highlightAreaColor = SerieHelper.GetAreaColor(serie, theme, colorIndex, true); - var highlightAreaToColor = SerieHelper.GetAreaToColor(serie, theme, colorIndex, true); - - Color32 areaColor, areaToColor; - Vector3 lp = Vector3.zero; - Vector3 np = Vector3.zero; - Vector3 llp = Vector3.zero; - Vector3 nnp = Vector3.zero; - - float scaleWid = AxisHelper.GetDataWidth(yAxis, grid.context.height, showData.Count, dataZoom); - float startY = grid.context.y + (yAxis.boundaryGap ? scaleWid / 2 : 0); - int maxCount = serie.maxShow > 0 - ? (serie.maxShow > showData.Count ? showData.Count : serie.maxShow) - : showData.Count; - int i = 0; - var rate = LineHelper.GetDataAverageRate(serie, grid, maxCount, true); - var dataChanging = false; - float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); - double xMinValue = xAxis.context.minValue; - double xMaxValue = xAxis.context.maxValue; - - serie.containerIndex = grid.index; - serie.containterInstanceId = grid.instanceId; - - if (isStack) - SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData); - - for (i = serie.minShow; i < maxCount; i += rate) - { - double value = showData[i].GetCurrData(1, dataChangeDuration, xAxis.inverse, - xAxis.context.minValue, xAxis.context.maxValue); - - float pY = startY + i * scaleWid; - float pX = grid.context.x + yAxis.axisLine.GetWidth(theme.axis.lineWidth); - - if (isStack) - { - for (int n = 0; n < m_StackSerieData.Count - 1; n++) - { - pX += m_StackSerieData[n][i].runtimeStackHig; - } - } - - float dataHig = 0; - if (xAxis.IsLog()) - { - int minIndex = xAxis.GetLogMinIndex(); - float nowIndex = xAxis.GetLogValue(value); - dataHig = (nowIndex - minIndex) / (xAxis.splitNumber - 1) * grid.context.width; - } - else - { - dataHig = (float)((value - xMinValue) / (xMaxValue - xMinValue) * grid.context.width); - } - showData[i].runtimeStackHig = dataHig; - np = new Vector3(pX + dataHig, pY); - showData[i].runtimePosition = np; - serie.dataPoints.Add(np); - if (showData[i].IsDataChanged()) - dataChanging = true; - } - - if (dataChanging) - { - chart.RefreshPainter(serie); - } - - if (maxCount % rate != 0) - { - i = maxCount - 1; - double value = showData[i].GetCurrData(1, dataChangeDuration, xAxis.inverse, - xAxis.context.minValue, xAxis.context.maxValue); - float pY = startY + i * scaleWid; - float pX = grid.context.x + yAxis.axisLine.GetWidth(theme.axis.lineWidth); - - if (isStack) - { - for (int n = 0; n < m_StackSerieData.Count - 1; n++) - { - pX += m_StackSerieData[n][i].runtimeStackHig; - } - } - - float dataHig = 0; - if (xAxis.IsLog()) - { - int minIndex = xAxis.GetLogMinIndex(); - float nowIndex = xAxis.GetLogValue(value); - dataHig = (nowIndex - minIndex) / xAxis.splitNumber * grid.context.width; - } - else - { - dataHig = (float)((value - xMinValue) / (xMaxValue - xMinValue)) * grid.context.width; - } - showData[i].runtimeStackHig = dataHig; - np = new Vector3(pX + dataHig, pY); - showData[i].runtimePosition = np; - serie.dataPoints.Add(np); - } - - lp = serie.dataPoints[0]; - - int dataCount = serie.dataPoints.Count; - float currDetailProgress = lp.y; - float totalDetailProgress = serie.dataPoints[dataCount - 1].y; - - serie.animation.InitProgress(dataCount, currDetailProgress, totalDetailProgress); - for (i = 1; i < serie.dataPoints.Count; i++) - { - np = serie.dataPoints[i]; - serie.ClearSmoothList(i); - if (!serie.animation.NeedAnimation(i)) - break; - bool isFinish = true; - - if (serie.areaStyle.tooltipHighlight && tooltip.show && i < tooltip.runtimeDataIndex[0]) - { - areaColor = highlightAreaColor; - areaToColor = highlightAreaToColor; - } - else - { - areaColor = srcAreaColor; - areaToColor = srcAreaToColor; - } - - switch (serie.lineType) - { - case LineType.Normal: - - nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np; - isFinish = DrawNormalLine(vh, serie, yAxis, visualMap, lp, np, nnp, i, lineColor, - areaColor, areaToColor, zeroPos, 0); - break; - - case LineType.Smooth: - case LineType.SmoothDash: - - llp = i > 1 ? serie.dataPoints[i - 2] : lp; - nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np; - isFinish = DrawSmoothLine(vh, serie, yAxis, grid, visualMap, lp, np, llp, nnp, i, - lineColor, areaColor, areaToColor, isStack, zeroPos); - break; - - case LineType.StepStart: - case LineType.StepMiddle: - case LineType.StepEnd: - - nnp = i < serie.dataPoints.Count - 1 ? serie.dataPoints[i + 1] : np; - isFinish = DrawStepLine(vh, serie, yAxis, lp, np, nnp, i, lineColor, - areaColor, areaToColor, zeroPos); - break; - - case LineType.Dash: - - UGL.DrawDashLine(vh, lp, np, lineWidth, lineColor, lineColor); - isFinish = true; - break; - - case LineType.Dot: - - UGL.DrawDotLine(vh, lp, np, lineWidth, lineColor, lineColor); - isFinish = true; - break; - - case LineType.DashDot: - - UGL.DrawDashDotLine(vh, lp, np, lineWidth, lineColor); - isFinish = true; - break; - - case LineType.DashDotDot: - - UGL.DrawDashDotDotLine(vh, lp, np, lineWidth, lineColor); - isFinish = true; - break; - } - if (isFinish) - serie.animation.SetDataFinish(i); - - lp = np; - } - if (!serie.animation.IsFinish()) - { - var totalLineWidth = dataCount * lineWidth * 0.5f; - var total = totalDetailProgress - currDetailProgress - totalLineWidth; - - serie.animation.CheckProgress(total); - serie.animation.CheckSymbol(serie.symbol.GetSize(null, theme.serie.lineSymbolSize)); - chart.m_IsPlayingAnimation = true; - chart.RefreshPainter(serie); - } - } - - private Vector3 stPos1, stPos2, lastDir, lastDnPos; - private bool lastIsDown; - internal bool DrawNormalLine(VertexHelper vh, Serie serie, Axis axis, VisualMap visualMap, Vector3 lp, - Vector3 np, Vector3 nnp, int dataIndex, Color32 lineColor, Color32 areaColor, Color32 areaToColor, - Vector3 zeroPos, int startIndex) - { - var defaultLineColor = lineColor; - var isSecond = dataIndex == startIndex + 1; - var isTheLastPos = np == nnp; - var isYAxis = axis is YAxis; - var isTurnBack = LineHelper.IsInRightOrUp(isYAxis, np, lp); - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - var theme = chart.theme; - - Vector3 dnPos, upPos1, upPos2, dir1v, dir2v; - bool isDown; - var dir1 = (np - lp).normalized; - - dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * (isYAxis ? -1 : 1); - - if (np != nnp) - { - var dir2 = (nnp - np).normalized; - var dir3 = (dir1 + dir2).normalized; - var normal = Vector3.Cross(dir1, dir2); - var angle = (180 - Vector3.Angle(dir1, dir2)) * Mathf.Deg2Rad / 2; - var diff = lineWidth / Mathf.Sin(angle); - var dirDp = Vector3.Cross(dir3, Vector3.forward).normalized * (isYAxis ? -1 : 1); - - isDown = isYAxis ? normal.z >= 0 : normal.z <= 0; - dir2v = Vector3.Cross(dir2, Vector3.forward).normalized * (isYAxis ? -1 : 1); - dnPos = np + (isDown ? dirDp : -dirDp) * diff; - upPos1 = np + (isDown ? -dir1v : dir1v) * lineWidth; - upPos2 = np + (isDown ? -dir2v : dir2v) * lineWidth; - lastDir = dir1; - - if (isDown) - { - if (isYAxis && dnPos.x < lp.x && dnPos.x < nnp.x) - dnPos.x = lp.x; - if (!isYAxis && dnPos.y < lp.y && dnPos.y < nnp.y) - dnPos.y = lp.y; - } - else - { - if (isYAxis && dnPos.x > lp.x && dnPos.x > nnp.x) - dnPos.x = lp.x; - if (!isYAxis && dnPos.y > lp.y && dnPos.y > nnp.y) - dnPos.y = lp.y; + xPos += m_StackSerieData[n][i].runtimeStackHig; } } - else - { - isDown = Vector3.Cross(dir1, lastDir).z <= 0; - if (isYAxis) - isDown = !isDown; - dir1v = Vector3.Cross(dir1, Vector3.forward).normalized * (isYAxis ? -1 : 1); - upPos1 = np - dir1v * lineWidth; - upPos2 = np + dir1v * lineWidth; - dnPos = isDown ? upPos2 : upPos1; - } - - if (isSecond) - { - stPos1 = lp - dir1v * lineWidth; - stPos2 = lp + dir1v * lineWidth; - } - - var smoothPoints = serie.GetUpSmoothList(dataIndex); - var smoothDownPoints = serie.GetDownSmoothList(dataIndex); - var dist = Vector3.Distance(lp, np); - var lastSmoothPoint = Vector3.zero; - var lastSmoothDownPoint = Vector3.zero; - - int segment = (int)(dist / chart.settings.lineSegmentDistance); - if (segment <= 3) - segment = (int)(dist / lineWidth); - if (segment < 2) - segment = 2; - - if (dataIndex > startIndex) - { - lastSmoothPoint = ChartHelper.GetLastPoint(serie.GetUpSmoothList(dataIndex - 1)); - lastSmoothDownPoint = ChartHelper.GetLastPoint(serie.GetDownSmoothList(dataIndex - 1)); - } - - smoothPoints.Clear(); - smoothDownPoints.Clear(); - if (!TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, stPos1, false)) - { - smoothPoints.Add(lastSmoothPoint); - } - if (!TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, stPos2, false)) - { - smoothDownPoints.Add(lastSmoothDownPoint); - } - - var start = lp; - var ltp1 = stPos1; - var ltp2 = stPos2; - bool isBreak = false; - bool isStart = false; - bool isShort = false; - - for (int i = 1; i < segment; i++) - { - var isEndPos = i == segment - 1; - var cp = lp + dir1 * (dist * i / segment); - if (serie.animation.CheckDetailBreak(cp, isYAxis)) - isBreak = true; - - var tp1 = cp - dir1v * lineWidth; - var tp2 = cp + dir1v * lineWidth; - - if (ChartHelper.IsClearColor(serie.lineStyle.color)) - CheckLineGradientColor(visualMap, cp, serie.lineStyle, axis, defaultLineColor, ref lineColor); - - if (isDown) - { - if (!isBreak) - { - if (!isStart) - { - if (isEndPos) - { - isShort = true; - isStart = true; - chart.DrawClipPolygon(vh, stPos1, upPos1, upPos2, stPos2, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, stPos2, upPos2, dnPos, lineColor, serie.clip, grid); - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, stPos1, isEndPos); - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, upPos1, isEndPos); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, dnPos, isEndPos); - } - else if (isSecond || isTurnBack || - (lastIsDown && LineHelper.IsInRightOrUp(isYAxis, lastDnPos, tp2)) || - (!lastIsDown && LineHelper.IsInRightOrUp(isYAxis, lastDnPos, tp1))) - { - isStart = true; - chart.DrawClipPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip, grid); - } - } - else - { - if (isEndPos) - { - if (np != nnp) - { - chart.DrawClipPolygon(vh, ltp1, upPos1, dnPos, ltp2, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, upPos1, upPos2, dnPos, lineColor, serie.clip, grid); - } - else - { - chart.DrawClipPolygon(vh, ltp1, upPos1, upPos2, ltp2, lineColor, serie.clip, grid); - } - } - else - { - if (LineHelper.IsInRightOrUp(isYAxis, tp2, dnPos) || isTurnBack) - { - chart.DrawClipLine(vh, start, cp, lineWidth, - lineColor, serie.clip, grid); - } - else - { - chart.DrawClipPolygon(vh, ltp1, upPos1, dnPos, ltp2, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, upPos1, upPos2, dnPos, lineColor, serie.clip, grid); - i = segment; - } - } - - } - } - if (!isShort) - { - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, tp1, isEndPos); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, tp2, isEndPos); - } - } - else - { - if (!isBreak) - { - if (!isStart) - { - if (isEndPos) - { - isStart = true; - isShort = true; - if (np == nnp) - { - chart.DrawClipPolygon(vh, stPos1, dnPos, upPos2, stPos2, lineColor, serie.clip, grid); - } - else - { - chart.DrawClipPolygon(vh, stPos1, dnPos, upPos1, stPos2, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, dnPos, upPos1, upPos2, lineColor, serie.clip, grid); - } - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, dnPos, isEndPos); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, stPos2, isEndPos); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos2, isEndPos); - } - else if (isSecond || isTurnBack || - (lastIsDown && LineHelper.IsInRightOrUp(isYAxis, lastDnPos, tp2)) || - (!lastIsDown && LineHelper.IsInRightOrUp(isYAxis, lastDnPos, tp1))) - { - isStart = true; - if (stPos2 != Vector3.zero) - { - chart.DrawClipPolygon(vh, stPos1, tp1, tp2, stPos2, lineColor, serie.clip, grid); - } - } - } - else - { - if (isEndPos) - { - if (np != nnp) - { - chart.DrawClipPolygon(vh, ltp1, dnPos, upPos1, ltp2, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, dnPos, upPos2, upPos1, lineColor, serie.clip, grid); - } - else - chart.DrawClipPolygon(vh, ltp1, upPos1, upPos2, ltp2, lineColor, serie.clip, grid); - } - else - { - if (LineHelper.IsInRightOrUp(isYAxis, tp1, dnPos) || isTurnBack) - { - chart.DrawClipLine(vh, start, cp, lineWidth, - lineColor, serie.clip, grid); - } - else - { - chart.DrawClipPolygon(vh, ltp1, dnPos, upPos1, ltp2, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, dnPos, upPos2, upPos1, lineColor, serie.clip, grid); - i = segment; - } - } - } - } - if (!isShort) - { - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, tp1, isEndPos); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, tp2, isEndPos); - } - } - start = cp; - ltp1 = tp1; - ltp2 = tp2; - } - - if (!isBreak && !isShort) - { - if (isDown) - { - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, upPos1, true); - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, upPos2, true); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, dnPos, true); - } - else - { - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, dnPos, true); - if (isYAxis) - { - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, isTheLastPos ? upPos1 : upPos2, true); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, isTheLastPos ? upPos2 : upPos1, true); - } - else - { - if (isTheLastPos) - { - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos2, true); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos1, true); - } - else - { - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos1, true); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, upPos2, true); - } - } - } - } - if (serie.areaStyle.show) - { - var lastSerie = SeriesHelper.GetLastStackSerie(chart.series, serie); - if (lastSerie != null) - { - var lastSmoothPoints = lastSerie.GetUpSmoothList(dataIndex); - - DrawStackArea(vh, serie, axis, smoothDownPoints, lastSmoothPoints, areaColor, areaToColor); - } - else - { - var points = ((isYAxis && lp.x < zeroPos.x) || (!isYAxis && lp.y < zeroPos.y)) - ? smoothPoints - : smoothDownPoints; - - Vector3 aep = isYAxis - ? new Vector3(zeroPos.x, zeroPos.y + grid.context.height) - : new Vector3(zeroPos.x + grid.context.width, zeroPos.y); - var sindex = 0; - var eindex = 0; - var sp = LineHelper.GetStartPos(points, ref sindex, serie.ignoreLineBreak); - var ep = LineHelper.GetEndPos(points, ref eindex, serie.ignoreLineBreak); - var cross = Vector3.zero; - UGLHelper.GetIntersection(lp, np, zeroPos, aep, ref cross); - - if (cross == Vector3.zero || smoothDownPoints.Count <= 3) - { - sp = points[sindex]; - for (int i = sindex + 1; i <= eindex; i++) - { - ep = points[i]; - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - break; - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - sp = ep; - } - } - else - { - var sp1 = smoothDownPoints[0]; - var ep1 = smoothDownPoints[smoothDownPoints.Count - 1]; - var axisLineWidth = axis.axisLine.GetWidth(theme.axis.lineWidth); - var axisUpStart = zeroPos + (isYAxis ? Vector3.right : Vector3.up) * axisLineWidth; - 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 = 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 = Vector3.zero; - UGLHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd, ref rdPos); - - if ((isYAxis && lp.x >= zeroPos.x) || (!isYAxis && lp.y >= zeroPos.y)) - { - sp = smoothDownPoints[0]; - for (int i = 1; i < smoothDownPoints.Count; i++) - { - ep = smoothDownPoints[i]; - - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - break; - - if (luPos == Vector3.zero) - { - sp = ep; - continue; - } - - if ((isYAxis && ep.y > luPos.y) || (!isYAxis && ep.x > luPos.x)) - { - var tp = isYAxis ? new Vector3(luPos.x, sp.y) : new Vector3(sp.x, luPos.y); - chart.DrawClipTriangle(vh, sp, luPos, tp, areaColor, areaToColor, areaToColor, serie.clip, grid); - break; - } - - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - sp = ep; - } - sp = smoothPoints[0]; - bool first = false; - for (int i = 1; i < smoothPoints.Count; i++) - { - ep = smoothPoints[i]; - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - break; - - if ((isYAxis && ep.y <= rdPos.y) || (!isYAxis && ep.x <= rdPos.x)) - continue; - - if (rdPos == Vector3.zero) - { - sp = ep; - continue; - } - if (!first) - { - first = true; - var tp = isYAxis ? new Vector3(rdPos.x, ep.y) : new Vector3(ep.x, rdPos.y); - chart.DrawClipTriangle(vh, rdPos, tp, ep, areaToColor, areaToColor, areaColor, serie.clip, grid); - sp = ep; - continue; - } - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - sp = ep; - } - } - else - { - sp = smoothPoints[0]; - for (int i = 1; i < smoothPoints.Count; i++) - { - ep = smoothPoints[i]; - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - break; - - if (rdPos == Vector3.zero) - { - sp = ep; - continue; - } - - if ((isYAxis && ep.y > rdPos.y) || (!isYAxis && ep.x > rdPos.x)) - { - var tp = isYAxis ? new Vector3(rdPos.x, sp.y) : new Vector3(sp.x, rdPos.y); - chart.DrawClipTriangle(vh, sp, rdPos, tp, areaColor, areaToColor, areaToColor, serie.clip, grid); - break; - } - if (rdPos != Vector3.zero) - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - - sp = ep; - } - sp = smoothDownPoints[0]; - bool first = false; - for (int i = 1; i < smoothDownPoints.Count; i++) - { - ep = smoothDownPoints[i]; - - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - break; - - if ((isYAxis && ep.y < luPos.y) || (!isYAxis && ep.x < luPos.x)) - continue; - - if (luPos == Vector3.zero) - { - sp = ep; - continue; - } - - if (!first) - { - first = true; - var tp = isYAxis ? new Vector3(luPos.x, ep.y) : new Vector3(ep.x, luPos.y); - chart.DrawClipTriangle(vh, ep, luPos, tp, areaColor, areaToColor, areaToColor, serie.clip, grid); - sp = ep; - continue; - } - - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - sp = ep; - } - } - } - } - } - stPos1 = isDown ? upPos2 : dnPos; - stPos2 = isDown ? dnPos : upPos2; - lastDnPos = dnPos; - lastIsDown = isDown; - return !isBreak; - } - - private static bool TryAddToList(bool isTurnBack, bool isYAxis, List<Vector3> list, Vector3 lastPos, - Vector3 pos, bool ignoreClose = false) - { - if (ChartHelper.IsZeroVector(pos)) - return false; - - if (isTurnBack) - { - list.Add(pos); - return true; - } - else if (!ChartHelper.IsZeroVector(lastPos) && LineHelper.IsInRightOrUpNotCheckZero(isYAxis, pos, lastPos)) - { - return false; - } - else if (list.Count <= 0) - { - list.Add(pos); - return true; - } - else - { - var end = list[list.Count - 1]; - if (LineHelper.IsInRightOrUpNotCheckZero(isYAxis, end, pos) - && (!ignoreClose || !LineHelper.WasTooClose(isYAxis, end, pos, ignoreClose))) - { - list.Add(pos); - return true; - } - } - return false; - } - - private void CheckLineGradientColor(VisualMap visualMap, Vector3 cp, LineStyle lineStyle, Axis axis, - Color32 defaultLineColor, ref Color32 lineColor) - { - if (VisualMapHelper.IsNeedGradient(visualMap)) - lineColor = VisualMapHelper.GetLineGradientColor(visualMap, cp, chart, axis, defaultLineColor); - else if (lineStyle.IsNeedGradient()) - lineColor = VisualMapHelper.GetLineStyleGradientColor(lineStyle, cp, chart, axis, defaultLineColor); - } - - private void DrawPolygonToZero(VertexHelper vh, Vector3 sp, Vector3 ep, Axis axis, Vector3 zeroPos, - Color32 areaColor, Color32 areaToColor, Vector3 areaDiff, bool clip = false) - { - float diff = 0; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - var lineWidth = axis.axisLine.GetWidth(chart.theme.axis.lineWidth); - - if (axis is YAxis) - { - var isLessthan0 = (sp.x < zeroPos.x || ep.x < zeroPos.x); - diff = isLessthan0 ? -lineWidth : lineWidth; - areaColor = chart.GetYLerpColor(areaColor, areaToColor, sp, grid); - if (isLessthan0) areaDiff = -areaDiff; - chart.DrawClipPolygon(vh, new Vector3(zeroPos.x + diff, sp.y), new Vector3(zeroPos.x + diff, ep.y), - ep + areaDiff, sp + areaDiff, areaToColor, areaColor, clip, grid); - } - else - { - var isLessthan0 = (sp.y < zeroPos.y || ep.y < zeroPos.y); - diff = isLessthan0 ? -lineWidth : lineWidth; - areaColor = chart.GetXLerpColor(areaColor, areaToColor, sp, grid); - if (isLessthan0) areaDiff = -areaDiff; - if (isLessthan0) - { - chart.DrawClipPolygon(vh, ep + areaDiff, sp + areaDiff, new Vector3(sp.x, zeroPos.y + diff), - new Vector3(ep.x, zeroPos.y + diff), areaColor, areaToColor, clip, grid); - } - else - { - chart.DrawClipPolygon(vh, sp + areaDiff, ep + areaDiff, new Vector3(ep.x, zeroPos.y + diff), - new Vector3(sp.x, zeroPos.y + diff), areaColor, areaToColor, clip, grid); - } - } - } - - private List<Vector3> posList = new List<Vector3>(); - private bool DrawOtherLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp, - Vector3 np, int dataIndex, Color32 lineColor, Color32 areaColor, - Color32 areaToColor, Vector3 zeroPos) - { - bool isYAxis = axis is YAxis; - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - - posList.Clear(); - - switch (serie.lineType) - { - case LineType.Dash: - UGL.DrawDashLine(vh, lp, np, lineWidth, lineColor, lineColor, 0, 0, posList); - break; - case LineType.Dot: - UGL.DrawDotLine(vh, lp, np, lineWidth, lineColor, lineColor, 0, 0, posList); - break; - case LineType.DashDot: - UGL.DrawDashDotLine(vh, lp, np, lineWidth, lineColor, 0, 0, 0, posList); - break; - case LineType.DashDotDot: - UGL.DrawDashDotDotLine(vh, lp, np, lineWidth, lineColor, 0, 0, 0, posList); - break; - } - - if (serie.areaStyle.show && !isYAxis && posList.Count > 0) - { - lp = posList[0]; - var value = serie.GetSerieData(dataIndex).data[1]; - - for (int i = 0; i < posList.Count; i++) - { - np = posList[i]; - var start = new Vector3(lp.x, value > 0 ? (lp.y - lineWidth) : (lp.y + lineWidth)); - var end = new Vector3(np.x, value > 0 ? (np.y - lineWidth) : (np.y + lineWidth)); - DrawPolygonToZero(vh, start, end, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - lp = np; - } - } - - return true; - } - - private List<Vector3> bezierPoints = new List<Vector3>(); - private Vector3 smoothStartPosUp, smoothStartPosDn; - private bool DrawSmoothLine(VertexHelper vh, Serie serie, Axis xAxis, GridCoord grid, VisualMap visualMap, - Vector3 lp, Vector3 np, Vector3 llp, Vector3 nnp, int dataIndex, Color32 lineColor, Color32 areaColor, - Color32 areaToColor, bool isStack, Vector3 zeroPos, int startIndex = 0) - { - var defaultLineColor = lineColor; - var defaultAreaColor = areaColor; - var defaultAreaToColor = areaToColor; - bool isYAxis = xAxis is YAxis; - var isTurnBack = LineHelper.IsInRightOrUp(isYAxis, np, lp); - var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - var smoothPoints = serie.GetUpSmoothList(dataIndex); - var smoothDownPoints = serie.GetDownSmoothList(dataIndex); - var lastSmoothPoint = Vector3.zero; - var lastSmoothDownPoint = Vector3.zero; - var settings = chart.settings; - - if (dataIndex > startIndex) - { - lastSmoothPoint = ChartHelper.GetLastPoint(serie.GetUpSmoothList(dataIndex - 1)); - lastSmoothDownPoint = ChartHelper.GetLastPoint(serie.GetDownSmoothList(dataIndex - 1)); - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, lastSmoothPoint, true); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, lastSmoothDownPoint, true); - } - - if (isYAxis) - UGLHelper.GetBezierListVertical(ref bezierPoints, lp, np, settings.lineSmoothness, settings.lineSmoothStyle); - else - UGLHelper.GetBezierList(ref bezierPoints, lp, np, llp, nnp, settings.lineSmoothness, settings.lineSmoothStyle); - - Vector3 start, to; - if (serie.lineType == LineType.SmoothDash) - { - for (int i = 0; i < bezierPoints.Count - 2; i += 2) - { - start = bezierPoints[i]; - to = bezierPoints[i + 1]; - CheckLineGradientColor(visualMap, start, serie.lineStyle, xAxis, defaultLineColor, ref lineColor); - chart.DrawClipLine(vh, start, to, lineWidth, lineColor, serie.clip, grid); - } - return true; - } - - start = bezierPoints[0]; - - var dir = bezierPoints[1] - start; - var dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1); - var diff = dir1v * lineWidth; - var startUp = start - diff; - var startDn = start + diff; - var startAreaDn = Vector3.zero; - var startAreaUp = Vector3.zero; - Vector3 toUp, toDn; - bool isFinish = true; - - if (dataIndex > startIndex + 1) - { - if (smoothStartPosDn != Vector3.zero && smoothStartPosUp != Vector3.zero) - { - if (!serie.animation.IsInFadeOut()) - { - if (ChartHelper.IsClearColor(serie.lineStyle.color)) - CheckLineGradientColor(visualMap, lp, serie.lineStyle, xAxis, defaultLineColor, ref lineColor); - chart.DrawClipTriangle(vh, smoothStartPosUp, startUp, lp, lineColor, serie.clip, grid); - chart.DrawClipTriangle(vh, smoothStartPosDn, startDn, lp, lineColor, serie.clip, grid); - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, smoothStartPosUp, false); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, smoothStartPosDn, false); - } - } - } - else - { - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, startUp, false); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, startDn, false); - } - - var bezierPointsCount = bezierPoints.Count; - for (int k = 1; k < bezierPointsCount; k++) - { - var isEndPos = k == bezierPointsCount - 1; - to = bezierPoints[k]; - if (serie.animation.CheckDetailBreak(to, isYAxis)) - { - isFinish = false; - break; - } - dir = to - start; - dir1v = Vector3.Cross(dir, Vector3.forward).normalized * (isYAxis ? -1 : 1); - diff = dir1v * lineWidth; - toUp = to - diff; - toDn = to + diff; - - if (ChartHelper.IsClearColor(serie.lineStyle.color)) - CheckLineGradientColor(visualMap, to, serie.lineStyle, xAxis, defaultLineColor, ref lineColor); - - if (isYAxis) - chart.DrawClipPolygon(vh, startDn, toDn, toUp, startUp, lineColor, serie.clip, grid); - else - chart.DrawClipPolygon(vh, startUp, toUp, toDn, startDn, lineColor, serie.clip, grid); - - TryAddToList(isTurnBack, isYAxis, smoothPoints, lastSmoothPoint, toUp, true); - TryAddToList(isTurnBack, isYAxis, smoothDownPoints, lastSmoothDownPoint, toDn, true); - - if (isEndPos) - { - smoothStartPosUp = toUp; - smoothStartPosDn = toDn; - } - - start = to; - startUp = toUp; - startDn = toDn; - } - if (serie.areaStyle.show && (serie.index == 0 || !isStack)) - { - if (smoothDownPoints.Count > 0) - { - start = smoothDownPoints[0]; - for (int i = 1; i < smoothDownPoints.Count; i++) - { - to = smoothDownPoints[i]; - - if (LineHelper.IsInRightOrUp(!isYAxis, zeroPos, to)) - { - if (ChartHelper.IsClearColor(serie.areaStyle.color)) - { - CheckLineGradientColor(visualMap, to, serie.lineStyle, xAxis, defaultAreaColor, ref areaColor); - CheckLineGradientColor(visualMap, to, serie.lineStyle, xAxis, defaultAreaToColor, ref areaToColor); - } - DrawPolygonToZero(vh, start, to, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero); - } - start = to; - } - } - - if (smoothPoints.Count > 0) - { - start = smoothPoints[smoothPoints.Count - 1]; - for (int i = smoothPoints.Count - 1; i >= 0; i--) - { - to = smoothPoints[i]; - if (!LineHelper.IsInRightOrUp(!isYAxis, zeroPos, to)) - { - DrawPolygonToZero(vh, to, start, xAxis, zeroPos, areaColor, areaToColor, Vector3.zero); - } - start = to; - } - } - } - - if (serie.areaStyle.show) - { - var lastSerie = SeriesHelper.GetLastStackSerie(chart.series, serie); - if (lastSerie != null) - { - var lastSmoothPoints = lastSerie.GetUpSmoothList(dataIndex); - DrawStackArea(vh, serie, xAxis, smoothDownPoints, lastSmoothPoints, areaColor, areaToColor); - } - } - return isFinish; - } - - private void DrawStackArea(VertexHelper vh, Serie serie, Axis axis, List<Vector3> smoothPoints, - List<Vector3> lastSmoothPoints, Color32 areaColor, Color32 areaToColor) - { - if (!serie.areaStyle.show || lastSmoothPoints.Count <= 0) - return; - - Vector3 start, to; - var isYAxis = axis is YAxis; - - var lastCount = 1; - start = smoothPoints[0]; - var sourAreaColor = areaColor; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - - for (int k = 1; k < smoothPoints.Count; k++) - { - to = smoothPoints[k]; - if (!LineHelper.IsInRightOrUp(isYAxis, start, to)) - continue; - if (serie.animation.CheckDetailBreak(to, isYAxis)) - break; - - Vector3 tnp, tlp; - if (isYAxis) - areaColor = chart.GetYLerpColor(sourAreaColor, areaToColor, to, grid); - else - areaColor = chart.GetXLerpColor(sourAreaColor, areaToColor, to, grid); - - if (k == smoothPoints.Count - 1) - { - if (k < lastSmoothPoints.Count - 1) - { - tnp = lastSmoothPoints[lastCount - 1]; - chart.DrawClipTriangle(vh, start, to, tnp, areaColor, areaColor, areaToColor, serie.clip, grid); - while (lastCount < lastSmoothPoints.Count) - { - tlp = lastSmoothPoints[lastCount]; - if (serie.animation.CheckDetailBreak(tlp, isYAxis)) - break; - - chart.DrawClipTriangle(vh, tnp, to, tlp, areaToColor, areaColor, areaToColor, serie.clip, grid); - lastCount++; - tnp = tlp; - } - start = to; - continue; - } - } - if (lastCount >= lastSmoothPoints.Count) - { - tlp = lastSmoothPoints[lastSmoothPoints.Count - 1]; - if (serie.animation.CheckDetailBreak(tlp, isYAxis)) - break; - - chart.DrawClipTriangle(vh, to, start, tlp, areaColor, areaColor, areaToColor, serie.clip, grid); - start = to; - continue; - } - tnp = lastSmoothPoints[lastCount]; - var diff = isYAxis ? tnp.y - to.y : tnp.x - to.x; - if (Math.Abs(diff) < 1) - { - tlp = lastSmoothPoints[lastCount - 1]; - if (serie.animation.CheckDetailBreak(tlp, isYAxis)) - break; - - chart.DrawClipPolygon(vh, start, to, tnp, tlp, areaColor, areaToColor, serie.clip, grid); - lastCount++; - } - else - { - if (diff < 0) - { - tnp = lastSmoothPoints[lastCount - 1]; - chart.DrawClipTriangle(vh, start, to, tnp, areaColor, areaColor, areaToColor, serie.clip, grid); - while (diff < 0 && lastCount < lastSmoothPoints.Count) - { - tlp = lastSmoothPoints[lastCount]; - if (serie.animation.CheckDetailBreak(tlp, isYAxis)) - break; - - chart.DrawClipTriangle(vh, tnp, to, tlp, areaToColor, areaColor, areaToColor, serie.clip, grid); - lastCount++; - diff = isYAxis ? tlp.y - to.y : tlp.x - to.x; - tnp = tlp; - } - } - else - { - tlp = lastSmoothPoints[lastCount - 1]; - if (serie.animation.CheckDetailBreak(tlp, isYAxis)) - break; - - chart.DrawClipTriangle(vh, start, to, tlp, areaColor, areaColor, areaToColor, serie.clip, grid); - } - } - start = to; - } - if (lastCount < lastSmoothPoints.Count) - { - var p1 = lastSmoothPoints[lastCount - 1]; - var p2 = lastSmoothPoints[lastSmoothPoints.Count - 1]; - if (!serie.animation.CheckDetailBreak(p1, isYAxis) && !serie.animation.CheckDetailBreak(p2, isYAxis)) - { - chart.DrawClipTriangle(vh, p1, start, p2, areaToColor, areaColor, areaToColor, serie.clip, grid); - } - } - } - - private List<Vector3> linePointList = new List<Vector3>(); - private bool DrawStepLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp, Vector3 np, - Vector3 nnp, int dataIndex, Color32 lineColor, Color32 areaColor, Color32 areaToColor, Vector3 zeroPos) - { - bool isYAxis = axis is YAxis; - float lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); - Vector3 start, end, middle, middleZero, middle1, middle2; - Vector3 sp, ep, diff1, diff2; - var areaDiff = isYAxis ? Vector3.left * lineWidth : Vector3.down * lineWidth; - var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex); - var settings = chart.settings; - - switch (serie.lineType) - { - case LineType.StepStart: - - middle = isYAxis ? new Vector3(np.x, lp.y) : new Vector3(lp.x, np.y); - middleZero = isYAxis ? new Vector3(zeroPos.x, middle.y) : new Vector3(middle.x, zeroPos.y); - diff1 = (middle - lp).normalized * lineWidth; - diff2 = (np - middle).normalized * lineWidth; - start = dataIndex == 1 ? lp : lp + diff1; - end = nnp != np ? np - diff2 : np; - - if (Vector3.Distance(lp, middle) > 2 * lineWidth) - { - ChartHelper.GetPointList(ref linePointList, start, middle - diff1, settings.lineSegmentDistance); - sp = linePointList[0]; - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - return false; - - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - sp = ep; - } - chart.DrawClipPolygon(vh, middle, lineWidth, lineColor, serie.clip, true, grid); - } - else - { - if (dataIndex == 1) - chart.DrawClipPolygon(vh, lp, lineWidth, lineColor, serie.clip, true, grid); - - chart.DrawClipLine(vh, lp + diff1, middle + diff1, lineWidth, lineColor, serie.clip, grid); - } - if (serie.areaStyle.show) - { - if (Vector3.Dot(middle - lp, middleZero - middle) >= 0) - { - DrawPolygonToZero(vh, middle - diff2, middle + diff2, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - else if (dataIndex == 1) - { - DrawPolygonToZero(vh, lp - diff2, lp + diff2, axis, zeroPos, areaColor, areaToColor, Vector3.zero); - } - } - - ChartHelper.GetPointList(ref linePointList, middle + diff2, end, settings.lineSegmentDistance); - - sp = linePointList[0]; - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - return false; - - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - if (serie.areaStyle.show) - { - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - sp = ep; - } - - if (nnp != np) - { - if (serie.animation.CheckDetailBreak(np, isYAxis)) - return false; - - chart.DrawClipPolygon(vh, np, lineWidth, lineColor, serie.clip, true, grid); - bool flag = ((isYAxis && nnp.x > np.x && np.x > zeroPos.x) || (!isYAxis && nnp.y > np.y && np.y > zeroPos.y)); - if (serie.areaStyle.show && flag) - { - DrawPolygonToZero(vh, np - diff2, np + diff2, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - } - break; - - case LineType.StepMiddle: - - middle1 = isYAxis ? new Vector2(lp.x, (lp.y + np.y) / 2) : new Vector2((lp.x + np.x) / 2, lp.y); - middle2 = isYAxis ? new Vector2(np.x, (lp.y + np.y) / 2) : new Vector2((lp.x + np.x) / 2, np.y); - middleZero = isYAxis ? new Vector3(zeroPos.x, middle1.y) : new Vector3(middle1.x, zeroPos.y); - diff1 = (middle1 - lp).normalized * lineWidth; - diff2 = (middle2 - middle1).normalized * lineWidth; - - start = dataIndex == 1 ? lp : lp + diff1; - end = nnp != np ? np - diff2 : np; - - //draw lp to middle1 - if (Vector3.Distance(lp, middle1) > 2 * lineWidth) - { - ChartHelper.GetPointList(ref linePointList, start, middle1 - diff1, settings.lineSegmentDistance); - sp = linePointList[0]; - - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - return false; - - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - if (serie.areaStyle.show) - { - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - sp = ep; - } - - if (serie.animation.CheckDetailBreak(middle1, isYAxis)) - return false; - - chart.DrawClipPolygon(vh, middle1, lineWidth, lineColor, serie.clip, true, grid); - if (serie.areaStyle.show && Vector3.Dot(middleZero - middle1, middle2 - middle1) <= 0) - { - DrawPolygonToZero(vh, middle1 - diff1, middle1 + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - } - else - { - if (dataIndex == 1) - chart.DrawClipPolygon(vh, lp, lineWidth, lineColor, serie.clip, true, grid); - - chart.DrawClipLine(vh, lp + diff1, middle1 + diff1, lineWidth, lineColor, serie.clip, grid); - } - - //draw middle1 to middle2 - if (Vector3.Distance(middle1, middle2) > 2 * lineWidth) - { - ChartHelper.GetPointList(ref linePointList, middle1 + diff2, middle2 - diff2, settings.lineSegmentDistance); - sp = linePointList[0]; - - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - sp = ep; - } - - chart.DrawClipPolygon(vh, middle2, lineWidth, lineColor, serie.clip, true, grid); - - if (serie.areaStyle.show && Vector3.Dot(middleZero - middle2, middle2 - middle1) >= 0) - { - DrawPolygonToZero(vh, middle2 - diff1, middle2 + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - } - else - { - chart.DrawClipLine(vh, middle1 + diff2, middle2 + diff2, lineWidth, lineColor, serie.clip, grid); - } - //draw middle2 to np - if (Vector3.Distance(middle2, np) > 2 * lineWidth) - { - ChartHelper.GetPointList(ref linePointList, middle2 + diff1, np - diff1, settings.lineSegmentDistance); - sp = linePointList[0]; - - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - return false; - - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - if (serie.areaStyle.show) - { - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - sp = ep; - } - - if (serie.animation.CheckDetailBreak(np, isYAxis)) - return false; - - chart.DrawClipPolygon(vh, np, lineWidth, lineColor, serie.clip, true, grid); - if (serie.areaStyle.show) - { - DrawPolygonToZero(vh, np - diff1, np + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - } - else - { - chart.DrawClipLine(vh, middle1 + diff1, middle1 + diff1, lineWidth, lineColor, serie.clip, grid); - } - break; - - case LineType.StepEnd: - - middle = isYAxis ? new Vector3(lp.x, np.y) : new Vector3(np.x, lp.y); - middleZero = isYAxis ? new Vector3(zeroPos.x, middle.y) : new Vector3(middle.x, zeroPos.y); - diff1 = (middle - lp).normalized * lineWidth; - diff2 = (np - middle).normalized * lineWidth; - start = dataIndex == 1 ? lp : lp + diff1; - end = nnp != np ? np - diff2 : np; - - if (Vector3.Distance(lp, middle) > 2 * lineWidth) - { - ChartHelper.GetPointList(ref linePointList, start, middle - diff1, settings.lineSegmentDistance); - sp = linePointList[0]; - - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - - if (serie.animation.CheckDetailBreak(ep, isYAxis)) - return false; - - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - - if (serie.areaStyle.show) - { - DrawPolygonToZero(vh, sp, ep, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - sp = ep; - } - - if (serie.animation.CheckDetailBreak(middle, isYAxis)) - return false; - - chart.DrawClipPolygon(vh, middle, lineWidth, lineColor, serie.clip, true, grid); - - if (serie.areaStyle.show && Vector3.Dot(np - middle, middleZero - middle) <= 0) - { - DrawPolygonToZero(vh, middle - diff1, middle + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - } - else - { - if (dataIndex == 1) - chart.DrawClipPolygon(vh, lp, lineWidth, lineColor, serie.clip, true, grid); - - chart.DrawClipLine(vh, lp + diff1, middle + diff1, lineWidth, lineColor, serie.clip, grid); - } - - if (Vector3.Distance(middle, np) > 2 * lineWidth) - { - ChartHelper.GetPointList(ref linePointList, middle + diff2, end, settings.lineSegmentDistance); - sp = linePointList[0]; - - for (int i = 1; i < linePointList.Count; i++) - { - ep = linePointList[i]; - chart.DrawClipLine(vh, sp, ep, lineWidth, lineColor, serie.clip, grid); - sp = ep; - } - - if (nnp != np) - chart.DrawClipPolygon(vh, np, lineWidth, lineColor, serie.clip, true, grid); - } - else - { - chart.DrawClipLine(vh, middle + diff2, np + diff2, lineWidth, lineColor, serie.clip, grid); - } - - bool flag2 = ((isYAxis && middle.x > np.x && np.x > zeroPos.x) - || (!isYAxis && middle.y > np.y && np.y > zeroPos.y)); - if (serie.areaStyle.show && flag2) - { - DrawPolygonToZero(vh, np - diff1, np + diff1, axis, zeroPos, areaColor, areaToColor, areaDiff); - } - break; - } - return true; + np = new Vector3(xPos, yPos); + return yPos; } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs b/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs index 1d0c842a..148c4457 100644 --- a/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs +++ b/Assets/XCharts/Runtime/Serie/Line/LineHandler.PolarCoord.cs @@ -97,12 +97,13 @@ namespace XCharts var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, n, highlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, n, highlight); + var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, n, highlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, highlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); symbolSize = serie.animation.GetSysmbolSize(symbolSize); chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, serieData.runtimePosition, - symbolColor, symbolToColor, symbol.gap, cornerRadius); + symbolColor, symbolToColor, symbolEmptyColor, symbol.gap, cornerRadius); } } } diff --git a/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs b/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs index b0135994..491eabd7 100644 --- a/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs +++ b/Assets/XCharts/Runtime/Serie/Line/LineHelper.cs @@ -7,11 +7,15 @@ using System.Collections.Generic; using UnityEngine; +using UnityEngine.UI; +using XUGL; namespace XCharts { internal static class LineHelper { + private static List<Vector3> s_CurvesPosList = new List<Vector3>(); + public static int GetDataAverageRate(Serie serie, GridCoord grid, int maxCount, bool isYAxis) { var sampleDist = serie.sampleDist; @@ -24,93 +28,424 @@ namespace XCharts return rate; } - public static Vector3 GetNNPos(List<Vector3> dataPoints, int index, Vector3 np, bool ignoreLineBreak) + public static void DrawSerieLineArea(VertexHelper vh, Serie serie, Serie lastStackSerie, + ThemeStyle theme, bool isY, Axis axis, Axis relativedAxis, GridCoord grid) { - int size = dataPoints.Count; - if (index >= size) - return np; - for (int i = index + 1; i < size; i++) + if (!serie.areaStyle.show) + return; + + var srcAreaColor = SerieHelper.GetAreaColor(serie, theme, serie.context.colorIndex, false); + var srcAreaToColor = SerieHelper.GetAreaToColor(serie, theme, serie.context.colorIndex, false); + var gridXY = (isY ? grid.context.x : grid.context.y); + if (lastStackSerie == null) { - if (dataPoints[i] != Vector3.zero || ignoreLineBreak) - return dataPoints[i]; + LineHelper.DrawSerieLineNormalArea(vh, serie, isY, + gridXY + relativedAxis.context.offset, + gridXY, + gridXY + (isY ? grid.context.width : grid.context.height), + srcAreaColor, + srcAreaToColor); } - return np; - } - - public static Vector3 GetStartPos(List<Vector3> dataPoints, ref int start, bool ignoreLineBreak) - { - for (int i = 0; i < dataPoints.Count; i++) - { - if (dataPoints[i] != Vector3.zero || ignoreLineBreak) - { - start = i; - return dataPoints[i]; - } - } - return Vector3.zero; - } - - public static Vector3 GetEndPos(List<Vector3> dataPoints, ref int end, bool ignoreLineBreak) - { - for (int i = dataPoints.Count - 1; i >= 0; i--) - { - if (dataPoints[i] != Vector3.zero || ignoreLineBreak) - { - end = i; - return dataPoints[i]; - } - } - return Vector3.zero; - } - - public static Vector3 GetLastPos(List<Vector3> dataPoints, int index, Vector3 pos, bool ignoreLineBreak) - { - if (index <= 0) - return pos; - for (int i = index - 1; i >= 0; i--) - { - if (dataPoints[i] != Vector3.zero || ignoreLineBreak) - return dataPoints[i]; - } - return pos; - } - - public static Vector3 GetLLPos(List<Vector3> dataPoints, int index, Vector3 lp, bool ignoreLineBreak) - { - if (index <= 1) - return lp; - for (int i = index - 2; i >= 0; i--) - { - if (dataPoints[i] != Vector3.zero || ignoreLineBreak) - return dataPoints[i]; - } - return lp; - } - - public static bool IsInRightOrUp(bool isYAxis, Vector3 lp, Vector3 rp) - { - return ChartHelper.IsZeroVector(lp) - || ((isYAxis && rp.y > lp.y) - || (!isYAxis && rp.x > lp.x)); - } - - public static bool IsInRightOrUpNotCheckZero(bool isYAxis, Vector3 lp, Vector3 rp) - { - return (isYAxis && rp.y > lp.y) || (!isYAxis && rp.x > lp.x); - } - - public static bool WasTooClose(bool isYAxis, Vector3 lp, Vector3 rp, bool ignore) - { - if (ignore) - return false; - - if (lp == Vector3.zero || rp == Vector3.zero) - return false; - - if (isYAxis) - return Mathf.Abs(rp.y - lp.y) < 1f; else - return Mathf.Abs(rp.x - lp.x) < 1f; + { + LineHelper.DrawSerieLineStackArea(vh, serie, lastStackSerie, isY, + gridXY + relativedAxis.context.offset, + gridXY, + gridXY + (isY ? grid.context.width : grid.context.height), + srcAreaColor, + srcAreaToColor); + } + } + + private static void DrawSerieLineNormalArea(VertexHelper vh, Serie serie, bool isY, + float zero, float min, float max, Color32 color, Color32 toColor) + { + var points = serie.context.drawPoints; + var count = points.Count; + if (count < 2) + return; + + var isBreak = false; + var lp = Vector3.zero; + var lerp = !ChartHelper.IsValueEqualsColor(color, toColor); + var zsp = isY + ? new Vector3(zero, points[0].position.y) + : new Vector3(points[0].position.x, zero); + var zep = isY + ? new Vector3(zero, points[count - 1].position.y) + : new Vector3(points[count - 1].position.x, zero); + + var lastDataIsIgnore = false; + for (int i = 0; i < points.Count; i++) + { + var tp = points[i].position; + var isIgnore = points[i].isIgnoreBreak; + + if (serie.animation.CheckDetailBreak(tp, isY)) + { + isBreak = true; + + var progress = serie.animation.GetCurrDetail(); + var ip = Vector3.zero; + var axisStartPos = isY ? new Vector3(-10000, progress) : new Vector3(progress, -10000); + var axisEndPos = isY ? new Vector3(10000, progress) : new Vector3(progress, 10000); + + if (UGLHelper.GetIntersection(lp, tp, axisStartPos, axisEndPos, ref ip)) + tp = ip; + } + + var zp = isY ? new Vector3(zero, tp.y) : new Vector3(tp.x, zero); + + if (i > 0) + { + if ((lp.y - zero > 0 && tp.y - zero < 0) || (lp.y - zero < 0 && tp.y - zero > 0)) + { + var ip = Vector3.zero; + if (UGLHelper.GetIntersection(lp, tp, zsp, zep, ref ip)) + { + if (lerp) + AddVertToVertexHelperWithLerpColor(vh, ip, ip, color, toColor, isY, min, max, i > 0); + else + { + if (lastDataIsIgnore) + UGL.AddVertToVertexHelper(vh, ip, ip, ColorUtil.clearColor32, true); + + UGL.AddVertToVertexHelper(vh, ip, ip, toColor, color, i > 0); + + if (isIgnore) + UGL.AddVertToVertexHelper(vh, ip, ip, ColorUtil.clearColor32, true); + } + } + } + } + + if (lerp) + AddVertToVertexHelperWithLerpColor(vh, tp, zp, color, toColor, isY, min, max, i > 0); + else + { + if (lastDataIsIgnore) + UGL.AddVertToVertexHelper(vh, tp, zp, ColorUtil.clearColor32, true); + + UGL.AddVertToVertexHelper(vh, tp, zp, toColor, color, i > 0); + + if (isIgnore) + UGL.AddVertToVertexHelper(vh, tp, zp, ColorUtil.clearColor32, true); + } + lp = tp; + lastDataIsIgnore = isIgnore; + if (isBreak) + break; + } + } + + private static void DrawSerieLineStackArea(VertexHelper vh, Serie serie, Serie lastStackSerie, bool isY, + float zero, float min, float max, Color32 color, Color32 toColor) + { + if (lastStackSerie == null) + return; + + var upPoints = serie.context.drawPoints; + var downPoints = lastStackSerie.context.drawPoints; + var upCount = upPoints.Count; + var downCount = downPoints.Count; + + if (upCount <= 0 || downCount <= 0) + return; + + var lerp = !ChartHelper.IsValueEqualsColor(color, toColor); + var ltp = upPoints[0].position; + var lbp = downPoints[0].position; + + if (lerp) + AddVertToVertexHelperWithLerpColor(vh, ltp, lbp, color, toColor, isY, min, max, false); + else + UGL.AddVertToVertexHelper(vh, ltp, lbp, color, false); + + int u = 1, d = 1; + var isBreakTop = false; + var isBreakBottom = false; + + while ((u < upCount || d < downCount)) + { + var tp = u < upCount ? upPoints[u].position : upPoints[upCount - 1].position; + var bp = d < downCount ? downPoints[d].position : downPoints[downCount - 1].position; + + var tnp = (u + 1) < upCount ? upPoints[u + 1].position : upPoints[upCount - 1].position; + var bnp = (d + 1) < downCount ? downPoints[d + 1].position : downPoints[downCount - 1].position; + + if (serie.animation.CheckDetailBreak(tp, isY)) + { + isBreakTop = true; + + var progress = serie.animation.GetCurrDetail(); + var ip = Vector3.zero; + + if (UGLHelper.GetIntersection(ltp, tp, + new Vector3(progress, -10000), + new Vector3(progress, 10000), ref ip)) + tp = ip; + else + tp = new Vector3(progress, tp.y); + } + if (serie.animation.CheckDetailBreak(bp, isY)) + { + isBreakBottom = true; + + var progress = serie.animation.GetCurrDetail(); + var ip = Vector3.zero; + + if (UGLHelper.GetIntersection(lbp, bp, + new Vector3(progress, -10000), + new Vector3(progress, 10000), ref ip)) + bp = ip; + else + bp = new Vector3(progress, bp.y); + } + + if (lerp) + AddVertToVertexHelperWithLerpColor(vh, tp, bp, color, toColor, isY, min, max, true); + else + UGL.AddVertToVertexHelper(vh, tp, bp, color, true); + u++; + d++; + if (bp.x < tp.x && bnp.x < tp.x) + u--; + if (tp.x < bp.x && tnp.x < bp.x) + d--; + + ltp = tp; + lbp = bp; + if (isBreakTop && isBreakBottom) + break; + } + } + + private static void AddVertToVertexHelperWithLerpColor(VertexHelper vh, Vector3 tp, Vector3 bp, + Color32 color, Color32 toColor, bool isY, float min, float max, bool needTriangle) + { + var range = max - min; + var color1 = Color32.Lerp(color, toColor, ((isY ? tp.x : tp.y) - min) / range); + var color2 = Color32.Lerp(color, toColor, ((isY ? bp.x : bp.y) - min) / range); + UGL.AddVertToVertexHelper(vh, tp, bp, color1, color2, needTriangle); + } + + internal static void DrawSerieLine(VertexHelper vh, ThemeStyle theme, Serie serie, VisualMap visualMap, + GridCoord grid, Axis axis, Axis relativedAxis) + { + var datas = serie.context.drawPoints; + + var dataCount = datas.Count; + if (dataCount < 2) + return; + + var ltp = Vector3.zero; + var lbp = Vector3.zero; + var ntp = Vector3.zero; + var nbp = Vector3.zero; + var itp = Vector3.zero; + var ibp = Vector3.zero; + var clp = Vector3.zero; + var crp = Vector3.zero; + + var isBreak = false; + var isY = axis is YAxis; + var isVisualMapGradient = VisualMapHelper.IsNeedGradient(visualMap); + var isLineStyleGradient = serie.lineStyle.IsNeedGradient(); + + var highlight = serie.highlighted || serie.context.pointerEnter; + var lineWidth = serie.lineStyle.GetWidth(theme.serie.lineWidth); + var lineColor = SerieHelper.GetLineColor(serie, theme, serie.context.colorIndex, highlight); + + var lastDataIsIgnore = datas[0].isIgnoreBreak; + for (int i = 1; i < dataCount; i++) + { + if (!serie.animation.NeedAnimation(i)) + break; + + var cdata = datas[i]; + var isIgnore = cdata.isIgnoreBreak; + + var cp = cdata.position; + var lp = datas[i - 1].position; + + var np = i == dataCount - 1 ? cp : datas[i + 1].position; + if (serie.animation.CheckDetailBreak(cp, isY)) + { + isBreak = true; + + var progress = serie.animation.GetCurrDetail(); + var ip = Vector3.zero; + + var axisStartPos = isY ? new Vector3(-10000, progress) : new Vector3(progress, -10000); + var axisEndPos = isY ? new Vector3(10000, progress) : new Vector3(progress, 10000); + + if (UGLHelper.GetIntersection(lp, cp, axisStartPos, axisEndPos, ref ip)) + cp = np = ip; + + } + bool bitp = true, bibp = true; + UGLHelper.GetLinePoints(lp, cp, np, lineWidth, + ref ltp, ref lbp, + ref ntp, ref nbp, + ref itp, ref ibp, + ref clp, ref crp, + ref bitp, ref bibp); + + if (i == 1) + { + AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient, + visualMap, serie.lineStyle, grid, axis, relativedAxis, false, lastDataIsIgnore, isIgnore); + } + + if (bitp == bibp) + { + AddLineVertToVertexHelper(vh, itp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient, + visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); + } + else + { + if (bitp) + { + AddLineVertToVertexHelper(vh, itp, clp, lineColor, isVisualMapGradient, isLineStyleGradient, + visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); + AddLineVertToVertexHelper(vh, itp, crp, lineColor, isVisualMapGradient, isLineStyleGradient, + visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); + } + else if (bibp) + { + AddLineVertToVertexHelper(vh, clp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient, + visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); + AddLineVertToVertexHelper(vh, crp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient, + visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore); + } + } + lastDataIsIgnore = isIgnore; + if (!isBreak) + serie.animation.SetDataFinish(i); + else + break; + } + } + + private static void AddLineVertToVertexHelper(VertexHelper vh, Vector3 tp, Vector3 bp, + Color32 lineColor, bool visualMapGradient, bool lineStyleGradient, VisualMap visualMap, + LineStyle lineStyle, GridCoord grid, Axis axis, Axis relativedAxis, bool needTriangle, + bool lastIgnore, bool ignore) + { + if (lastIgnore && needTriangle) + UGL.AddVertToVertexHelper(vh, tp, bp, ColorUtil.clearColor32, true); + + if (visualMapGradient) + { + var color1 = VisualMapHelper.GetLineGradientColor(visualMap, tp, grid, axis, relativedAxis, lineColor); + var color2 = VisualMapHelper.GetLineGradientColor(visualMap, bp, grid, axis, relativedAxis, lineColor); + UGL.AddVertToVertexHelper(vh, tp, bp, color1, color2, needTriangle); + } + else if (lineStyleGradient) + { + var color1 = VisualMapHelper.GetLineStyleGradientColor(lineStyle, tp, grid, axis, lineColor); + var color2 = VisualMapHelper.GetLineStyleGradientColor(lineStyle, bp, grid, axis, lineColor); + UGL.AddVertToVertexHelper(vh, tp, bp, color1, color2, needTriangle); + } + else + { + UGL.AddVertToVertexHelper(vh, tp, bp, lineColor, needTriangle); + } + if (lastIgnore && !needTriangle) + UGL.AddVertToVertexHelper(vh, tp, bp, ColorUtil.clearColor32, false); + if (ignore && needTriangle) + UGL.AddVertToVertexHelper(vh, tp, bp, ColorUtil.clearColor32, false); + } + + internal static void UpdateSerieDrawPoints(Serie serie, Settings setting, ThemeStyle theme, bool isY = false) + { + + serie.context.drawPoints.Clear(); + var last = Vector3.zero; + switch (serie.lineType) + { + case LineType.Smooth: + UpdateSmoothLineDrawPoints(serie, setting, isY); + break; + case LineType.StepStart: + case LineType.StepMiddle: + case LineType.StepEnd: + UpdateStepLineDrawPoints(serie, setting, theme, isY); + break; + default: + for (int i = 0; i < serie.dataPoints.Count; i++) + { + serie.context.drawPoints.Add(new PointInfo(serie.dataPoints[i], serie.dataIgnore[i])); + } + break; + } + } + + private static void UpdateSmoothLineDrawPoints(Serie serie, Settings setting, bool isY) + { + var points = serie.dataPoints; + float smoothness = setting.lineSmoothness; + for (int i = 0; i < points.Count - 1; i++) + { + 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; + var ignore = serie.dataIgnore[i]; + if (isY) + UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness); + else + UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness); + + for (int j = 1; j < s_CurvesPosList.Count; j++) + { + serie.context.drawPoints.Add(new PointInfo(s_CurvesPosList[j], ignore)); + } + } + } + + private static void UpdateStepLineDrawPoints(Serie serie, Settings setting, ThemeStyle theme, bool isY) + { + var points = serie.dataPoints; + var lp = points[0]; + var lineWidth = serie.lineStyle.GetWidth(theme.serie.lineWidth); + serie.context.drawPoints.Clear(); + serie.context.drawPoints.Add(new PointInfo(lp, serie.dataIgnore[0])); + for (int i = 1; i < points.Count; i++) + { + var cp = points[i]; + var ignore = serie.dataIgnore[i]; + if ((isY && Mathf.Abs(lp.x - cp.x) <= lineWidth) + || (!isY && Mathf.Abs(lp.y - cp.y) <= lineWidth)) + { + serie.context.drawPoints.Add(new PointInfo(cp, ignore)); + lp = cp; + continue; + } + switch (serie.lineType) + { + case LineType.StepStart: + serie.context.drawPoints.Add(new PointInfo(isY + ? new Vector3(cp.x, lp.y) + : new Vector3(lp.x, cp.y), ignore)); + break; + case LineType.StepMiddle: + serie.context.drawPoints.Add(new PointInfo(isY + ? new Vector3(lp.x, (lp.y + cp.y) / 2) + : new Vector3((lp.x + cp.x) / 2, lp.y), ignore)); + serie.context.drawPoints.Add(new PointInfo(isY + ? new Vector3(cp.x, (lp.y + cp.y) / 2) + : new Vector3((lp.x + cp.x) / 2, cp.y), ignore)); + break; + case LineType.StepEnd: + serie.context.drawPoints.Add(new PointInfo(isY + ? new Vector3(lp.x, cp.y) + : new Vector3(cp.x, lp.y), ignore)); + break; + } + serie.context.drawPoints.Add(new PointInfo(cp, ignore)); + lp = cp; + } } } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs b/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs index 4124f9a6..6b4c69eb 100644 --- a/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Radar/RadarHandler.cs @@ -226,10 +226,11 @@ namespace XCharts : serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize); var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieIndex, isHighlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight); + var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serieIndex, isHighlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, serie.symbol.gap, cornerRadius); + symbolToColor, symbolEmptyColor, serie.symbol.gap, cornerRadius); } } } @@ -413,6 +414,7 @@ namespace XCharts : serie.symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieIndex, isHighlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight); + var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serieIndex, isHighlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); if (!radar.IsInIndicatorRange(j, serieData.GetData(1))) @@ -421,7 +423,7 @@ namespace XCharts symbolToColor = radar.outRangeColor; } chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.labelPosition, symbolColor, - symbolToColor, serie.symbol.gap, cornerRadius); + symbolToColor, symbolEmptyColor, serie.symbol.gap, cornerRadius); } } if (!serie.animation.IsFinish()) @@ -462,12 +464,13 @@ namespace XCharts : serie.symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize); var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieIndex, isHighlight); var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieIndex, isHighlight); + var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, serieIndex, isHighlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight); foreach (var point in pointList) { chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor, - symbolToColor, serie.symbol.gap, cornerRadius); + symbolToColor, symbolEmptyColor, serie.symbol.gap, cornerRadius); } } } diff --git a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs b/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs index 8a7d4e4e..10676f04 100644 --- a/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs +++ b/Assets/XCharts/Runtime/Serie/Scatter/BaseScatterHandler.cs @@ -168,6 +168,7 @@ namespace XCharts var highlight = serie.highlighted || serieData.highlighted; var color = SerieHelper.GetItemColor(serie, serieData, theme, colorIndex, highlight); var toColor = SerieHelper.GetItemToColor(serie, serieData, theme, colorIndex, highlight); + var emptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, theme, colorIndex, highlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); double xValue = serieData.GetCurrData(0, dataChangeDuration, xAxis.inverse); @@ -206,14 +207,14 @@ namespace XCharts { var nowSize = symbol.animationSize[count]; color.a = (byte)(255 * (symbolSize - nowSize) / symbolSize); - chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius); + chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, color, toColor, emptyColor, symbol.gap, cornerRadius); } chart.RefreshPainter(serie); } else { if (symbolSize > 100) symbolSize = 100; - chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius); + chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, toColor, emptyColor, symbol.gap, cornerRadius); } } @@ -269,6 +270,7 @@ namespace XCharts var highlight = serie.highlighted || serieData.highlighted; var color = SerieHelper.GetItemColor(serie, serieData, theme, colorIndex, highlight); var toColor = SerieHelper.GetItemToColor(serie, serieData, theme, colorIndex, highlight); + var emptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, theme, colorIndex, highlight, false); var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight); var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight); var xValue = serieData.GetCurrData(0, dataChangeDuration, axis.inverse); @@ -307,14 +309,16 @@ namespace XCharts { var nowSize = symbol.animationSize[count]; color.a = (byte)(255 * (symbolSize - nowSize) / symbolSize); - chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius); + chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, + color, toColor, emptyColor, symbol.gap, cornerRadius); } chart.RefreshPainter(serie); } else { if (symbolSize > 100) symbolSize = 100; - chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius); + chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, + color, toColor, emptyColor, symbol.gap, cornerRadius); } } if (!serie.animation.IsFinish()) diff --git a/Assets/XCharts/Runtime/Serie/Serie.cs b/Assets/XCharts/Runtime/Serie/Serie.cs index 77f496ea..6cc98d73 100644 --- a/Assets/XCharts/Runtime/Serie/Serie.cs +++ b/Assets/XCharts/Runtime/Serie/Serie.cs @@ -50,11 +50,6 @@ namespace XCharts /// </summary> Smooth, /// <summary> - /// the smooth-dash line chart, - /// 平滑虚线。 - /// </summary> - SmoothDash, - /// <summary> /// step line. /// 阶梯线图:当前点。 /// </summary> @@ -68,23 +63,7 @@ namespace XCharts /// step line. /// 阶梯线图:下一个拐点。 /// </summary> - StepEnd, - /// <summary> - /// 虚线 - /// </summary> - Dash, - /// <summary> - /// 点线 - /// </summary> - Dot, - /// <summary> - /// 点划线 - /// </summary> - DashDot, - /// <summary> - /// 双点划线 - /// </summary> - DashDotDot + StepEnd } public enum BarType @@ -294,6 +273,7 @@ namespace XCharts [NonSerialized] private Dictionary<int, List<Vector3>> m_UpSmoothPoints = new Dictionary<int, List<Vector3>>(); [NonSerialized] private Dictionary<int, List<Vector3>> m_DownSmoothPoints = new Dictionary<int, List<Vector3>>(); [NonSerialized] private List<Vector3> m_DataPoints = new List<Vector3>(); + [NonSerialized] private List<bool> m_DataIgnore = new List<bool>(); [NonSerialized] private bool m_NameDirty; /// <summary> @@ -1017,6 +997,7 @@ namespace XCharts /// 数据项位置坐标。 /// </summary> public List<Vector3> dataPoints { get { return m_DataPoints; } } + public List<bool> dataIgnore { get { return m_DataIgnore; } } /// <summary> /// 饼图的中心点位置。 /// </summary> diff --git a/Assets/XCharts/Runtime/Serie/SerieContext.cs b/Assets/XCharts/Runtime/Serie/SerieContext.cs index d974d860..9d84cc9e 100644 --- a/Assets/XCharts/Runtime/Serie/SerieContext.cs +++ b/Assets/XCharts/Runtime/Serie/SerieContext.cs @@ -6,9 +6,21 @@ /************************************************/ using System.Collections.Generic; +using UnityEngine; namespace XCharts { + public struct PointInfo + { + public Vector3 position; + public bool isIgnoreBreak; + + public PointInfo(Vector3 pos, bool ignore) + { + this.position = pos; + this.isIgnoreBreak = ignore; + } + } [System.Serializable] public class SerieContext { @@ -25,5 +37,9 @@ namespace XCharts /// </summary> public List<int> pointerAxisDataIndexs = new List<int>(); + public int vertCount; + + internal int colorIndex; + internal List<PointInfo> drawPoints = new List<PointInfo>(); } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/Serie/SerieData.cs b/Assets/XCharts/Runtime/Serie/SerieData.cs index 955a0165..70df2a6f 100644 --- a/Assets/XCharts/Runtime/Serie/SerieData.cs +++ b/Assets/XCharts/Runtime/Serie/SerieData.cs @@ -32,7 +32,7 @@ namespace XCharts [SerializeField] private List<double> m_Data = new List<double>(); [SerializeField] private List<int> m_Children = new List<int>(); - + public SerieDataContext context = new SerieDataContext(); public ChartLabel labelObject { get; set; } private bool m_Show = true; diff --git a/Assets/XCharts/Runtime/Serie/SerieDataContext.cs b/Assets/XCharts/Runtime/Serie/SerieDataContext.cs index f8100579..ea25d150 100644 --- a/Assets/XCharts/Runtime/Serie/SerieDataContext.cs +++ b/Assets/XCharts/Runtime/Serie/SerieDataContext.cs @@ -11,5 +11,7 @@ using UnityEngine.UI; namespace XCharts { - + public class SerieDataContext + { + } } \ No newline at end of file diff --git a/Assets/XCharts/Runtime/XUGL/UGL.cs b/Assets/XCharts/Runtime/XUGL/UGL.cs index a9d05de8..8a773b07 100644 --- a/Assets/XCharts/Runtime/XUGL/UGL.cs +++ b/Assets/XCharts/Runtime/XUGL/UGL.cs @@ -140,31 +140,70 @@ namespace XUGL } 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; + var ctp = Vector3.zero; + var cbp = Vector3.zero; for (int i = 1; i < points.Count - 1; i++) { + bool bitp = true, bibp = true; UGLHelper.GetLinePoints(points[i - 1], points[i], points[i + 1], width, - ref ltp, ref lbp, ref ntp, ref nbp, ref itp, ref ibp); - + ref ltp, ref lbp, + ref ntp, ref nbp, + ref itp, ref ibp, + ref ctp, ref cbp, + ref bitp, ref bibp); if (i == 1) { - lineLT = ltp; - lineLB = lbp; + vh.AddVert(ltp, color, Vector2.zero); + vh.AddVert(lbp, color, Vector2.zero); + } + if (bitp == bibp) + { + AddVertToVertexHelper(vh, itp, ibp, color); + } + else + { + if (bitp) + { + AddVertToVertexHelper(vh, itp, ctp, color); + AddVertToVertexHelper(vh, itp, cbp, color); + } + else + { + AddVertToVertexHelper(vh, ctp, ibp, color); + AddVertToVertexHelper(vh, cbp, ibp, color); + } } - - DrawQuadrilateral(vh, lineLB, ibp, itp, lineLT, color); - - lineLT = itp; - lineLB = ibp; } - DrawQuadrilateral(vh, lineLB, nbp, ntp, lineLT, color); + AddVertToVertexHelper(vh, ntp, nbp, color); + } + } + + public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top, + Vector3 bottom, Color32 color, bool needTriangle = true) + { + AddVertToVertexHelper(vh, top, bottom, color, color, needTriangle); + } + + public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top, + Vector3 bottom, Color32 topColor, Color32 bottomColor, bool needTriangle = true) + { + var lastVertCount = vh.currentVertCount; + vh.AddVert(top, topColor, Vector2.zero); + vh.AddVert(bottom, bottomColor, Vector2.zero); + if (needTriangle) + { + var indexRt = lastVertCount; + var indexRb = indexRt + 1; + var indexLt = indexRt - 2; + var indexLb = indexLt + 1; + vh.AddTriangle(indexLt, indexRb, indexLb); + vh.AddTriangle(indexLt, indexRt, indexRb); } } @@ -545,14 +584,23 @@ namespace XUGL /// <param name="toColor"></param> public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color32 startColor, Color32 toColor) + { + DrawQuadrilateral(vh, p1, p2, p3, p4, startColor, startColor, toColor, toColor); + } + + public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, + Color32 color1, Color32 color2, Color32 color3, Color32 color4) { s_Vertex[0].position = p1; s_Vertex[1].position = p2; s_Vertex[2].position = p3; s_Vertex[3].position = p4; + s_Vertex[0].color = color1; + s_Vertex[1].color = color2; + s_Vertex[2].color = color3; + s_Vertex[3].color = color4; for (int j = 0; j < 4; j++) { - s_Vertex[j].color = j >= 2 ? toColor : startColor; s_Vertex[j].uv0 = s_ZeroVector2; } vh.AddUIVertexQuad(s_Vertex); @@ -1673,20 +1721,19 @@ namespace XUGL var ep = points[i + 1]; var lsp = i > 0 ? points[i - 1] : sp; var nep = i < points.Count - 2 ? points[i + 2] : ep; + var smoothness2 = smoothness; 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); } + if (isYAxis) + UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness2); else - { - UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness); - } + UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2); + DrawCurvesInternal(vh, s_CurvesPosList, width, color, currProgress, isYAxis); } } @@ -1702,6 +1749,11 @@ namespace XUGL var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth; var startUp = start - diff; var startDn = start + diff; + var toUp = Vector3.zero; + var toDn = Vector3.zero; + + var lastVertCount = vh.currentVertCount; + AddVertToVertexHelper(vh, startUp, startDn, lineColor, false); for (int i = 1; i < curvesPosList.Count; i++) { to = curvesPosList[i]; @@ -1714,13 +1766,16 @@ namespace XUGL } diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth; - var toUp = to - diff; - var toDn = to + diff; - DrawQuadrilateral(vh, startUp, toUp, toDn, startDn, lineColor); + toUp = to - diff; + toDn = to + diff; + + AddVertToVertexHelper(vh, toUp, toDn, lineColor); + startUp = toUp; startDn = toDn; start = to; } + AddVertToVertexHelper(vh, toUp, toDn, lineColor); } } } diff --git a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs b/Assets/XCharts/Runtime/XUGL/UGLHelper.cs index 3cb96ca3..7e419e0f 100644 --- a/Assets/XCharts/Runtime/XUGL/UGLHelper.cs +++ b/Assets/XCharts/Runtime/XUGL/UGLHelper.cs @@ -288,29 +288,43 @@ namespace XUGL 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) + ref Vector3 itp, ref Vector3 ibp, + ref Vector3 clp, ref Vector3 crp, + ref bool bitp, ref bool bibp + ) { 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; + ltp = lp - dir1v * width; + lbp = lp + dir1v * width; - ntp = np + dir2v * width; - nbp = np - dir2v * 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; + clp = cp - dir2v * width; + crp = cp + dir2v * width; + var ldist = (Vector3.Distance(cp, lp) + 1) * dir1; + var rdist = (Vector3.Distance(cp, np) + 1) * dir2; + + bitp = true; if (!UGLHelper.GetIntersection(ltp, ltp + ldist, ntp, ntp + rdist, ref itp)) { - itp = cp + dir1v * width; + itp = cp - dir1v * width; + clp = cp - dir1v * width; + crp = cp - dir2v * width; + bitp = false; } + bibp = true; if (!UGLHelper.GetIntersection(lbp, lbp + ldist, nbp, nbp + rdist, ref ibp)) { - ibp = cp - dir1v * width; + ibp = cp + dir1v * width; + clp = cp + dir1v * width; + crp = cp + dir2v * width; + bibp = false; } } } diff --git a/ProjectSettings/QualitySettings.asset b/ProjectSettings/QualitySettings.asset index b60be20a..f4008a1b 100644 --- a/ProjectSettings/QualitySettings.asset +++ b/ProjectSettings/QualitySettings.asset @@ -166,7 +166,7 @@ QualitySettings: softVegetation: 1 realtimeReflectionProbes: 1 billboardsFaceCameraPosition: 1 - vSyncCount: 1 + vSyncCount: 0 lodBias: 2 maximumLODLevel: 0 particleRaycastBudget: 4096