Aimbot-PPO/Aimbot-PPO-MultiScene/Assets/XCharts/Runtime/Component/Tooltip/TooltipHandler.cs

641 lines
29 KiB
C#
Raw Permalink Normal View History

using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using XUGL;
namespace XCharts.Runtime
{
[UnityEngine.Scripting.Preserve]
internal sealed class TooltipHandler : MainComponentHandler<Tooltip>
{
private List<ChartLabel> m_IndicatorLabels = new List<ChartLabel>();
private GameObject m_LabelRoot;
private ISerieContainer m_PointerContainer;
public override void InitComponent()
{
InitTooltip(component);
}
public override void Update()
{
UpdateTooltip(component);
UpdateTooltipIndicatorLabelText(component);
if (component.view != null)
component.view.Update();
}
public override void DrawTop(VertexHelper vh)
{
DrawTooltipIndicator(vh, component);
}
private void InitTooltip(Tooltip tooltip)
{
tooltip.painter = chart.m_PainterTop;
tooltip.refreshComponent = delegate()
{
var objName = ChartCached.GetComponentObjectName(tooltip);
tooltip.gameObject = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
var tooltipObject = tooltip.gameObject;
tooltipObject.transform.localPosition = Vector3.zero;
tooltipObject.hideFlags = chart.chartHideFlags;
var parent = tooltipObject.transform;
ChartHelper.HideAllObject(tooltipObject.transform);
tooltip.view = TooltipView.CreateView(tooltip, chart.theme, parent);
tooltip.SetActive(false);
m_LabelRoot = ChartHelper.AddObject("label", tooltip.gameObject.transform, chart.chartMinAnchor,
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
ChartHelper.HideAllObject(m_LabelRoot);
m_IndicatorLabels.Clear();
for (int i = 0; i < 2; i++)
{
var labelName = "label_" + i;
var item = ChartHelper.AddTooltipIndicatorLabel(component, labelName, m_LabelRoot.transform,
chart.theme, TextAnchor.MiddleCenter);
item.SetActive(false);
m_IndicatorLabels.Add(item);
}
};
tooltip.refreshComponent();
}
private ChartLabel GetIndicatorLabel(int index)
{
if (m_LabelRoot == null) return null;
if (index < m_IndicatorLabels.Count) return m_IndicatorLabels[index];
else
{
var labelName = "label_" + index;
var item = ChartHelper.AddTooltipIndicatorLabel(component, labelName, m_LabelRoot.transform,
chart.theme, TextAnchor.MiddleCenter);
m_IndicatorLabels.Add(item);
return item;
}
}
private void UpdateTooltip(Tooltip tooltip)
{
if (tooltip.trigger == Tooltip.Trigger.None) return;
if (!chart.isPointerInChart || !tooltip.show)
{
if (tooltip.IsActive())
{
tooltip.ClearValue();
tooltip.SetActive(false);
}
return;
}
var showTooltip = false;
for (int i = chart.series.Count - 1; i >= 0; i--)
{
var serie = chart.series[i];
if (!(serie is INeedSerieContainer))
{
if (SetSerieTooltip(tooltip, serie))
{
showTooltip = true;
chart.RefreshTopPainter();
return;
}
}
}
var containerSeries = ListPool<Serie>.Get();
m_PointerContainer = GetPointerContainerAndSeries(tooltip, containerSeries);
if (containerSeries.Count > 0)
{
if (SetSerieTooltip(tooltip, containerSeries))
showTooltip = true;
}
ListPool<Serie>.Release(containerSeries);
if (!showTooltip)
{
if (tooltip.type == Tooltip.Type.Corss && m_PointerContainer != null && m_PointerContainer.IsPointerEnter())
{
tooltip.SetActive(true);
tooltip.SetContentActive(false);
}
else
{
tooltip.SetActive(false);
}
}
else
{
chart.RefreshTopPainter();
}
}
private void UpdateTooltipIndicatorLabelText(Tooltip tooltip)
{
if (!tooltip.show) return;
if (tooltip.type == Tooltip.Type.None) return;
if (m_PointerContainer != null)
{
if (tooltip.type == Tooltip.Type.Corss)
{
var labelCount = 0;
if (m_PointerContainer is GridCoord)
{
var grid = m_PointerContainer as GridCoord;
ChartHelper.HideAllObject(m_LabelRoot);
foreach (var component in chart.components)
{
if (component is XAxis || component is YAxis)
{
var axis = component as Axis;
if (axis.gridIndex == grid.index)
{
var label = GetIndicatorLabel(labelCount++);
SetTooltipIndicatorLabel(tooltip, axis, label);
}
}
}
}
else if (m_PointerContainer is PolarCoord)
{
var polar = m_PointerContainer as PolarCoord;
ChartHelper.HideAllObject(m_LabelRoot);
foreach (var component in chart.components)
{
if (component is AngleAxis || component is RadiusAxis)
{
var axis = component as Axis;
if (axis.polarIndex == polar.index)
{
var label = GetIndicatorLabel(labelCount++);
SetTooltipIndicatorLabel(tooltip, axis, label);
}
}
}
}
}
}
}
private void SetTooltipIndicatorLabel(Tooltip tooltip, Axis axis, ChartLabel label)
{
if (label == null) return;
if (double.IsPositiveInfinity(axis.context.pointerValue)) return;
label.SetActive(true);
label.SetTextActive(true);
label.SetPosition(axis.context.pointerLabelPosition);
if (axis.IsCategory())
label.SetText(axis.GetData((int) axis.context.pointerValue));
else
label.SetText(axis.context.pointerValue.ToString("f2"));
var textColor = axis.axisLabel.textStyle.GetColor(chart.theme.axis.textColor);
if (ChartHelper.IsClearColor(tooltip.indicatorLabelStyle.background.color))
label.color = textColor;
else
label.color = tooltip.indicatorLabelStyle.background.color;
label.SetTextColor(Color.white);
}
private ISerieContainer GetPointerContainerAndSeries(Tooltip tooltip, List<Serie> list)
{
list.Clear();
for (int i = chart.components.Count - 1; i >= 0; i--)
{
var component = chart.components[i];
if (component is ISerieContainer)
{
var container = component as ISerieContainer;
if (container.IsPointerEnter())
{
foreach (var serie in chart.series)
{
if (serie is INeedSerieContainer &&
(serie as INeedSerieContainer).containterInstanceId == component.instanceId)
{
var isTriggerAxis = tooltip.IsTriggerAxis();
if (container is GridCoord)
{
var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex);
var yAxis = chart.GetChartComponent<YAxis>(serie.yAxisIndex);
serie.context.pointerEnter = true;
UpdateAxisPointerDataIndex(serie, xAxis, yAxis, container as GridCoord, isTriggerAxis);
}
else if (container is PolarCoord)
{
var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, container.index);
tooltip.context.angle = (float) m_AngleAxis.context.pointerValue;
}
list.Add(serie);
if (!isTriggerAxis)
chart.RefreshTopPainter();
}
}
return container;
}
}
}
return null;
}
private void UpdateAxisPointerDataIndex(Serie serie, XAxis xAxis, YAxis yAxis, GridCoord grid, bool isTriggerAxis)
{
serie.context.pointerAxisDataIndexs.Clear();
if (yAxis.IsCategory())
{
serie.context.pointerAxisDataIndexs.Add((int) yAxis.context.pointerValue);
yAxis.context.axisTooltipValue = yAxis.context.pointerValue;
}
else if (yAxis.IsTime())
{
if (isTriggerAxis)
GetSerieDataIndexByAxis(serie, yAxis, grid);
else
GetSerieDataIndexByItem(serie, yAxis, grid);
}
else if (xAxis.IsCategory())
{
serie.context.pointerAxisDataIndexs.Add((int) xAxis.context.pointerValue);
xAxis.context.axisTooltipValue = xAxis.context.pointerValue;
}
else
{
if (isTriggerAxis)
GetSerieDataIndexByAxis(serie, xAxis, grid);
else
GetSerieDataIndexByItem(serie, xAxis, grid);
}
}
private void GetSerieDataIndexByAxis(Serie serie, Axis axis, GridCoord grid, int dimension = 0)
{
var currValue = 0d;
var lastValue = 0d;
var nextValue = 0d;
var axisValue = axis.context.pointerValue;
var isTimeAxis = axis.IsTime();
var dataCount = serie.dataCount;
var themeSymbolSize = chart.theme.serie.scatterSymbolSize;
var data = serie.data;
if (!isTimeAxis)
{
serie.context.sortedData.Clear();
for (int i = 0; i < dataCount; i++)
{
var serieData = serie.data[i];
serieData.index = i;
serie.context.sortedData.Add(serieData);
}
serie.context.sortedData.Sort(delegate(SerieData a, SerieData b)
{
return a.GetData(dimension).CompareTo(b.GetData(dimension));
});
data = serie.context.sortedData;
}
serie.context.pointerAxisDataIndexs.Clear();
for (int i = 0; i < dataCount; i++)
{
var serieData = data[i];
currValue = serieData.GetData(dimension);
if (i == 0)
{
nextValue = data[i + 1].GetData(dimension);
if (axisValue <= currValue + (nextValue - currValue) / 2)
{
serie.context.pointerAxisDataIndexs.Add(serieData.index);
break;
}
}
else if (i == dataCount - 1)
{
if (axisValue > lastValue + (currValue - lastValue) / 2)
{
serie.context.pointerAxisDataIndexs.Add(serieData.index);
break;
}
}
else
{
nextValue = data[i + 1].GetData(dimension);
if (axisValue > (currValue - (currValue - lastValue) / 2) && axisValue <= currValue + (nextValue - currValue) / 2)
{
serie.context.pointerAxisDataIndexs.Add(serieData.index);
break;
}
}
lastValue = currValue;
}
if (serie.context.pointerAxisDataIndexs.Count > 0)
{
var index = serie.context.pointerAxisDataIndexs[0];
serie.context.pointerItemDataIndex = index;
axis.context.axisTooltipValue = serie.GetSerieData(index).GetData(dimension);
}
else
{
serie.context.pointerItemDataIndex = -1;
axis.context.axisTooltipValue = 0;
}
}
private void GetSerieDataIndexByItem(Serie serie, Axis axis, GridCoord grid, int dimension = 0)
{
if (serie.context.pointerItemDataIndex >= 0)
{
axis.context.axisTooltipValue = serie.GetSerieData(serie.context.pointerItemDataIndex).GetData(dimension);
}
else if (component.type == Tooltip.Type.Corss)
{
axis.context.axisTooltipValue = axis.context.pointerValue;
}
else
{
axis.context.axisTooltipValue = 0;
}
}
private bool SetSerieTooltip(Tooltip tooltip, Serie serie)
{
if (tooltip.trigger == Tooltip.Trigger.None) return false;
if (serie.context.pointerItemDataIndex < 0) return false;
tooltip.context.data.param.Clear();
tooltip.context.data.title = serie.serieName;
tooltip.context.pointer = chart.pointerPos;
serie.handler.UpdateTooltipSerieParams(serie.context.pointerItemDataIndex, false, null,
tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter,
ref tooltip.context.data.param,
ref tooltip.context.data.title);
TooltipHelper.ResetTooltipParamsByItemFormatter(tooltip, chart);
tooltip.SetActive(true);
tooltip.view.Refresh();
TooltipHelper.LimitInRect(tooltip, chart.chartRect);
return true;
}
private bool SetSerieTooltip(Tooltip tooltip, List<Serie> series)
{
if (tooltip.trigger == Tooltip.Trigger.None)
return false;
if (series.Count <= 0)
return false;
string category = null;
var showCategory = false;
var isTriggerByAxis = false;
var dataIndex = -1;
tooltip.context.data.param.Clear();
tooltip.context.pointer = chart.pointerPos;
if (m_PointerContainer is GridCoord)
{
if (tooltip.trigger == Tooltip.Trigger.Axis)
{
isTriggerByAxis = true;
GetAxisCategory(m_PointerContainer.index, ref dataIndex, ref category);
if (series.Count <= 1)
{
showCategory = true;
tooltip.context.data.title = series[0].serieName;
}
else
tooltip.context.data.title = category;
}
}
for (int i = 0; i < series.Count; i++)
{
var serie = series[i];
serie.context.isTriggerByAxis = isTriggerByAxis;
if (isTriggerByAxis && dataIndex >= 0)
serie.context.pointerItemDataIndex = dataIndex;
serie.handler.UpdateTooltipSerieParams(dataIndex, showCategory, category,
tooltip.marker, tooltip.itemFormatter, tooltip.numericFormatter,
ref tooltip.context.data.param,
ref tooltip.context.data.title);
}
TooltipHelper.ResetTooltipParamsByItemFormatter(tooltip, chart);
if (tooltip.context.data.param.Count > 0)
{
tooltip.SetActive(true);
if (tooltip.view != null)
tooltip.view.Refresh();
TooltipHelper.LimitInRect(tooltip, chart.chartRect);
return true;
}
return false;
}
private bool GetAxisCategory(int gridIndex, ref int dataIndex, ref string category)
{
foreach (var component in chart.components)
{
if (component is Axis)
{
var axis = component as Axis;
if (axis.gridIndex == gridIndex && axis.IsCategory())
{
dataIndex = (int) axis.context.pointerValue;
category = axis.GetData(dataIndex);
return true;
}
}
}
return false;
}
private void DrawTooltipIndicator(VertexHelper vh, Tooltip tooltip)
{
if (!tooltip.show) return;
if (tooltip.type == Tooltip.Type.None) return;
if (m_PointerContainer is GridCoord)
{
var grid = m_PointerContainer as GridCoord;
if (!grid.context.isPointerEnter) return;
if (IsYCategoryOfGrid(grid.index))
DrawYAxisIndicator(vh, tooltip, grid);
else
DrawXAxisIndicator(vh, tooltip, grid);
}
else if (m_PointerContainer is PolarCoord)
{
DrawPolarIndicator(vh, tooltip, m_PointerContainer as PolarCoord);
}
}
private bool IsYCategoryOfGrid(int gridIndex)
{
var yAxes = chart.GetChartComponents<YAxis>();
foreach (var component in yAxes)
{
var yAxis = component as YAxis;
if (yAxis.gridIndex == gridIndex && yAxis.IsCategory()) return true;
}
return false;
}
private void DrawXAxisIndicator(VertexHelper vh, Tooltip tooltip, GridCoord grid)
{
var xAxes = chart.GetChartComponents<XAxis>();
var lineType = tooltip.lineStyle.GetType(chart.theme.tooltip.lineType);
var lineWidth = tooltip.lineStyle.GetWidth(chart.theme.tooltip.lineWidth);
foreach (var component in xAxes)
{
var xAxis = component as XAxis;
if (xAxis.gridIndex == grid.index)
{
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
int dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0;
float splitWidth = AxisHelper.GetDataWidth(xAxis, grid.context.width, dataCount, dataZoom);
switch (tooltip.type)
{
case Tooltip.Type.Corss:
case Tooltip.Type.Line:
float pX = grid.context.x;
pX += xAxis.IsCategory() ?
(float) (xAxis.context.pointerValue * splitWidth + (xAxis.boundaryGap ? splitWidth / 2 : 0)) :
xAxis.GetDistance(xAxis.context.axisTooltipValue, grid.context.width);
Vector2 sp = new Vector2(pX, grid.context.y);
Vector2 ep = new Vector2(pX, grid.context.y + grid.context.height);
var lineColor = TooltipHelper.GetLineColor(tooltip, chart.theme);
// if (xAxis.IsCategory() && tooltip.type == Tooltip.Type.Corss)
// {
// float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth;
// pX = (float)(grid.context.x + splitWidth * xAxis.context.pointerValue -
// (xAxis.boundaryGap ? 0 : splitWidth / 2));
// float pY = grid.context.y + grid.context.height;
// Vector3 p1 = new Vector3(pX, grid.context.y);
// Vector3 p2 = new Vector3(pX, pY);
// Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY);
// Vector3 p4 = new Vector3(pX + tooltipSplitWid, grid.context.y);
// UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor);
// }
// else
{
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
}
if (tooltip.type == Tooltip.Type.Corss)
{
sp = new Vector2(grid.context.x, chart.pointerPos.y);
ep = new Vector2(grid.context.x + grid.context.width, chart.pointerPos.y);
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
}
break;
case Tooltip.Type.Shadow:
if (xAxis.IsCategory())
{
float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth;
pX = (float) (grid.context.x + splitWidth * xAxis.context.pointerValue -
(xAxis.boundaryGap ? 0 : splitWidth / 2));
float pY = grid.context.y + grid.context.height;
Vector3 p1 = new Vector3(pX, grid.context.y);
Vector3 p2 = new Vector3(pX, pY);
Vector3 p3 = new Vector3(pX + tooltipSplitWid, pY);
Vector3 p4 = new Vector3(pX + tooltipSplitWid, grid.context.y);
UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor);
}
break;
}
}
}
}
private void DrawYAxisIndicator(VertexHelper vh, Tooltip tooltip, GridCoord grid)
{
var yAxes = chart.GetChartComponents<YAxis>();
var lineType = tooltip.lineStyle.GetType(chart.theme.tooltip.lineType);
var lineWidth = tooltip.lineStyle.GetWidth(chart.theme.tooltip.lineWidth);
foreach (var component in yAxes)
{
var yAxis = component as YAxis;
if (yAxis.gridIndex == grid.index)
{
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
int dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0;
float splitWidth = AxisHelper.GetDataWidth(yAxis, grid.context.height, dataCount, dataZoom);
switch (tooltip.type)
{
case Tooltip.Type.Corss:
case Tooltip.Type.Line:
float pY = (float) (grid.context.y + yAxis.context.pointerValue * splitWidth +
(yAxis.boundaryGap ? splitWidth / 2 : 0));
Vector2 sp = new Vector2(grid.context.x, pY);
Vector2 ep = new Vector2(grid.context.x + grid.context.width, pY);
var lineColor = TooltipHelper.GetLineColor(tooltip, chart.theme);
// if (yAxis.IsCategory() && tooltip.type == Tooltip.Type.Corss)
// {
// float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth;
// float pX = grid.context.x + grid.context.width;
// pY = (float)(grid.context.y + splitWidth * yAxis.context.pointerValue -
// (yAxis.boundaryGap ? 0 : splitWidth / 2));
// Vector3 p1 = new Vector3(grid.context.x, pY);
// Vector3 p2 = new Vector3(grid.context.x, pY + tooltipSplitWid);
// Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid);
// Vector3 p4 = new Vector3(pX, pY);
// UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor);
// }
// else
{
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
}
if (tooltip.type == Tooltip.Type.Corss)
{
sp = new Vector2(chart.pointerPos.x, grid.context.y);
ep = new Vector2(chart.pointerPos.x, grid.context.y + grid.context.height);
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
}
break;
case Tooltip.Type.Shadow:
if (yAxis.IsCategory())
{
float tooltipSplitWid = splitWidth < 1 ? 1 : splitWidth;
float pX = grid.context.x + grid.context.width;
pY = (float) (grid.context.y + splitWidth * yAxis.context.pointerValue -
(yAxis.boundaryGap ? 0 : splitWidth / 2));
Vector3 p1 = new Vector3(grid.context.x, pY);
Vector3 p2 = new Vector3(grid.context.x, pY + tooltipSplitWid);
Vector3 p3 = new Vector3(pX, pY + tooltipSplitWid);
Vector3 p4 = new Vector3(pX, pY);
UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, chart.theme.tooltip.areaColor);
}
break;
}
}
}
}
private void DrawPolarIndicator(VertexHelper vh, Tooltip tooltip, PolarCoord m_Polar)
{
if (tooltip.context.angle < 0) return;
var theme = chart.theme;
var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_Polar.index);
var lineColor = TooltipHelper.GetLineColor(tooltip, theme);
var lineType = tooltip.lineStyle.GetType(theme.tooltip.lineType);
var lineWidth = tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth);
var cenPos = m_Polar.context.center;
var radius = m_Polar.context.radius;
var sp = m_Polar.context.center;
var tooltipAngle = m_AngleAxis.GetValueAngle(tooltip.context.angle);
var ep = ChartHelper.GetPos(sp, radius, tooltipAngle, true);
switch (tooltip.type)
{
case Tooltip.Type.Corss:
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
var dist = Vector2.Distance(chart.pointerPos, cenPos);
if (dist > radius) dist = radius;
var outsideRaidus = dist + tooltip.lineStyle.GetWidth(theme.tooltip.lineWidth) * 2;
UGL.DrawDoughnut(vh, cenPos, dist, outsideRaidus, lineColor, Color.clear);
break;
case Tooltip.Type.Line:
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, sp, ep, lineColor);
break;
case Tooltip.Type.Shadow:
UGL.DrawSector(vh, cenPos, radius, lineColor, tooltipAngle - 2, tooltipAngle + 2, chart.settings.cicleSmoothness);
break;
}
}
}
}