/******************************************/ /* */ /* Copyright (c) 2018 monitor1394 */ /* https://github.com/monitor1394 */ /* */ /******************************************/ using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System.Text; using UnityEngine.EventSystems; namespace XCharts { public partial class CoordinateChart : BaseChart { private static readonly string s_DefaultDataZoom = "datazoom"; private static readonly string s_DefaultAxisName = "name"; [SerializeField] protected Grid m_Grid = Grid.defaultGrid; [SerializeField] protected List m_XAxises = new List(); [SerializeField] protected List m_YAxises = new List(); [SerializeField] protected DataZoom m_DataZoom = DataZoom.defaultDataZoom; [SerializeField] protected VisualMap m_VisualMap = new VisualMap(); protected float m_CoordinateX; protected float m_CoordinateY; protected float m_CoordinateWidth; protected float m_CoordinateHeight; private bool m_DataZoomDrag; private bool m_DataZoomCoordinateDrag; private bool m_DataZoomStartDrag; private bool m_DataZoomEndDrag; private float m_DataZoomLastStartIndex; private float m_DataZoomLastEndIndex; private bool m_CheckMinMaxValue; private bool m_CheckDataZoomLabel; private bool m_XAxisesDirty; private bool m_YAxisesDirty; private Dictionary> m_StackSeries = new Dictionary>(); private List m_SeriesCurrHig = new List(); protected override void Awake() { base.Awake(); m_CheckMinMaxValue = false; InitDefaultAxises(); CheckMinMaxValue(); InitDataZoom(); InitAxisX(); InitAxisY(); m_Tooltip.UpdateToTop(); } protected override void Update() { CheckMinMaxValue(); CheckRaycastTarget(); CheckDataZoom(); CheckVisualMap(); base.Update(); } protected override void CheckComponent() { if (m_DataZoom.anyDirty) { if (m_DataZoom.componentDirty) InitDataZoom(); if (m_DataZoom.vertsDirty) RefreshChart(); m_DataZoom.ClearDirty(); } if (m_VisualMap.anyDirty) { if (m_VisualMap.vertsDirty) RefreshChart(); m_VisualMap.ClearDirty(); } if (m_Grid.anyDirty) { if (m_Grid.componentDirty) { m_XAxisesDirty = true; m_YAxisesDirty = true; OnCoordinateChanged(); } if (m_Grid.vertsDirty) RefreshChart(); m_Grid.ClearDirty(); } for (int i = 0; i < m_XAxises.Count; i++) { var axis = m_XAxises[i]; if (m_XAxisesDirty || axis.anyDirty) { if (axis.componentDirty || m_XAxisesDirty) InitXAxis(i, axis); if (axis.vertsDirty || m_XAxisesDirty) RefreshChart(); axis.ClearDirty(); } } for (int i = 0; i < m_YAxises.Count; i++) { var axis = m_YAxises[i]; if (m_YAxisesDirty || axis.anyDirty) { if (axis.componentDirty || m_YAxisesDirty) InitYAxis(i, axis); if (axis.vertsDirty || m_YAxisesDirty) RefreshChart(); axis.ClearDirty(); } } m_XAxisesDirty = false; m_YAxisesDirty = false; base.CheckComponent(); } #if UNITY_EDITOR protected override void Reset() { base.Reset(); m_Grid = Grid.defaultGrid; m_XAxises.Clear(); m_YAxises.Clear(); Awake(); } protected override void OnValidate() { base.OnValidate(); m_XAxisesDirty = true; m_YAxisesDirty = true; m_Grid.SetAllDirty(); m_DataZoom.SetAllDirty(); m_VisualMap.SetAllDirty(); } #endif protected override void DrawChart(VertexHelper vh) { base.DrawChart(vh); DrawCoordinate(vh); DrawSerie(vh); DrawAxisTick(vh); DrawDataZoomSlider(vh); DrawVisualMap(vh); } protected override void DrawBackground(VertexHelper vh) { if (SeriesHelper.IsAnyClipSerie(m_Series)) { var xLineDiff = xAxis0.axisLine.width; var yLineDiff = yAxis0.axisLine.width; var xSplitDiff = xAxis0.splitLine.lineStyle.width; var ySplitDiff = yAxis0.splitLine.lineStyle.width; var cpty = m_CoordinateY + m_CoordinateHeight + ySplitDiff; var cp1 = new Vector3(m_CoordinateX - yLineDiff, m_CoordinateY - xLineDiff); var cp2 = new Vector3(m_CoordinateX - yLineDiff, cpty); var cp3 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, cpty); var cp4 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_CoordinateY - xLineDiff); var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background); ChartDrawer.DrawPolygon(vh, cp1, cp2, cp3, cp4, backgroundColor); } else { base.DrawBackground(vh); } } protected void DrawClip(VertexHelper vh) { if (!SeriesHelper.IsAnyClipSerie(m_Series)) return; var xLineDiff = xAxis0.axisLine.width; var yLineDiff = yAxis0.axisLine.width; var xSplitDiff = xAxis0.splitLine.lineStyle.width; var ySplitDiff = yAxis0.splitLine.lineStyle.width; var backgroundColor = ThemeHelper.GetBackgroundColor(m_ThemeInfo, m_Background); var lp1 = new Vector3(m_ChartX, m_ChartY); var lp2 = new Vector3(m_ChartX, m_ChartY + chartHeight); var lp3 = new Vector3(m_CoordinateX - yLineDiff, m_ChartY + chartHeight); var lp4 = new Vector3(m_CoordinateX - yLineDiff, m_ChartY); ChartDrawer.DrawPolygon(vh, lp1, lp2, lp3, lp4, backgroundColor); var rp1 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_ChartY); var rp2 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_ChartY + chartHeight); var rp3 = new Vector3(m_ChartX + chartWidth, m_ChartY + chartHeight); var rp4 = new Vector3(m_ChartX + chartWidth, m_ChartY); ChartDrawer.DrawPolygon(vh, rp1, rp2, rp3, rp4, backgroundColor); var up1 = new Vector3(m_CoordinateX - yLineDiff, m_CoordinateY + m_CoordinateHeight + ySplitDiff); var up2 = new Vector3(m_CoordinateX - yLineDiff, m_ChartY + chartHeight); var up3 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_ChartY + chartHeight); var up4 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_CoordinateY + m_CoordinateHeight + ySplitDiff); ChartDrawer.DrawPolygon(vh, up1, up2, up3, up4, backgroundColor); var dp1 = new Vector3(m_CoordinateX - yLineDiff, m_ChartY); var dp2 = new Vector3(m_CoordinateX - yLineDiff, m_CoordinateY - xLineDiff); var dp3 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_CoordinateY - xLineDiff); var dp4 = new Vector3(m_CoordinateX + m_CoordinateWidth + xSplitDiff, m_ChartY); ChartDrawer.DrawPolygon(vh, dp1, dp2, dp3, dp4, backgroundColor); } protected virtual void DrawSerie(VertexHelper vh) { base.DrawChart(vh); if (!m_CheckMinMaxValue) return; m_IsPlayingAnimation = false; bool yCategory = m_YAxises[0].IsCategory() || m_YAxises[1].IsCategory(); SeriesHelper.GetStackSeries(m_Series, ref m_StackSeries); int seriesCount = m_StackSeries.Count; m_BarLastOffset = 0; for (int j = 0; j < seriesCount; j++) { var serieList = m_StackSeries[j]; m_SeriesCurrHig.Clear(); for (int n = 0; n < serieList.Count; n++) { Serie serie = serieList[n]; serie.dataPoints.Clear(); var colorIndex = m_LegendRealShowName.IndexOf(serie.legendName); switch (serie.type) { case SerieType.Line: if (yCategory) DrawYLineSerie(vh, serie, colorIndex, ref m_SeriesCurrHig); else DrawXLineSerie(vh, serie, colorIndex, ref m_SeriesCurrHig); break; case SerieType.Bar: if (yCategory) DrawYBarSerie(vh, serie, colorIndex, ref m_SeriesCurrHig); else DrawXBarSerie(vh, serie, colorIndex, ref m_SeriesCurrHig); break; case SerieType.Scatter: case SerieType.EffectScatter: DrawScatterSerie(vh, colorIndex, serie); break; case SerieType.Heatmap: DrawHeatmapSerie(vh, colorIndex, serie); break; } } } DrawClip(vh); DrawLabelBackground(vh); DrawLinePoint(vh); DrawLineArrow(vh); if (yCategory) DrawYTooltipIndicator(vh); else DrawXTooltipIndicator(vh); } protected override void CheckTootipArea(Vector2 local) { if (!IsInCooridate(local)) { m_Tooltip.ClearValue(); UpdateTooltip(); } else { var isCartesian = IsValue(); int dataCount = m_Series.list.Count > 0 ? m_Series.list[0].GetDataList(dataZoom).Count : 0; for (int i = 0; i < m_XAxises.Count; i++) { var xAxis = m_XAxises[i]; var yAxis = m_YAxises[i]; if (!xAxis.show && !yAxis.show) continue; if (isCartesian && xAxis.show && yAxis.show) { var yRate = (yAxis.runtimeMaxValue - yAxis.runtimeMinValue) / m_CoordinateHeight; var xRate = (xAxis.runtimeMaxValue - xAxis.runtimeMinValue) / m_CoordinateWidth; var yValue = yRate * (local.y - m_CoordinateY - yAxis.runtimeZeroYOffset); if (yAxis.runtimeMinValue > 0) yValue += yAxis.runtimeMinValue; m_Tooltip.runtimeYValues[i] = yValue; var xValue = xRate * (local.x - m_CoordinateX - xAxis.runtimeZeroXOffset); if (xAxis.runtimeMinValue > 0) xValue += xAxis.runtimeMinValue; m_Tooltip.runtimeXValues[i] = xValue; for (int j = 0; j < m_Series.Count; j++) { var serie = m_Series.GetSerie(j); for (int n = 0; n < serie.data.Count; n++) { var serieData = serie.data[n]; var xdata = serieData.GetData(0, xAxis.inverse); var ydata = serieData.GetData(1, yAxis.inverse); var symbolSize = serie.symbol.GetSize(serieData == null ? null : serieData.data); if (Mathf.Abs(xValue - xdata) / xRate < symbolSize && Mathf.Abs(yValue - ydata) / yRate < symbolSize) { m_Tooltip.runtimeDataIndex[i] = n; serieData.highlighted = true; } else { serieData.highlighted = false; } } } } else if (IsCategory()) { for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++) { float splitWid = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); float pX = m_CoordinateX + j * splitWid; if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || (!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) { m_Tooltip.runtimeXValues[i] = j; m_Tooltip.runtimeDataIndex[i] = j; break; } } for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++) { float splitWid = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); float pY = m_CoordinateY + j * splitWid; if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || (!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) { m_Tooltip.runtimeYValues[i] = j; break; } } } else if (xAxis.IsCategory()) { var value = (yAxis.runtimeMaxValue - yAxis.runtimeMinValue) * (local.y - m_CoordinateY - yAxis.runtimeZeroYOffset) / m_CoordinateHeight; if (yAxis.runtimeMinValue > 0) value += yAxis.runtimeMinValue; m_Tooltip.runtimeYValues[i] = value; for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++) { float splitWid = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); float pX = m_CoordinateX + j * splitWid; if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || (!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) { m_Tooltip.runtimeXValues[i] = j; m_Tooltip.runtimeDataIndex[i] = j; break; } } } else if (yAxis.IsCategory()) { var value = (xAxis.runtimeMaxValue - xAxis.runtimeMinValue) * (local.x - m_CoordinateX - xAxis.runtimeZeroXOffset) / m_CoordinateWidth; if (xAxis.runtimeMinValue > 0) value += xAxis.runtimeMinValue; m_Tooltip.runtimeXValues[i] = value; for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++) { float splitWid = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); float pY = m_CoordinateY + j * splitWid; if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || (!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) { m_Tooltip.runtimeYValues[i] = j; m_Tooltip.runtimeDataIndex[i] = j; break; } } } } } if (m_Tooltip.IsSelected()) { m_Tooltip.UpdateContentPos(new Vector2(local.x + 18, local.y - 25)); UpdateTooltip(); if (m_Tooltip.IsDataIndexChanged() || m_Tooltip.type == Tooltip.Type.Corss) { m_Tooltip.UpdateLastDataIndex(); RefreshChart(); } } else if (m_Tooltip.IsActive()) { m_Tooltip.SetActive(false); RefreshChart(); } } protected StringBuilder sb = new StringBuilder(100); protected override void UpdateTooltip() { base.UpdateTooltip(); int index; Axis tempAxis; bool isCartesian = IsValue(); if (isCartesian) { index = m_Tooltip.runtimeDataIndex[0]; tempAxis = m_XAxises[0]; } else if (m_XAxises[0].type == Axis.AxisType.Value) { index = (int)m_Tooltip.runtimeYValues[0]; tempAxis = m_YAxises[0]; } else { index = (int)m_Tooltip.runtimeXValues[0]; tempAxis = m_XAxises[0]; } if (index < 0) { if (m_Tooltip.IsActive()) { m_Tooltip.SetActive(false); RefreshChart(); } return; } var category = tempAxis.GetData(index, m_DataZoom); var content = TooltipHelper.GetFormatterContent(m_Tooltip, index, m_Series, m_ThemeInfo, category, m_DataZoom, isCartesian); TooltipHelper.SetContentAndPosition(m_Tooltip, content, chartRect); m_Tooltip.SetActive(true); for (int i = 0; i < m_XAxises.Count; i++) { UpdateAxisTooltipLabel(i, m_XAxises[i]); } for (int i = 0; i < m_YAxises.Count; i++) { UpdateAxisTooltipLabel(i, m_YAxises[i]); } } protected void UpdateAxisTooltipLabel(int axisIndex, Axis axis) { var showTooltipLabel = axis.show && m_Tooltip.type == Tooltip.Type.Corss; axis.SetTooltipLabelActive(showTooltipLabel); if (!showTooltipLabel) return; string labelText = ""; Vector2 labelPos = Vector2.zero; if (axis is XAxis) { var posY = axisIndex > 0 ? m_CoordinateY + m_CoordinateHeight : m_CoordinateY; var diff = axisIndex > 0 ? -axis.axisLabel.fontSize - axis.axisLabel.margin - 3.5f : axis.axisLabel.margin / 2 + 1; if (axis.IsValue()) { labelText = ChartCached.NumberToStr(m_Tooltip.runtimeXValues[axisIndex], axis.axisLabel.numericFormatter); labelPos = new Vector2(m_Tooltip.runtimePointerPos.x, posY - diff); } else { labelText = axis.GetData((int)m_Tooltip.runtimeXValues[axisIndex], m_DataZoom); float splitWidth = AxisHelper.GetSplitWidth(axis, m_CoordinateWidth, m_DataZoom); int index = (int)m_Tooltip.runtimeXValues[axisIndex]; float px = m_CoordinateX + index * splitWidth + (axis.boundaryGap ? splitWidth / 2 : 0) + 0.5f; labelPos = new Vector2(px, posY - diff); } } else if (axis is YAxis) { var posX = axisIndex > 0 ? m_CoordinateX + m_CoordinateWidth : m_CoordinateX; var diff = axisIndex > 0 ? -axis.axisLabel.margin + 3 : axis.axisLabel.margin - 3; if (axis.IsValue()) { labelText = ChartCached.NumberToStr(m_Tooltip.runtimeYValues[axisIndex], axis.axisLabel.numericFormatter); labelPos = new Vector2(posX - diff, m_Tooltip.runtimePointerPos.y); } else { labelText = axis.GetData((int)m_Tooltip.runtimeYValues[axisIndex], m_DataZoom); float splitWidth = AxisHelper.GetSplitWidth(axis, m_CoordinateHeight, m_DataZoom); int index = (int)m_Tooltip.runtimeYValues[axisIndex]; float py = m_CoordinateY + index * splitWidth + (axis.boundaryGap ? splitWidth / 2 : 0); labelPos = new Vector2(posX - diff, py); } } axis.UpdateTooptipLabelText(labelText); axis.UpdateTooltipLabelPos(labelPos); } protected override void OnThemeChanged() { base.OnThemeChanged(); m_DataZoom.SetAllDirty(); m_XAxisesDirty = true; m_YAxisesDirty = true; } private void InitDefaultAxises() { if (m_XAxises.Count <= 0) { var axis1 = XAxis.defaultXAxis; var axis2 = XAxis.defaultXAxis; axis1.show = true; axis2.show = false; m_XAxises.Add(axis1); m_XAxises.Add(axis2); } if (m_YAxises.Count <= 0) { var axis1 = YAxis.defaultYAxis; var axis2 = YAxis.defaultYAxis; axis1.show = true; axis1.splitNumber = 5; axis1.boundaryGap = false; axis2.show = false; m_YAxises.Add(axis1); m_YAxises.Add(axis2); } foreach (var axis in m_XAxises) axis.runtimeMinValue = axis.runtimeMaxValue = 0; foreach (var axis in m_YAxises) axis.runtimeMinValue = axis.runtimeMaxValue = 0; } private void InitAxisY() { for (int i = 0; i < m_YAxises.Count; i++) { InitYAxis(i, m_YAxises[i]); } } private void InitYAxis(int yAxisIndex, YAxis yAxis) { yAxis.axisLabelTextList.Clear(); string objName = ChartCached.GetYAxisName(yAxisIndex); var axisObj = ChartHelper.AddObject(objName, transform, chartAnchorMin, chartAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight)); axisObj.transform.localPosition = Vector3.zero; axisObj.SetActive(yAxis.show && yAxis.axisLabel.show); axisObj.hideFlags = chartHideFlags; ChartHelper.HideAllObject(axisObj); var labelColor = ChartHelper.IsClearColor(yAxis.axisLabel.color) ? (Color)m_ThemeInfo.axisTextColor : yAxis.axisLabel.color; int splitNumber = AxisHelper.GetSplitNumber(yAxis, m_CoordinateHeight, m_DataZoom); float totalWidth = 0; for (int i = 0; i < splitNumber; i++) { Text txt; bool inside = yAxis.axisLabel.inside; if ((inside && yAxisIndex == 0) || (!inside && yAxisIndex == 1)) { txt = ChartHelper.AddTextObject(objName + i, axisObj.transform, m_ThemeInfo.font, labelColor, TextAnchor.MiddleLeft, Vector2.zero, Vector2.zero, new Vector2(0, 0.5f), new Vector2(m_Grid.left, 20), yAxis.axisLabel.fontSize, yAxis.axisLabel.rotate, yAxis.axisLabel.fontStyle); } else { txt = ChartHelper.AddTextObject(objName + i, axisObj.transform, m_ThemeInfo.font, labelColor, TextAnchor.MiddleRight, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f), new Vector2(m_Grid.left, 20), yAxis.axisLabel.fontSize, yAxis.axisLabel.rotate, yAxis.axisLabel.fontStyle); } float labelWidth = AxisHelper.GetScaleWidth(yAxis, m_CoordinateHeight, i, m_DataZoom); if (i == 0) yAxis.axisLabel.SetRelatedText(txt, labelWidth); txt.transform.localPosition = GetLabelYPosition(totalWidth + (yAxis.boundaryGap ? labelWidth / 2 : 0), i, yAxisIndex, yAxis); var isPercentStack = SeriesHelper.IsPercentStack(m_Series, SerieType.Bar); txt.text = AxisHelper.GetLabelName(yAxis, m_CoordinateHeight, i, yAxis.runtimeMinValue, yAxis.runtimeMaxValue, m_DataZoom, isPercentStack); txt.gameObject.SetActive(yAxis.show && (yAxis.axisLabel.interval == 0 || i % (yAxis.axisLabel.interval + 1) == 0)); yAxis.axisLabelTextList.Add(txt); totalWidth += labelWidth; } if (yAxis.axisName.show) { var color = ChartHelper.IsClearColor(yAxis.axisName.color) ? (Color)m_ThemeInfo.axisTextColor : yAxis.axisName.color; var fontSize = yAxis.axisName.fontSize; var offset = yAxis.axisName.offset; Text axisName = null; var zeroPos = new Vector3(m_CoordinateX + m_XAxises[yAxisIndex].runtimeZeroXOffset, m_CoordinateY); switch (yAxis.axisName.location) { case AxisName.Location.Start: axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, m_ThemeInfo.font, color, TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), fontSize, yAxis.axisName.rotate, yAxis.axisName.fontStyle); axisName.transform.localPosition = yAxisIndex > 0 ? new Vector2(m_CoordinateX + m_CoordinateWidth + offset.x, m_CoordinateY - offset.y) : new Vector2(zeroPos.x + offset.x, m_CoordinateY - offset.y); break; case AxisName.Location.Middle: axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, m_ThemeInfo.font, color, TextAnchor.MiddleRight, new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(100, 20), fontSize, yAxis.axisName.rotate, yAxis.axisName.fontStyle); axisName.transform.localPosition = yAxisIndex > 0 ? new Vector2(m_CoordinateX + m_CoordinateWidth - offset.x, m_CoordinateY + m_CoordinateHeight / 2 + offset.y) : new Vector2(m_CoordinateX - offset.x, m_CoordinateY + m_CoordinateHeight / 2 + offset.y); break; case AxisName.Location.End: axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, m_ThemeInfo.font, color, TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), fontSize, yAxis.axisName.rotate, yAxis.axisName.fontStyle); axisName.transform.localPosition = yAxisIndex > 0 ? new Vector2(m_CoordinateX + m_CoordinateWidth + offset.x, m_CoordinateY + m_CoordinateHeight + offset.y) : new Vector2(zeroPos.x + offset.x, m_CoordinateY + m_CoordinateHeight + offset.y); break; } axisName.text = yAxis.axisName.name; } //init tooltip label if (m_Tooltip.runtimeGameObject) { Vector2 privot = yAxisIndex > 0 ? new Vector2(0, 0.5f) : new Vector2(1, 0.5f); var labelParent = m_Tooltip.runtimeGameObject.transform; GameObject labelObj = ChartHelper.AddTooltipLabel(ChartCached.GetAxisTooltipLabel(objName), labelParent, m_ThemeInfo.font, privot); yAxis.SetTooltipLabel(labelObj); yAxis.SetTooltipLabelColor(m_ThemeInfo.tooltipBackgroundColor, m_ThemeInfo.tooltipTextColor); yAxis.SetTooltipLabelActive(yAxis.show && m_Tooltip.show && m_Tooltip.type == Tooltip.Type.Corss); } } private void InitAxisX() { for (int i = 0; i < m_XAxises.Count; i++) { InitXAxis(i, m_XAxises[i]); } } private void InitXAxis(int xAxisIndex, XAxis xAxis) { xAxis.axisLabelTextList.Clear(); string objName = ChartCached.GetXAxisName(xAxisIndex); var axisObj = ChartHelper.AddObject(objName, transform, chartAnchorMin, chartAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight)); axisObj.transform.localPosition = Vector3.zero; axisObj.SetActive(xAxis.show && xAxis.axisLabel.show); axisObj.hideFlags = chartHideFlags; ChartHelper.HideAllObject(axisObj); var labelColor = ChartHelper.IsClearColor(xAxis.axisLabel.color) ? (Color)m_ThemeInfo.axisTextColor : xAxis.axisLabel.color; int splitNumber = AxisHelper.GetSplitNumber(xAxis, m_CoordinateWidth, m_DataZoom); float totalWidth = 0; for (int i = 0; i < splitNumber; i++) { float labelWidth = AxisHelper.GetScaleWidth(xAxis, m_CoordinateWidth, i, m_DataZoom); bool inside = xAxis.axisLabel.inside; Text txt = ChartHelper.AddTextObject(ChartCached.GetXAxisName(xAxisIndex, i), axisObj.transform, m_ThemeInfo.font, labelColor, TextAnchor.MiddleCenter, new Vector2(0, 1), new Vector2(0, 1), new Vector2(1, 0.5f), new Vector2(labelWidth, 20), xAxis.axisLabel.fontSize, xAxis.axisLabel.rotate, xAxis.axisLabel.fontStyle); if (i == 0) xAxis.axisLabel.SetRelatedText(txt, labelWidth); txt.transform.localPosition = GetLabelXPosition(totalWidth + (xAxis.boundaryGap ? labelWidth : labelWidth / 2), i, xAxisIndex, xAxis); totalWidth += labelWidth; var isPercentStack = SeriesHelper.IsPercentStack(m_Series, SerieType.Bar); txt.text = AxisHelper.GetLabelName(xAxis, m_CoordinateWidth, i, xAxis.runtimeMinValue, xAxis.runtimeMaxValue, m_DataZoom, isPercentStack); txt.gameObject.SetActive(xAxis.show && (xAxis.axisLabel.interval == 0 || i % (xAxis.axisLabel.interval + 1) == 0)); xAxis.axisLabelTextList.Add(txt); } if (xAxis.axisName.show) { var color = ChartHelper.IsClearColor(xAxis.axisName.color) ? (Color)m_ThemeInfo.axisTextColor : xAxis.axisName.color; var fontSize = xAxis.axisName.fontSize; var offset = xAxis.axisName.offset; Text axisName = null; var zeroPos = new Vector3(m_CoordinateX, m_CoordinateY + m_YAxises[xAxisIndex].runtimeZeroYOffset); switch (xAxis.axisName.location) { case AxisName.Location.Start: axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, m_ThemeInfo.font, color, TextAnchor.MiddleRight, new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(100, 20), fontSize, xAxis.axisName.rotate, xAxis.axisName.fontStyle); axisName.transform.localPosition = xAxisIndex > 0 ? new Vector2(zeroPos.x - offset.x, m_CoordinateY + m_CoordinateHeight + offset.y) : new Vector2(zeroPos.x - offset.x, zeroPos.y + offset.y); break; case AxisName.Location.Middle: axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, m_ThemeInfo.font, color, TextAnchor.MiddleCenter, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), fontSize, xAxis.axisName.rotate, xAxis.axisName.fontStyle); axisName.transform.localPosition = xAxisIndex > 0 ? new Vector2(m_CoordinateX + m_CoordinateWidth / 2 + offset.x, m_CoordinateY + m_CoordinateHeight - offset.y) : new Vector2(m_CoordinateX + m_CoordinateWidth / 2 + offset.x, m_CoordinateY - offset.y); break; case AxisName.Location.End: axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, m_ThemeInfo.font, color, TextAnchor.MiddleLeft, new Vector2(0, 0.5f), new Vector2(0, 0.5f), new Vector2(0, 0.5f), new Vector2(100, 20), fontSize, xAxis.axisName.rotate, xAxis.axisName.fontStyle); axisName.transform.localPosition = xAxisIndex > 0 ? new Vector2(m_CoordinateX + m_CoordinateWidth + offset.x, m_CoordinateY + m_CoordinateHeight + offset.y) : new Vector2(m_CoordinateX + m_CoordinateWidth + offset.x, zeroPos.y + offset.y); break; } axisName.text = xAxis.axisName.name; } if (m_Tooltip.runtimeGameObject) { Vector2 privot = xAxisIndex > 0 ? new Vector2(0.5f, 1) : new Vector2(0.5f, 1); var labelParent = m_Tooltip.runtimeGameObject.transform; GameObject labelObj = ChartHelper.AddTooltipLabel(ChartCached.GetAxisTooltipLabel(objName), labelParent, m_ThemeInfo.font, privot); xAxis.SetTooltipLabel(labelObj); xAxis.SetTooltipLabelColor(m_ThemeInfo.tooltipBackgroundColor, m_ThemeInfo.tooltipTextColor); xAxis.SetTooltipLabelActive(xAxis.show && m_Tooltip.show && m_Tooltip.type == Tooltip.Type.Corss); } } private void InitDataZoom() { var dataZoomObject = ChartHelper.AddObject(s_DefaultDataZoom, transform, chartAnchorMin, chartAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight)); dataZoomObject.transform.localPosition = Vector3.zero; dataZoomObject.hideFlags = chartHideFlags; ChartHelper.HideAllObject(dataZoomObject); var startLabel = ChartHelper.AddTextObject(s_DefaultDataZoom + "start", dataZoomObject.transform, m_ThemeInfo.font, m_ThemeInfo.dataZoomTextColor, TextAnchor.MiddleRight, Vector2.zero, Vector2.zero, new Vector2(1, 0.5f), new Vector2(200, 20), m_DataZoom.fontSize, 0, m_DataZoom.fontStyle); var endLabel = ChartHelper.AddTextObject(s_DefaultDataZoom + "end", dataZoomObject.transform, m_ThemeInfo.font, m_ThemeInfo.dataZoomTextColor, TextAnchor.MiddleLeft, Vector2.zero, Vector2.zero, new Vector2(0, 0.5f), new Vector2(200, 20), m_DataZoom.fontSize, 0, m_DataZoom.fontStyle); m_DataZoom.SetStartLabel(startLabel); m_DataZoom.SetEndLabel(endLabel); m_DataZoom.SetLabelActive(false); CheckRaycastTarget(); var xAxis = m_XAxises[m_DataZoom.xAxisIndex]; if (xAxis != null) { xAxis.UpdateFilterData(m_DataZoom); } if (m_Series != null) { m_Series.UpdateFilterData(m_DataZoom); } } private Vector3 GetLabelYPosition(float scaleWid, int i, int yAxisIndex, YAxis yAxis) { var startX = yAxisIndex == 0 ? m_CoordinateX : m_CoordinateX + m_CoordinateWidth; var posX = 0f; var inside = yAxis.axisLabel.inside; if ((inside && yAxisIndex == 0) || (!inside && yAxisIndex == 1)) { posX = startX + yAxis.axisLabel.margin; } else { posX = startX - yAxis.axisLabel.margin; } return new Vector3(posX, m_CoordinateY + scaleWid, 0); } private Vector3 GetLabelXPosition(float scaleWid, int i, int xAxisIndex, XAxis xAxis) { var startY = m_CoordinateY + (xAxis.axisLabel.onZero ? m_YAxises[xAxisIndex].runtimeZeroYOffset : 0); if (xAxisIndex > 0) startY += m_CoordinateHeight; var posY = 0f; var inside = xAxis.axisLabel.inside; if ((inside && xAxisIndex == 0) || (!inside && xAxisIndex == 1)) { posY = startY + xAxis.axisLabel.margin + xAxis.axisLabel.fontSize / 2; } else { posY = startY - xAxis.axisLabel.margin - xAxis.axisLabel.fontSize / 2; } return new Vector3(m_CoordinateX + scaleWid, posY); } private void CheckMinMaxValue() { if (m_XAxises == null || m_YAxises == null) return; if (IsCategory()) { m_CheckMinMaxValue = true; return; } for (int i = 0; i < m_XAxises.Count; i++) { UpdateAxisMinMaxValue(i, m_XAxises[i]); } for (int i = 0; i < m_YAxises.Count; i++) { UpdateAxisMinMaxValue(i, m_YAxises[i]); } } private void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true) { if (axis.IsCategory() || !axis.show) return; float tempMinValue = 0; float tempMaxValue = 0; if (IsValue()) { if (axis is XAxis) { SeriesHelper.GetXMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); } else { SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue); } } else { SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, false, axis.inverse, out tempMinValue, out tempMaxValue); } AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true); if (tempMinValue != axis.runtimeMinValue || tempMaxValue != axis.runtimeMaxValue) { m_CheckMinMaxValue = true; m_IsPlayingAnimation = true; var needCheck = !m_IsPlayingAnimation && axis.runtimeLastCheckInverse == axis.inverse; axis.UpdateMinValue(tempMinValue, needCheck); axis.UpdateMaxValue(tempMaxValue, needCheck); axis.runtimeZeroXOffset = 0; axis.runtimeZeroYOffset = 0; axis.runtimeLastCheckInverse = axis.inverse; if (tempMinValue != 0 || tempMaxValue != 0) { if (axis is XAxis && axis.IsValue()) { axis.runtimeZeroXOffset = axis.runtimeMinValue > 0 ? 0 : axis.runtimeMaxValue < 0 ? this.m_CoordinateWidth : Mathf.Abs(axis.runtimeMinValue) * (this.m_CoordinateWidth / (Mathf.Abs(axis.runtimeMinValue) + Mathf.Abs(axis.runtimeMaxValue))); } if (axis is YAxis && axis.IsValue()) { axis.runtimeZeroYOffset = axis.runtimeMinValue > 0 ? 0 : axis.runtimeMaxValue < 0 ? m_CoordinateHeight : Mathf.Abs(axis.runtimeMinValue) * (m_CoordinateHeight / (Mathf.Abs(axis.runtimeMinValue) + Mathf.Abs(axis.runtimeMaxValue))); } } if (updateChart) { UpdateAxisLabelText(axis); RefreshChart(); } } if (axis.IsValueChanging(500) && !m_IsPlayingAnimation) { UpdateAxisLabelText(axis); RefreshChart(); } } protected void UpdateAxisLabelText(Axis axis) { float m_CoordinateWidth = axis is XAxis ? this.m_CoordinateWidth : m_CoordinateHeight; var isPercentStack = SeriesHelper.IsPercentStack(m_Series, SerieType.Bar); axis.UpdateLabelText(m_CoordinateWidth, m_DataZoom, isPercentStack, 500); } protected virtual void OnCoordinateChanged() { UpdateCoordinate(); m_XAxisesDirty = true; m_YAxisesDirty = true; } protected override void OnSizeChanged() { base.OnSizeChanged(); OnCoordinateChanged(); } private void DrawCoordinate(VertexHelper vh) { DrawGrid(vh); for (int i = 0; i < m_XAxises.Count; i++) { DrawXAxisSplit(vh, i, m_XAxises[i]); } for (int i = 0; i < m_YAxises.Count; i++) { DrawYAxisSplit(vh, i, m_YAxises[i]); } for (int i = 0; i < m_XAxises.Count; i++) { DrawXAxisLine(vh, i, m_XAxises[i]); } for (int i = 0; i < m_YAxises.Count; i++) { DrawYAxisLine(vh, i, m_YAxises[i]); } } private void DrawAxisTick(VertexHelper vh) { for (int i = 0; i < m_XAxises.Count; i++) { DrawXAxisTick(vh, i, m_XAxises[i]); } for (int i = 0; i < m_YAxises.Count; i++) { DrawYAxisTick(vh, i, m_YAxises[i]); } } private void DrawGrid(VertexHelper vh) { if (m_Grid.show && !ChartHelper.IsClearColor(m_Grid.backgroundColor)) { var p1 = new Vector2(m_CoordinateX, m_CoordinateY); var p2 = new Vector2(m_CoordinateX, m_CoordinateY + m_CoordinateHeight); var p3 = new Vector2(m_CoordinateX + m_CoordinateWidth, m_CoordinateY + m_CoordinateHeight); var p4 = new Vector2(m_CoordinateX + m_CoordinateWidth, m_CoordinateY); ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, m_Grid.backgroundColor); } } private void DrawYAxisSplit(VertexHelper vh, int yAxisIndex, YAxis yAxis) { if (AxisHelper.NeedShowSplit(yAxis)) { var size = AxisHelper.GetScaleNumber(yAxis, m_CoordinateWidth, m_DataZoom); var totalWidth = m_CoordinateY; var xAxis = m_XAxises[yAxisIndex]; var zeroPos = new Vector3(m_CoordinateX + xAxis.runtimeZeroXOffset, m_CoordinateY + yAxis.runtimeZeroYOffset); for (int i = 0; i < size; i++) { var scaleWidth = AxisHelper.GetScaleWidth(yAxis, m_CoordinateHeight, i, m_DataZoom); float pY = totalWidth; if (yAxis.boundaryGap && yAxis.axisTick.alignWithLabel) { pY -= scaleWidth / 2; } if (yAxis.splitArea.show && i < size - 1) { ChartDrawer.DrawPolygon(vh, new Vector2(m_CoordinateX, pY), new Vector2(m_CoordinateX + m_CoordinateWidth, pY), new Vector2(m_CoordinateX + m_CoordinateWidth, pY + scaleWidth), new Vector2(m_CoordinateX, pY + scaleWidth), yAxis.splitArea.getColor(i)); } if (yAxis.splitLine.show) { if (!xAxis.axisLine.show || !xAxis.axisLine.onZero || zeroPos.y != pY) { if (yAxis.splitLine.NeedShow(i)) { ChartDrawer.DrawLineStyle(vh, yAxis.splitLine.lineStyle, new Vector3(m_CoordinateX, pY), new Vector3(m_CoordinateX + m_CoordinateWidth, pY), yAxis.splitLine.GetColor(m_ThemeInfo)); } } } totalWidth += scaleWidth; } } } private void DrawYAxisTick(VertexHelper vh, int yAxisIndex, YAxis yAxis) { if (AxisHelper.NeedShowSplit(yAxis)) { var size = AxisHelper.GetScaleNumber(yAxis, m_CoordinateWidth, m_DataZoom); var totalWidth = m_CoordinateY; var xAxis = m_XAxises[yAxisIndex]; for (int i = 0; i < size; i++) { var scaleWidth = AxisHelper.GetScaleWidth(yAxis, m_CoordinateHeight, i, m_DataZoom); float pX = 0; float pY = totalWidth; if (yAxis.boundaryGap && yAxis.axisTick.alignWithLabel) { pY -= scaleWidth / 2; } if (yAxis.axisTick.show && i > 0) { var startX = m_CoordinateX + (yAxis.axisLine.onZero ? m_XAxises[yAxisIndex].runtimeZeroXOffset : 0); startX -= yAxis.axisLine.width; if (yAxis.IsValue() && yAxisIndex > 0) startX += m_CoordinateWidth; bool inside = yAxis.axisTick.inside; if ((inside && yAxisIndex == 0) || (!inside && yAxisIndex == 1)) { pX += startX + yAxis.axisTick.length; } else { pX += startX - yAxis.axisTick.length; } ChartDrawer.DrawLine(vh, new Vector3(startX, pY), new Vector3(pX, pY), AxisHelper.GetTickWidth(yAxis), m_ThemeInfo.axisLineColor); } totalWidth += scaleWidth; } } if (yAxis.show && yAxis.axisLine.show && yAxis.axisLine.symbol) { var lineX = m_CoordinateX + (yAxis.axisLine.onZero ? m_XAxises[yAxisIndex].runtimeZeroXOffset : 0); if (yAxis.IsValue() && yAxisIndex > 0) lineX += m_CoordinateWidth; var inverse = yAxis.IsValue() && yAxis.inverse; if (inverse) { var startPos = new Vector3(lineX, m_CoordinateY + m_CoordinateHeight); var arrowPos = new Vector3(lineX, m_CoordinateY); var axisLine = yAxis.axisLine; ChartDrawer.DrawArrow(vh, startPos, arrowPos, axisLine.symbolWidth, axisLine.symbolHeight, axisLine.symbolOffset, axisLine.symbolDent, m_ThemeInfo.axisLineColor); } else { var startPos = new Vector3(lineX, m_CoordinateX); var arrowPos = new Vector3(lineX, m_CoordinateY + m_CoordinateHeight + yAxis.axisLine.width); var axisLine = yAxis.axisLine; ChartDrawer.DrawArrow(vh, startPos, arrowPos, axisLine.symbolWidth, axisLine.symbolHeight, axisLine.symbolOffset, axisLine.symbolDent, m_ThemeInfo.axisLineColor); } } } private void DrawXAxisSplit(VertexHelper vh, int xAxisIndex, XAxis xAxis) { if (AxisHelper.NeedShowSplit(xAxis)) { var size = AxisHelper.GetScaleNumber(xAxis, m_CoordinateWidth, m_DataZoom); var totalWidth = m_CoordinateX; var yAxis = m_YAxises[xAxisIndex]; var zeroPos = new Vector3(m_CoordinateX, m_CoordinateY + yAxis.runtimeZeroYOffset); for (int i = 0; i < size; i++) { var scaleWidth = AxisHelper.GetScaleWidth(xAxis, m_CoordinateWidth, i, m_DataZoom); float pX = totalWidth; if (xAxis.boundaryGap && xAxis.axisTick.alignWithLabel) { pX -= scaleWidth / 2; } if (xAxis.splitArea.show && i < size - 1) { ChartDrawer.DrawPolygon(vh, new Vector2(pX, m_CoordinateY), new Vector2(pX, m_CoordinateY + m_CoordinateHeight), new Vector2(pX + scaleWidth, m_CoordinateY + m_CoordinateHeight), new Vector2(pX + scaleWidth, m_CoordinateY), xAxis.splitArea.getColor(i)); } if (xAxis.splitLine.show) { if (!yAxis.axisLine.show || !yAxis.axisLine.onZero || zeroPos.x != pX) { if (xAxis.splitLine.NeedShow(i)) { ChartDrawer.DrawLineStyle(vh, xAxis.splitLine.lineStyle, new Vector3(pX, m_CoordinateY), new Vector3(pX, m_CoordinateY + m_CoordinateHeight), xAxis.splitLine.GetColor(m_ThemeInfo)); } } } totalWidth += scaleWidth; } } } private void DrawXAxisTick(VertexHelper vh, int xAxisIndex, XAxis xAxis) { if (AxisHelper.NeedShowSplit(xAxis)) { var size = AxisHelper.GetScaleNumber(xAxis, m_CoordinateWidth, m_DataZoom); var totalWidth = m_CoordinateX; var yAxis = m_YAxises[xAxisIndex]; for (int i = 0; i < size; i++) { var scaleWidth = AxisHelper.GetScaleWidth(xAxis, m_CoordinateWidth, i, m_DataZoom); float pX = totalWidth; float pY = 0; if (xAxis.boundaryGap && xAxis.axisTick.alignWithLabel) { pX -= scaleWidth / 2; } if (xAxis.axisTick.show && i > 0) { var startY = m_CoordinateY + (xAxis.axisLine.onZero ? m_YAxises[xAxisIndex].runtimeZeroYOffset : 0); startY -= xAxis.axisLine.width; if (xAxis.IsValue() && xAxisIndex > 0) startY += m_CoordinateHeight; bool inside = xAxis.axisTick.inside; if ((inside && xAxisIndex == 0) || (!inside && xAxisIndex == 1)) { pY += startY + xAxis.axisTick.length; } else { pY += startY - xAxis.axisTick.length; } ChartDrawer.DrawLine(vh, new Vector3(pX, startY), new Vector3(pX, pY), AxisHelper.GetTickWidth(xAxis), m_ThemeInfo.axisLineColor); } totalWidth += scaleWidth; } } if (xAxis.show && xAxis.axisLine.show && xAxis.axisLine.symbol) { var lineY = m_CoordinateY + (xAxis.axisLine.onZero ? m_YAxises[xAxisIndex].runtimeZeroYOffset : 0); if (xAxis.IsValue() && xAxisIndex > 0) lineY += m_CoordinateHeight; var inverse = xAxis.IsValue() && xAxis.inverse; if (inverse) { var startPos = new Vector3(m_CoordinateX + m_CoordinateWidth, lineY); var arrowPos = new Vector3(m_CoordinateX, lineY); var axisLine = xAxis.axisLine; ChartDrawer.DrawArrow(vh, startPos, arrowPos, axisLine.symbolWidth, axisLine.symbolHeight, axisLine.symbolOffset, axisLine.symbolDent, m_ThemeInfo.axisLineColor); } else { var startPos = new Vector3(m_CoordinateX, lineY); var arrowPos = new Vector3(m_CoordinateX + m_CoordinateWidth + xAxis.axisLine.width, lineY); var axisLine = xAxis.axisLine; ChartDrawer.DrawArrow(vh, startPos, arrowPos, axisLine.symbolWidth, axisLine.symbolHeight, axisLine.symbolOffset, axisLine.symbolDent, m_ThemeInfo.axisLineColor); } } } private void DrawXAxisLine(VertexHelper vh, int xAxisIndex, XAxis xAxis) { if (xAxis.show && xAxis.axisLine.show) { var inverse = xAxis.IsValue() && xAxis.inverse; var offset = AxisHelper.GetAxisLineSymbolOffset(xAxis); var lineY = m_CoordinateY + (xAxis.axisLine.onZero ? m_YAxises[xAxisIndex].runtimeZeroYOffset : 0); if (xAxis.IsValue() && xAxisIndex > 0) lineY += m_CoordinateHeight; var left = new Vector3(m_CoordinateX - xAxis.axisLine.width - (inverse ? offset : 0), lineY); var right = new Vector3(m_CoordinateX + m_CoordinateWidth + xAxis.axisLine.width + (!inverse ? offset : 0), lineY); ChartDrawer.DrawLine(vh, left, right, xAxis.axisLine.width, m_ThemeInfo.axisLineColor); } } private void DrawYAxisLine(VertexHelper vh, int yAxisIndex, YAxis yAxis) { if (yAxis.show && yAxis.axisLine.show) { var offset = AxisHelper.GetAxisLineSymbolOffset(yAxis); var inverse = yAxis.IsValue() && yAxis.inverse; var lineX = m_CoordinateX + (yAxis.axisLine.onZero ? m_XAxises[yAxisIndex].runtimeZeroXOffset : 0); if (yAxis.IsValue() && yAxisIndex > 0) lineX += m_CoordinateWidth; var bottom = new Vector3(lineX, m_CoordinateY - yAxis.axisLine.width - (inverse ? offset : 0)); var top = new Vector3(lineX, m_CoordinateY + m_CoordinateHeight + yAxis.axisLine.width + (!inverse ? offset : 0)); ChartDrawer.DrawLine(vh, bottom, top, yAxis.axisLine.width, m_ThemeInfo.axisLineColor); } } private void DrawDataZoomSlider(VertexHelper vh) { if (!m_DataZoom.enable || !m_DataZoom.supportSlider) return; var hig = m_DataZoom.GetHeight(grid.bottom); var p1 = new Vector3(m_CoordinateX, m_ChartY + m_DataZoom.bottom); var p2 = new Vector3(m_CoordinateX, m_ChartY + m_DataZoom.bottom + hig); var p3 = new Vector3(m_CoordinateX + m_CoordinateWidth, m_ChartY + m_DataZoom.bottom + hig); var p4 = new Vector3(m_CoordinateX + m_CoordinateWidth, m_ChartY + m_DataZoom.bottom); var xAxis = xAxises[0]; ChartDrawer.DrawLine(vh, p1, p2, xAxis.axisLine.width, m_ThemeInfo.dataZoomLineColor); ChartDrawer.DrawLine(vh, p2, p3, xAxis.axisLine.width, m_ThemeInfo.dataZoomLineColor); ChartDrawer.DrawLine(vh, p3, p4, xAxis.axisLine.width, m_ThemeInfo.dataZoomLineColor); ChartDrawer.DrawLine(vh, p4, p1, xAxis.axisLine.width, m_ThemeInfo.dataZoomLineColor); if (m_DataZoom.showDataShadow && m_Series.Count > 0) { Serie serie = m_Series.list[0]; Axis axis = yAxises[0]; var showData = serie.GetDataList(null); float scaleWid = m_CoordinateWidth / (showData.Count - 1); Vector3 lp = Vector3.zero; Vector3 np = Vector3.zero; float minValue = 0; float maxValue = 0; SeriesHelper.GetYMinMaxValue(m_Series, null, 0, IsValue(), axis.inverse, out minValue, out maxValue); AxisHelper.AdjustMinMaxValue(axis, ref minValue, ref maxValue, true); int rate = 1; var sampleDist = serie.sampleDist < 2 ? 2 : serie.sampleDist; var maxCount = showData.Count; if (sampleDist > 0) rate = (int)((maxCount - serie.minShow) / (m_CoordinateWidth / sampleDist)); if (rate < 1) rate = 1; var totalAverage = serie.sampleAverage > 0 ? serie.sampleAverage : DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate); var dataChanging = false; for (int i = 0; i < maxCount; i += rate) { float value = SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage, i, serie.animation.GetUpdateAnimationDuration(), ref dataChanging, axis.inverse); float pX = m_CoordinateX + i * scaleWid; float dataHig = (maxValue - minValue) == 0 ? 0 : (value - minValue) / (maxValue - minValue) * hig; np = new Vector3(pX, m_ChartY + m_DataZoom.bottom + dataHig); if (i > 0) { Color color = m_ThemeInfo.dataZoomLineColor; ChartDrawer.DrawLine(vh, lp, np, xAxis.axisLine.width, color); Vector3 alp = new Vector3(lp.x, lp.y - xAxis.axisLine.width); Vector3 anp = new Vector3(np.x, np.y - xAxis.axisLine.width); Color areaColor = new Color(color.r, color.g, color.b, color.a * 0.75f); Vector3 tnp = new Vector3(np.x, m_ChartY + m_DataZoom.bottom + xAxis.axisLine.width); Vector3 tlp = new Vector3(lp.x, m_ChartY + m_DataZoom.bottom + xAxis.axisLine.width); ChartDrawer.DrawPolygon(vh, alp, anp, tnp, tlp, areaColor); } lp = np; } if (dataChanging) { RefreshChart(); } } switch (m_DataZoom.rangeMode) { case DataZoom.RangeMode.Percent: var start = m_CoordinateX + m_CoordinateWidth * m_DataZoom.start / 100; var end = m_CoordinateX + m_CoordinateWidth * m_DataZoom.end / 100; p1 = new Vector2(start, m_ChartY + m_DataZoom.bottom); p2 = new Vector2(start, m_ChartY + m_DataZoom.bottom + hig); p3 = new Vector2(end, m_ChartY + m_DataZoom.bottom + hig); p4 = new Vector2(end, m_ChartY + m_DataZoom.bottom); ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.dataZoomSelectedColor); ChartDrawer.DrawLine(vh, p1, p2, xAxis.axisLine.width, m_ThemeInfo.dataZoomSelectedColor); ChartDrawer.DrawLine(vh, p3, p4, xAxis.axisLine.width, m_ThemeInfo.dataZoomSelectedColor); break; } } protected void DrawXTooltipIndicator(VertexHelper vh) { if (!m_Tooltip.show || !m_Tooltip.IsSelected()) return; if (m_Tooltip.type == Tooltip.Type.None) return; int dataCount = m_Series.list.Count > 0 ? m_Series.list[0].GetDataList(dataZoom).Count : 0; for (int i = 0; i < m_XAxises.Count; i++) { var xAxis = m_XAxises[i]; var yAxis = m_YAxises[i]; if (!xAxis.show) continue; float splitWidth = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); switch (m_Tooltip.type) { case Tooltip.Type.Corss: case Tooltip.Type.Line: float pX = m_CoordinateX + m_Tooltip.runtimeXValues[i] * splitWidth + (xAxis.boundaryGap ? splitWidth / 2 : 0); if (xAxis.IsValue()) pX = m_Tooltip.runtimePointerPos.x; Vector2 sp = new Vector2(pX, m_CoordinateY); Vector2 ep = new Vector2(pX, m_CoordinateY + m_CoordinateHeight); var lineColor = TooltipHelper.GetLineColor(tooltip, m_ThemeInfo); ChartDrawer.DrawLineStyle(vh, m_Tooltip.lineStyle, sp, ep, lineColor); if (m_Tooltip.type == Tooltip.Type.Corss) { sp = new Vector2(m_CoordinateX, m_Tooltip.runtimePointerPos.y); ep = new Vector2(m_CoordinateX + m_CoordinateWidth, m_Tooltip.runtimePointerPos.y); ChartDrawer.DrawLineStyle(vh, m_Tooltip.lineStyle, sp, ep, lineColor); } break; case Tooltip.Type.Shadow: float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth; pX = m_CoordinateX + splitWidth * m_Tooltip.runtimeXValues[i] - (xAxis.boundaryGap ? 0 : splitWidth / 2); if (xAxis.IsValue()) pX = m_Tooltip.runtimeXValues[i]; float pY = m_CoordinateY + m_CoordinateHeight; Vector3 p1 = new Vector3(pX, m_CoordinateY); Vector3 p2 = new Vector3(pX, pY); Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY); Vector3 p4 = new Vector3(pX + tooltipSplitWid, m_CoordinateY); ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.tooltipFlagAreaColor); break; } } } protected void DrawYTooltipIndicator(VertexHelper vh) { if (!m_Tooltip.show || !m_Tooltip.IsSelected()) return; if (m_Tooltip.type == Tooltip.Type.None) return; int dataCount = m_Series.list.Count > 0 ? m_Series.list[0].GetDataList(dataZoom).Count : 0; for (int i = 0; i < m_YAxises.Count; i++) { var yAxis = m_YAxises[i]; var xAxis = m_XAxises[i]; if (!yAxis.show) continue; float splitWidth = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); switch (m_Tooltip.type) { case Tooltip.Type.Corss: case Tooltip.Type.Line: float pY = m_CoordinateY + m_Tooltip.runtimeYValues[i] * splitWidth + (yAxis.boundaryGap ? splitWidth / 2 : 0); Vector2 sp = new Vector2(m_CoordinateX, pY); Vector2 ep = new Vector2(m_CoordinateX + m_CoordinateWidth, pY); var lineColor = TooltipHelper.GetLineColor(tooltip, m_ThemeInfo); ChartDrawer.DrawLineStyle(vh, m_Tooltip.lineStyle, sp, ep, lineColor); if (m_Tooltip.type == Tooltip.Type.Corss) { sp = new Vector2(m_CoordinateX, m_Tooltip.runtimePointerPos.y); ep = new Vector2(m_CoordinateX + m_CoordinateWidth, m_Tooltip.runtimePointerPos.y); ChartDrawer.DrawLineStyle(vh, m_Tooltip.lineStyle, sp, ep, lineColor); } break; case Tooltip.Type.Shadow: float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth; float pX = m_CoordinateX + m_CoordinateWidth; pY = m_CoordinateY + splitWidth * m_Tooltip.runtimeYValues[i] - (yAxis.boundaryGap ? 0 : splitWidth / 2); Vector3 p1 = new Vector3(m_CoordinateX, pY); Vector3 p2 = new Vector3(m_CoordinateX, pY + tooltipSplitWid); Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid); Vector3 p4 = new Vector3(pX, pY); ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, m_ThemeInfo.tooltipFlagAreaColor); break; } } } private void CheckRaycastTarget() { var ray = m_DataZoom.enable || (m_VisualMap.enable && m_VisualMap.show && m_VisualMap.calculable); if (raycastTarget != ray) { raycastTarget = ray; } } private void CheckDataZoom() { if (!m_DataZoom.enable) return; CheckDataZoomScale(); CheckDataZoomLabel(); } private bool m_IsSingleTouch; private Vector2 m_LastSingleTouchPos; private Vector2 m_LastTouchPos0; private Vector2 m_LastTouchPos1; private void CheckDataZoomScale() { if (!m_DataZoom.enable || m_DataZoom.zoomLock || !m_DataZoom.supportInside) return; if (Input.touchCount == 2) { var touch0 = Input.GetTouch(0); var touch1 = Input.GetTouch(1); if (touch1.phase == TouchPhase.Began) { m_LastTouchPos0 = touch0.position; m_LastTouchPos1 = touch1.position; } else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved) { var tempPos0 = touch0.position; var tempPos1 = touch1.position; var currDist = Vector2.Distance(tempPos0, tempPos1); var lastDist = Vector2.Distance(m_LastTouchPos0, m_LastTouchPos1); var delta = (currDist - lastDist); ScaleDataZoom(delta / m_DataZoom.scrollSensitivity); m_LastTouchPos0 = tempPos0; m_LastTouchPos1 = tempPos1; } } } private void CheckDataZoomLabel() { if (m_DataZoom.supportSlider && m_DataZoom.showDetail) { Vector2 local; if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Input.mousePosition, canvas.worldCamera, out local)) { m_DataZoom.SetLabelActive(false); return; } if (m_DataZoom.IsInSelectedZoom(local, m_CoordinateX, chartY, m_CoordinateWidth) || m_DataZoom.IsInStartZoom(local, m_CoordinateX, chartY, m_CoordinateWidth) || m_DataZoom.IsInEndZoom(local, m_CoordinateX, chartY, m_CoordinateWidth)) { m_DataZoom.SetLabelActive(true); RefreshDataZoomLabel(); } else { m_DataZoom.SetLabelActive(false); } } if (m_CheckDataZoomLabel) { m_CheckDataZoomLabel = false; var xAxis = m_XAxises[m_DataZoom.xAxisIndex]; var startIndex = (int)((xAxis.data.Count - 1) * m_DataZoom.start / 100); var endIndex = (int)((xAxis.data.Count - 1) * m_DataZoom.end / 100); if (m_DataZoomLastStartIndex != startIndex || m_DataZoomLastEndIndex != endIndex) { m_DataZoomLastStartIndex = startIndex; m_DataZoomLastEndIndex = endIndex; if (xAxis.data.Count > 0) { m_DataZoom.SetStartLabelText(xAxis.data[startIndex]); m_DataZoom.SetEndLabelText(xAxis.data[endIndex]); } InitAxisX(); } var start = m_CoordinateX + m_CoordinateWidth * m_DataZoom.start / 100; var end = m_CoordinateX + m_CoordinateWidth * m_DataZoom.end / 100; var hig = m_DataZoom.GetHeight(grid.bottom); m_DataZoom.UpdateStartLabelPosition(new Vector3(start - 10, chartY + m_DataZoom.bottom + hig / 2)); m_DataZoom.UpdateEndLabelPosition(new Vector3(end + 10, chartY + m_DataZoom.bottom + hig / 2)); } } protected void DrawLabelBackground(VertexHelper vh) { var isYAxis = m_YAxises[0].type == Axis.AxisType.Category || m_YAxises[1].type == Axis.AxisType.Category; for (int n = 0; n < m_Series.Count; n++) { var serie = m_Series.GetSerie(n); if (!serie.show) continue; for (int j = 0; j < serie.data.Count; j++) { var serieData = serie.data[j]; if (serieData.labelObject == null) continue; var serieLabel = SerieHelper.GetSerieLabel(serie, serieData, serieData.highlighted); serieData.index = j; if ((serieLabel.show || serieData.iconStyle.show)) { var pos = serie.dataPoints[j]; var isIngore = ChartHelper.IsIngore(pos); if (isIngore) { serieData.SetLabelActive(false); } else { var value = serieData.data[1]; switch (serie.type) { case SerieType.Line: break; case SerieType.Bar: var zeroPos = Vector3.zero; var lastStackSerie = SeriesHelper.GetLastStackSerie(m_Series, n); if (serie.type == SerieType.Bar) { if (serieLabel.position == SerieLabel.Position.Bottom || serieLabel.position == SerieLabel.Position.Center) { if (isYAxis) { var xAxis = m_XAxises[serie.axisIndex]; zeroPos = new Vector3(m_CoordinateX + xAxis.runtimeZeroXOffset, m_CoordinateY); } else { var yAxis = m_YAxises[serie.axisIndex]; zeroPos = new Vector3(m_CoordinateX, m_CoordinateY + yAxis.runtimeZeroYOffset); } } } var bottomPos = lastStackSerie == null ? zeroPos : lastStackSerie.dataPoints[j]; switch (serieLabel.position) { case SerieLabel.Position.Center: pos = isYAxis ? new Vector3(bottomPos.x + (pos.x - bottomPos.x) / 2, pos.y) : new Vector3(pos.x, bottomPos.y + (pos.y - bottomPos.y) / 2); break; case SerieLabel.Position.Bottom: pos = isYAxis ? new Vector3(bottomPos.x, pos.y) : new Vector3(pos.x, bottomPos.y); break; } break; } m_RefreshLabel = true; serieData.labelPosition = pos; if (serieLabel.show) DrawLabelBackground(vh, serie, serieData); } } else { serieData.SetLabelActive(false); } } } } protected override void OnRefreshLabel() { var anyPercentStack = SeriesHelper.IsPercentStack(m_Series, SerieType.Bar); for (int i = 0; i < m_Series.Count; i++) { var serie = m_Series.GetSerie(i); if (serie.IsPerformanceMode()) continue; var total = serie.yTotal; var isPercentStack = SeriesHelper.IsPercentStack(m_Series, serie.stack, SerieType.Bar); for (int j = 0; j < serie.data.Count; j++) { if (j >= serie.dataPoints.Count) break; var serieData = serie.data[j]; if (serieData.labelObject == null) continue; var pos = serie.dataPoints[j]; var serieLabel = SerieHelper.GetSerieLabel(serie, serieData); var dimension = 1; var isIgnore = serie.IsIgnoreIndex(j, 1); serieData.labelObject.SetPosition(serieData.labelPosition); serieData.labelObject.UpdateIcon(serieData.iconStyle); if (serie.show && serieLabel.show && serieData.canShowLabel && !isIgnore) { float value = 0f; if (serie.type == SerieType.Heatmap) { dimension = m_VisualMap.enable && m_VisualMap.dimension > 0 ? m_VisualMap.dimension - 1 : serieData.data.Count - 1; } SerieLabelHelper.ResetLabel(serieData, serieLabel, themeInfo, i); value = serieData.data[dimension]; var content = ""; if (anyPercentStack && isPercentStack) { var tempTotal = GetSameStackTotalValue(serie.stack, j); content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, tempTotal, serieLabel); } else { content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, total, serieLabel); } serieData.SetLabelActive(value != 0 && serieData.labelPosition != Vector3.zero); var invert = serie.type == SerieType.Line && SerieHelper.IsDownPoint(serie, j) && !serie.areaStyle.show; serieData.labelObject.SetLabelPosition(invert ? -serieLabel.offset : serieLabel.offset); if (serieData.labelObject.SetText(content)) RefreshChart(); } else { serieData.SetLabelActive(false); } } } } public override void OnBeginDrag(PointerEventData eventData) { base.OnBeginDrag(eventData); if (Input.touchCount > 1) return; Vector2 pos; if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, canvas.worldCamera, out pos)) { return; } if (m_DataZoom.supportInside) { if (IsInCooridate(pos)) { m_DataZoomCoordinateDrag = true; } } if (m_DataZoom.supportSlider) { if (m_DataZoom.IsInStartZoom(pos, m_CoordinateX, chartY, m_CoordinateWidth)) { m_DataZoomStartDrag = true; } else if (m_DataZoom.IsInEndZoom(pos, m_CoordinateX, chartY, m_CoordinateWidth)) { m_DataZoomEndDrag = true; } else if (m_DataZoom.IsInSelectedZoom(pos, m_CoordinateX, chartY, m_CoordinateWidth)) { m_DataZoomDrag = true; } } OnDragVisualMapStart(); } public override void OnDrag(PointerEventData eventData) { base.OnDrag(eventData); if (Input.touchCount > 1) return; float deltaX = eventData.delta.x; float deltaPercent = deltaX / m_CoordinateWidth * 100; OnDragInside(deltaPercent); OnDragSlider(deltaPercent); OnDragVisualMap(); } private void OnDragInside(float deltaPercent) { if (Input.touchCount > 1) return; if (!m_DataZoom.supportInside) return; if (!m_DataZoomCoordinateDrag) return; var diff = m_DataZoom.end - m_DataZoom.start; if (deltaPercent > 0) { m_DataZoom.start -= deltaPercent; m_DataZoom.end = m_DataZoom.start + diff; } else { m_DataZoom.end += -deltaPercent; m_DataZoom.start = m_DataZoom.end - diff; } RefreshDataZoomLabel(); RefreshChart(); } private void OnDragSlider(float deltaPercent) { if (Input.touchCount > 1) return; if (!m_DataZoom.supportSlider) return; if (m_DataZoomStartDrag) { m_DataZoom.start += deltaPercent; if (m_DataZoom.start > m_DataZoom.end) { m_DataZoom.start = m_DataZoom.end; m_DataZoomEndDrag = true; m_DataZoomStartDrag = false; } if (m_DataZoom.realtime) { RefreshDataZoomLabel(); RefreshChart(); } } else if (m_DataZoomEndDrag) { m_DataZoom.end += deltaPercent; if (m_DataZoom.end < m_DataZoom.start) { m_DataZoom.end = m_DataZoom.start; m_DataZoomStartDrag = true; m_DataZoomEndDrag = false; } if (m_DataZoom.realtime) { RefreshDataZoomLabel(); RefreshChart(); } } else if (m_DataZoomDrag) { if (deltaPercent > 0) { if (m_DataZoom.end + deltaPercent > 100) { deltaPercent = 100 - m_DataZoom.end; } } else { if (m_DataZoom.start + deltaPercent < 0) { deltaPercent = -m_DataZoom.start; } } m_DataZoom.start += deltaPercent; m_DataZoom.end += deltaPercent; if (m_DataZoom.realtime) { RefreshDataZoomLabel(); RefreshChart(); } } } private void RefreshDataZoomLabel() { m_CheckDataZoomLabel = true; } public override void OnEndDrag(PointerEventData eventData) { base.OnEndDrag(eventData); if (m_DataZoomDrag || m_DataZoomStartDrag || m_DataZoomEndDrag || m_DataZoomCoordinateDrag) { RefreshChart(); } m_DataZoomDrag = false; m_DataZoomCoordinateDrag = false; m_DataZoomStartDrag = false; m_DataZoomEndDrag = false; OnDragVisualMapEnd(); } public override void OnPointerDown(PointerEventData eventData) { base.OnPointerDown(eventData); if (Input.touchCount > 1) return; Vector2 localPos; if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, canvas.worldCamera, out localPos)) { return; } if (m_DataZoom.IsInStartZoom(localPos, m_CoordinateX, chartY, m_CoordinateWidth) || m_DataZoom.IsInEndZoom(localPos, m_CoordinateX, chartY, m_CoordinateWidth)) { return; } if (m_DataZoom.IsInZoom(localPos, m_CoordinateX, chartY, m_CoordinateWidth) && !m_DataZoom.IsInSelectedZoom(localPos, m_CoordinateX, chartY, m_CoordinateWidth)) { var pointerX = localPos.x; var selectWidth = m_CoordinateWidth * (m_DataZoom.end - m_DataZoom.start) / 100; var startX = pointerX - selectWidth / 2; var endX = pointerX + selectWidth / 2; if (startX < m_CoordinateX) { startX = m_CoordinateX; endX = m_CoordinateX + selectWidth; } else if (endX > m_CoordinateX + m_CoordinateWidth) { endX = m_CoordinateX + m_CoordinateWidth; startX = m_CoordinateX + m_CoordinateWidth - selectWidth; } m_DataZoom.start = (startX - m_CoordinateX) / m_CoordinateWidth * 100; m_DataZoom.end = (endX - m_CoordinateX) / m_CoordinateWidth * 100; RefreshDataZoomLabel(); RefreshChart(); } } public override void OnScroll(PointerEventData eventData) { base.OnScroll(eventData); if (Input.touchCount > 1) return; if (!m_DataZoom.enable || m_DataZoom.zoomLock) return; Vector2 pos; if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, canvas.worldCamera, out pos)) { return; } if (!IsInCooridate(pos) && !m_DataZoom.IsInSelectedZoom(pos, m_CoordinateX, chartY, m_CoordinateWidth)) { return; } ScaleDataZoom(eventData.scrollDelta.y * m_DataZoom.scrollSensitivity); } private void ScaleDataZoom(float delta) { float deltaPercent = Mathf.Abs(delta / m_CoordinateWidth * 100); if (delta > 0) { if (m_DataZoom.end <= m_DataZoom.start) return; m_DataZoom.end -= deltaPercent; m_DataZoom.start += deltaPercent; if (m_DataZoom.end <= m_DataZoom.start) { m_DataZoom.end = m_DataZoom.start; } } else { m_DataZoom.end += deltaPercent; m_DataZoom.start -= deltaPercent; if (m_DataZoom.end > 100) m_DataZoom.end = 100; if (m_DataZoom.start < 0) m_DataZoom.start = 0; } RefreshDataZoomLabel(); RefreshChart(); } protected void CheckClipAndDrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color32 color, bool clip) { CheckClipAndDrawPolygon(vh, p1, p2, p3, p4, color, color, clip); } protected void CheckClipAndDrawPolygon(VertexHelper vh, Vector3 p, float radius, Color32 color, bool clip, bool vertical = true) { if (!IsInChart(p)) return; if (!clip || (clip && (IsInCooridate(p)))) ChartDrawer.DrawPolygon(vh, p, radius, color, vertical); } protected void CheckClipAndDrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color32 startColor, Color32 toColor, bool clip) { ClampInChart(ref p1); ClampInChart(ref p2); ClampInChart(ref p3); ClampInChart(ref p4); if (clip) { p1 = ClampInCoordinate(p1); p2 = ClampInCoordinate(p2); p3 = ClampInCoordinate(p3); p4 = ClampInCoordinate(p4); } if (!clip || (clip && (IsInCooridate(p1) && IsInCooridate(p2) && IsInCooridate(p3) && IsInCooridate(p4)))) ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, startColor, toColor); } protected void CheckClipAndDrawPolygon(VertexHelper vh, ref Vector3 p1, ref Vector3 p2, ref Vector3 p3, ref Vector3 p4, Color32 startColor, Color32 toColor, bool clip) { ClampInChart(ref p1); ClampInChart(ref p2); ClampInChart(ref p3); ClampInChart(ref p4); if (clip) { p1 = ClampInCoordinate(p1); p2 = ClampInCoordinate(p2); p3 = ClampInCoordinate(p3); p4 = ClampInCoordinate(p4); } if (!clip || (clip && (IsInCooridate(p1) && IsInCooridate(p2) && IsInCooridate(p3) && IsInCooridate(p4)))) ChartDrawer.DrawPolygon(vh, p1, p2, p3, p4, startColor, toColor); } protected void CheckClipAndDrawTriangle(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Color32 color, bool clip) { CheckClipAndDrawTriangle(vh, p1, p2, p3, color, color, color, clip); } protected void CheckClipAndDrawTriangle(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Color32 color, Color32 color2, Color32 color3, bool clip) { if (!IsInChart(p1) || !IsInChart(p2) || !IsInChart(p3)) return; if (!clip || (clip && (IsInCooridate(p1) || IsInCooridate(p2) || IsInCooridate(p3)))) ChartDrawer.DrawTriangle(vh, p1, p2, p3, color, color2, color3); } protected void CheckClipAndDrawLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, Color32 color, bool clip) { if (!IsInChart(p1) || !IsInChart(p2)) return; if (!clip || (clip && (IsInCooridate(p1) || IsInCooridate(p2)))) ChartDrawer.DrawLine(vh, p1, p2, size, color); } protected void CheckClipAndDrawSymbol(VertexHelper vh, SerieSymbolType type, float symbolSize, float tickness, Vector3 pos, Color color, Color toColor, float gap, bool clip, float[] cornerRadius) { if (!IsInChart(pos)) return; if (!clip || (clip && (IsInCooridate(pos)))) DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, cornerRadius); } protected void CheckClipAndDrawZebraLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, float zebraWidth, float zebraGap, Color32 color, bool clip) { ClampInChart(ref p1); ClampInChart(ref p2); ChartDrawer.DrawZebraLine(vh, p1, p2, size, zebraWidth, zebraGap, color); } protected Color GetXLerpColor(Color areaColor, Color areaToColor, Vector3 pos) { if (areaColor == areaToColor) return areaColor; return Color.Lerp(areaToColor, areaColor, (pos.y - m_CoordinateY) / m_CoordinateHeight); } protected Color GetYLerpColor(Color areaColor, Color areaToColor, Vector3 pos) { if (areaColor == areaToColor) return areaColor; return Color.Lerp(areaToColor, areaColor, (pos.x - m_CoordinateX) / m_CoordinateWidth); } } }