using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using XUGL; namespace XCharts.Runtime { [UnityEngine.Scripting.Preserve] internal sealed class ParallelHandler : SerieHandler { private List m_Points = new List(); public override void Update() { base.Update(); UpdateSerieContext(); } public override void DrawSerie(VertexHelper vh) { DrawParallelSerie(vh, serie); } private void UpdateSerieContext() { } private void DrawParallelSerie(VertexHelper vh, Parallel serie) { if (!serie.show) return; if (serie.animation.HasFadeOut()) return; var parallel = chart.GetChartComponent(serie.parallelIndex); if (parallel == null) return; var axisCount = parallel.context.parallelAxes.Count; if (axisCount <= 0) return; var animationIndex = serie.animation.GetCurrIndex(); var isHorizonal = parallel.orient == Orient.Horizonal; var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.context.colorIndex, false); var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth); float currDetailProgress = !isHorizonal ? parallel.context.x : parallel.context.y; float totalDetailProgress = !isHorizonal ? parallel.context.x + parallel.context.width : parallel.context.y + parallel.context.height; serie.animation.InitProgress(currDetailProgress, totalDetailProgress); serie.context.dataPoints.Clear(); serie.containerIndex = parallel.index; serie.containterInstanceId = parallel.instanceId; var currProgress = serie.animation.GetCurrDetail(); var isSmooth = serie.lineType == LineType.Smooth; foreach (var serieData in serie.data) { m_Points.Clear(); var count = Mathf.Min(axisCount, serieData.data.Count); var lp = Vector3.zero; for (int i = 0; i < count; i++) { if (animationIndex >= 0 && i > animationIndex) continue; var pos = GetPos(parallel, i, serieData.data[i], isHorizonal); if (!isHorizonal) { if (isSmooth) { m_Points.Add(pos); } else if (pos.x <= currProgress) { m_Points.Add(pos); } else { var currProgressStart = new Vector3(currProgress, parallel.context.y - 50); var currProgressEnd = new Vector3(currProgress, parallel.context.y + parallel.context.height + 50); var intersectionPos = Vector3.zero; if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) m_Points.Add(intersectionPos); else m_Points.Add(pos); break; } } else { if (isSmooth) { m_Points.Add(pos); } else if (pos.y <= currProgress) { m_Points.Add(pos); } else { var currProgressStart = new Vector3(parallel.context.x - 50, currProgress); var currProgressEnd = new Vector3(parallel.context.x + parallel.context.width + 50, currProgress); var intersectionPos = Vector3.zero; if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos)) m_Points.Add(intersectionPos); else m_Points.Add(pos); break; } } lp = pos; } if (isSmooth) UGL.DrawCurves(vh, m_Points, lineWidth, lineColor, chart.settings.lineSmoothness, currProgress, isHorizonal); else UGL.DrawLine(vh, m_Points, lineWidth, lineColor, isSmooth); } if (!serie.animation.IsFinish()) { serie.animation.CheckProgress(totalDetailProgress - currDetailProgress); chart.RefreshPainter(serie); } } private static ParallelAxis GetAxis(ParallelCoord parallel, int index) { if (index >= 0 && index < parallel.context.parallelAxes.Count) return parallel.context.parallelAxes[index]; else return null; } private static Vector3 GetPos(ParallelCoord parallel, int axisIndex, double dataValue, bool isHorizonal) { var axis = GetAxis(parallel, axisIndex); if (axis == null) return Vector3.zero; var sValueDist = axis.GetDistance(dataValue, axis.context.width); return new Vector3( isHorizonal ? axis.context.x + sValueDist : axis.context.x, isHorizonal ? axis.context.y : axis.context.y + sValueDist); } } }