using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using XUGL; namespace XCharts.Runtime { [UnityEngine.Scripting.Preserve] internal sealed class MarkAreaHandler : MainComponentHandler { private GameObject m_MarkLineLabelRoot; private bool m_NeedUpdateLabelPosition; public override void InitComponent() { m_MarkLineLabelRoot = ChartHelper.AddObject("markarea" + component.index, chart.transform, chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta); m_MarkLineLabelRoot.hideFlags = chart.chartHideFlags; ChartHelper.HideAllObject(m_MarkLineLabelRoot); InitMarkArea(component); } public override void DrawBase(VertexHelper vh) { DrawMarkArea(vh, component); } public override void Update() { if (m_NeedUpdateLabelPosition) { m_NeedUpdateLabelPosition = false; if (component.runtimeLabel != null) { component.runtimeLabel.SetPosition(component.runtimeLabelPosition); } } } private void InitMarkArea(MarkArea markArea) { markArea.painter = chart.m_PainterTop; markArea.refreshComponent = delegate() { var label = ChartHelper.AddChartLabel("label", m_MarkLineLabelRoot.transform, markArea.label, chart.theme.axis, component.text, Color.clear, TextAnchor.MiddleCenter); UpdateRuntimeData(component); label.SetActive(markArea.label.show); label.SetPosition(component.runtimeLabelPosition); label.SetText(component.text); markArea.runtimeLabel = label; }; markArea.refreshComponent(); } private void DrawMarkArea(VertexHelper vh, MarkArea markArea) { if (!markArea.show) return; var serie = chart.GetSerie(markArea.serieIndex); if (serie == null || !serie.show || !markArea.show) return; UpdateRuntimeData(markArea); var colorIndex = chart.GetLegendRealShowNameIndex(serie.legendName); var serieColor = SerieHelper.GetLineColor(serie, null, chart.theme, colorIndex, false); var areaColor = markArea.itemStyle.GetColor(serieColor); UGL.DrawRectangle(vh, markArea.runtimeRect, areaColor, areaColor); } private void UpdateRuntimeData(MarkArea markArea) { var serie = chart.GetSerie(markArea.serieIndex); if (serie == null || !serie.show || !markArea.show) return; var yAxis = chart.GetChartComponent(serie.yAxisIndex); var xAxis = chart.GetChartComponent(serie.xAxisIndex); var grid = chart.GetChartComponent(xAxis.gridIndex); var dataZoom = chart.GetDataZoomOfAxis(xAxis); var showData = serie.GetDataList(dataZoom); var lt = GetPosition(markArea.start, serie, dataZoom, xAxis, yAxis, grid, showData, true); var rb = GetPosition(markArea.end, serie, dataZoom, xAxis, yAxis, grid, showData, false); var lb = new Vector3(lt.x, rb.y); markArea.runtimeRect = new Rect(lb.x, lb.y, rb.x - lb.x, lt.y - lb.y); UpdateLabelPosition(markArea); } private void UpdateLabelPosition(MarkArea markArea) { if (!markArea.label.show) return; m_NeedUpdateLabelPosition = true; var rect = markArea.runtimeRect; switch (markArea.label.position) { case LabelStyle.Position.Center: markArea.runtimeLabelPosition = rect.center; break; case LabelStyle.Position.Left: markArea.runtimeLabelPosition = rect.center + new Vector2(rect.width / 2, 0); break; case LabelStyle.Position.Right: markArea.runtimeLabelPosition = rect.center - new Vector2(rect.width / 2, 0); break; case LabelStyle.Position.Top: markArea.runtimeLabelPosition = rect.center + new Vector2(0, rect.height / 2); break; case LabelStyle.Position.Bottom: markArea.runtimeLabelPosition = rect.center - new Vector2(0, rect.height / 2); break; default: markArea.runtimeLabelPosition = rect.center + new Vector2(0, rect.height / 2); break; } markArea.runtimeLabelPosition += markArea.label.offset; } private Vector3 GetPosition(MarkAreaData data, Serie serie, DataZoom dataZoom, XAxis xAxis, YAxis yAxis, GridCoord grid, List showData, bool start) { var pos = Vector3.zero; switch (data.type) { case MarkAreaType.Min: data.runtimeValue = SerieHelper.GetMinData(serie, data.dimension, dataZoom); return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); case MarkAreaType.Max: data.runtimeValue = SerieHelper.GetMaxData(serie, data.dimension, dataZoom); return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); case MarkAreaType.Average: data.runtimeValue = SerieHelper.GetAverageData(serie, data.dimension, dataZoom); return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); case MarkAreaType.Median: data.runtimeValue = SerieHelper.GetMedianData(serie, data.dimension, dataZoom); return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); case MarkAreaType.None: if (data.xPosition != 0 || data.yPosition != 0) { var pX = grid.context.x + data.xPosition; var pY = grid.context.y + data.yPosition; return new Vector3(pX, pY); } else if (data.yValue != 0) { data.runtimeValue = data.yValue; if (yAxis.IsCategory()) { var pY = AxisHelper.GetAxisPosition(grid, yAxis, data.yValue, showData.Count, dataZoom); return start ? new Vector3(grid.context.x, pY) : new Vector3(grid.context.x + grid.context.width, pY); } else { return GetPosition(xAxis, yAxis, grid, data.runtimeValue, start); } } else { data.runtimeValue = data.xValue; if (xAxis.IsCategory()) { var pX = AxisHelper.GetAxisPosition(grid, xAxis, data.xValue, showData.Count, dataZoom); return start ? new Vector3(pX, grid.context.y + grid.context.height) : new Vector3(pX, grid.context.y); } else { return GetPosition(xAxis, yAxis, grid, data.xValue, start); } } default: break; } return pos; } private Vector3 GetPosition(Axis xAxis, Axis yAxis, GridCoord grid, double value, bool start) { if (yAxis.IsCategory()) { var pX = AxisHelper.GetAxisPosition(grid, xAxis, value); return start ? new Vector3(pX, grid.context.y + grid.context.height) : new Vector3(pX, grid.context.y); } else { var pY = AxisHelper.GetAxisPosition(grid, yAxis, value); return start ? new Vector3(grid.context.x, pY + grid.context.height) : new Vector3(grid.context.x + grid.context.width, pY); } } } }