Fist Sub
based on aimbot multi seane
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db4db63725f6848e785146f5cf4bb657
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(BarHandler), true)]
|
||||
[SerieConvert(typeof(Line), typeof(Pie))]
|
||||
[RequireChartComponent(typeof(GridCoord))]
|
||||
[DefaultAnimation(AnimationType.BottomToTop)]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField("m_Ignore")]
|
||||
public class Bar : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Bar>(serieName);
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
chart.AddData(serie.index, UnityEngine.Random.Range(10, 90));
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static Bar CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = SerieHelper.CloneSerie<Bar>(serie);
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cfb8051cfc49e4afabd94a11c5912c3e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,436 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class BarHandler : SerieHandler<Bar>
|
||||
{
|
||||
List<List<SerieData>> m_StackSerieData = new List<List<SerieData>>();
|
||||
private GridCoord m_SerieGrid;
|
||||
private float[] m_CapusleDefaultCornerRadius = new float[] { 1, 1, 1, 1 };
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category,
|
||||
marker, itemFormatter, numericFormatter);
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
DrawBarSerie(vh, serie, serie.context.colorIndex);
|
||||
}
|
||||
|
||||
public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
|
||||
{
|
||||
switch (label.position)
|
||||
{
|
||||
case LabelStyle.Position.Bottom:
|
||||
var center = serieData.context.rect.center;
|
||||
return new Vector3(center.x, center.y - serieData.context.rect.height / 2);
|
||||
case LabelStyle.Position.Center:
|
||||
case LabelStyle.Position.Inside:
|
||||
return serieData.context.rect.center;
|
||||
default:
|
||||
return serieData.context.position;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (!serie.context.pointerEnter) return;
|
||||
if (serie.context.pointerItemDataIndex < 0) return;
|
||||
if (chart.onPointerClickBar != null)
|
||||
{
|
||||
chart.onPointerClickBar(eventData, serie.context.pointerItemDataIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter;
|
||||
var needInteract = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.Reset();
|
||||
}
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serie.context.pointerAxisDataIndexs.Contains(serieData.index) ||
|
||||
serieData.context.rect.Contains(chart.pointerPos))
|
||||
{
|
||||
serie.context.pointerItemDataIndex = serieData.index;
|
||||
serie.context.pointerEnter = true;
|
||||
serieData.context.highlight = true;
|
||||
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBarSerie(VertexHelper vh, Bar serie, int colorIndex)
|
||||
{
|
||||
if (!serie.show || serie.animation.HasFadeOut())
|
||||
return;
|
||||
|
||||
var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components);
|
||||
|
||||
Axis axis;
|
||||
Axis relativedAxis;
|
||||
|
||||
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);
|
||||
}
|
||||
m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
|
||||
if (axis == null)
|
||||
return;
|
||||
if (relativedAxis == null)
|
||||
return;
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
|
||||
if (showData.Count <= 0)
|
||||
return;
|
||||
|
||||
var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width;
|
||||
var relativedAxisLength = isY ? m_SerieGrid.context.width : m_SerieGrid.context.height;
|
||||
var axisXY = isY ? m_SerieGrid.context.y : m_SerieGrid.context.x;
|
||||
|
||||
var isStack = SeriesHelper.IsStack<Bar>(chart.series, serie.stack);
|
||||
if (isStack)
|
||||
SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData);
|
||||
|
||||
var barCount = chart.GetSerieBarRealCount<Bar>();
|
||||
float categoryWidth = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom);
|
||||
float barGap = chart.GetSerieBarGap<Bar>();
|
||||
float totalBarWidth = chart.GetSerieTotalWidth<Bar>(categoryWidth, barGap, barCount);
|
||||
float barWidth = serie.GetBarWidth(categoryWidth, barCount);
|
||||
float offset = (categoryWidth - totalBarWidth) * 0.5f;
|
||||
var serieReadIndex = chart.GetSerieIndexIfStack<Bar>(serie);
|
||||
float gap = serie.barGap == -1 ? offset : offset + chart.GetSerieTotalGap<Bar>(categoryWidth, barGap, serieReadIndex);
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > showData.Count ? showData.Count : serie.maxShow) :
|
||||
showData.Count;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series, serie.stack);
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double yMinValue = relativedAxis.context.minValue;
|
||||
double yMaxValue = relativedAxis.context.maxValue;
|
||||
|
||||
var areaColor = ColorUtil.clearColor32;
|
||||
var areaToColor = ColorUtil.clearColor32;
|
||||
var interacting = false;
|
||||
|
||||
serie.containerIndex = m_SerieGrid.index;
|
||||
serie.containterInstanceId = m_SerieGrid.instanceId;
|
||||
serie.animation.InitProgress(axisXY, axisXY + axisLength);
|
||||
for (int i = serie.minShow; i < maxCount; i++)
|
||||
{
|
||||
var serieData = showData[i];
|
||||
serieData.index = i;
|
||||
if (!serieData.show || serie.IsIgnoreValue(serieData))
|
||||
{
|
||||
serie.context.dataPoints.Add(Vector3.zero);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (serieData.IsDataChanged())
|
||||
dataChanging = true;
|
||||
|
||||
var highlight = serieData.context.highlight || serie.highlight;
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
|
||||
var value = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse);
|
||||
var relativedValue = serieData.GetCurrData(1, dataChangeDuration, relativedAxis.inverse, yMinValue, yMaxValue);
|
||||
var borderWidth = relativedValue == 0 ? 0 : itemStyle.runtimeBorderWidth;
|
||||
var borderGap = relativedValue == 0 ? 0 : itemStyle.borderGap;
|
||||
var borderGapAndWidth = borderWidth + borderGap;
|
||||
|
||||
if (!serieData.interact.TryGetColor(ref areaColor, ref areaToColor, ref interacting))
|
||||
{
|
||||
areaColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, highlight);
|
||||
areaToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, highlight);
|
||||
serieData.interact.SetColor(ref interacting, areaColor, areaToColor);
|
||||
}
|
||||
|
||||
var pX = 0f;
|
||||
var pY = 0f;
|
||||
UpdateXYPosition(m_SerieGrid, isY, axis, relativedAxis, i, categoryWidth, barWidth, isStack, value, ref pX, ref pY);
|
||||
var barHig = 0f;
|
||||
if (isPercentStack)
|
||||
{
|
||||
var valueTotal = chart.GetSerieSameStackTotalValue<Bar>(serie.stack, i);
|
||||
barHig = valueTotal != 0 ? (float) (relativedValue / valueTotal * relativedAxisLength) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
barHig = AxisHelper.GetAxisValueLength(m_SerieGrid, relativedAxis, categoryWidth, relativedValue);
|
||||
}
|
||||
|
||||
float currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig);
|
||||
Vector3 plb, plt, prt, prb, top;
|
||||
UpdateRectPosition(m_SerieGrid, isY, relativedValue, pX, pY, gap, borderWidth, barWidth, currHig,
|
||||
out plb, out plt, out prt, out prb, out top);
|
||||
serieData.context.stackHeight = barHig;
|
||||
serieData.context.position = top;
|
||||
serieData.context.rect = Rect.MinMaxRect(plb.x + borderGapAndWidth, plb.y + borderGapAndWidth,
|
||||
prt.x - borderGapAndWidth, prt.y - borderGapAndWidth);
|
||||
serieData.context.backgroundRect = isY ?
|
||||
Rect.MinMaxRect(m_SerieGrid.context.x, plb.y, m_SerieGrid.context.x + relativedAxisLength, prt.y) :
|
||||
Rect.MinMaxRect(plb.x, m_SerieGrid.context.y, prb.x, m_SerieGrid.context.y + relativedAxisLength);
|
||||
|
||||
if (!serie.clip || (serie.clip && m_SerieGrid.Contains(top)))
|
||||
serie.context.dataPoints.Add(top);
|
||||
else
|
||||
continue;
|
||||
|
||||
if (serie.show && currHig != 0 && !serie.placeHolder)
|
||||
{
|
||||
switch (serie.barType)
|
||||
{
|
||||
case BarType.Normal:
|
||||
case BarType.Capsule:
|
||||
DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, gap, barWidth,
|
||||
pX, pY, plb, plt, prt, prb, isY, m_SerieGrid, axis, areaColor, areaToColor, relativedValue);
|
||||
break;
|
||||
case BarType.Zebra:
|
||||
DrawZebraBar(vh, serie, serieData, itemStyle, colorIndex, highlight, gap, barWidth,
|
||||
pX, pY, plb, plt, prt, prb, isY, m_SerieGrid, axis, areaColor, areaToColor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (serie.animation.CheckDetailBreak(top, isY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging || interacting)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateXYPosition(GridCoord grid, bool isY, Axis axis, Axis relativedAxis, int i, float categoryWidth, float barWidth, bool isStack,
|
||||
double value, ref float pX, ref float pY)
|
||||
{
|
||||
if (isY)
|
||||
{
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
pY = grid.context.y + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.context.minMaxRange <= 0) pY = grid.context.y;
|
||||
else
|
||||
{
|
||||
var valueLen = (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * grid.context.height;
|
||||
pY = grid.context.y + valueLen - categoryWidth * 0.5f;
|
||||
}
|
||||
}
|
||||
pX = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0);
|
||||
if (isStack)
|
||||
{
|
||||
for (int n = 0; n < m_StackSerieData.Count - 1; n++)
|
||||
pX += m_StackSerieData[n][i].context.stackHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
pX = grid.context.x + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.context.minMaxRange <= 0) pX = grid.context.x;
|
||||
else
|
||||
{
|
||||
var valueLen = (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * grid.context.width;
|
||||
pX = grid.context.x + valueLen - categoryWidth * 0.5f;
|
||||
}
|
||||
}
|
||||
pY = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0);
|
||||
if (isStack)
|
||||
{
|
||||
for (int n = 0; n < m_StackSerieData.Count - 1; n++)
|
||||
pY += m_StackSerieData[n][i].context.stackHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRectPosition(GridCoord grid, bool isY, double yValue, float pX, float pY, float gap, float borderWidth,
|
||||
float barWidth, float currHig,
|
||||
out Vector3 plb, out Vector3 plt, out Vector3 prt, out Vector3 prb, out Vector3 top)
|
||||
{
|
||||
if (isY)
|
||||
{
|
||||
if (yValue < 0)
|
||||
{
|
||||
plt = new Vector3(pX + currHig, pY + gap + barWidth);
|
||||
prt = new Vector3(pX, pY + gap + barWidth);
|
||||
prb = new Vector3(pX, pY + gap);
|
||||
plb = new Vector3(pX + currHig, pY + gap);
|
||||
}
|
||||
else
|
||||
{
|
||||
plt = new Vector3(pX, pY + gap + barWidth);
|
||||
prt = new Vector3(pX + currHig, pY + gap + barWidth);
|
||||
prb = new Vector3(pX + currHig, pY + gap);
|
||||
plb = new Vector3(pX, pY + gap);
|
||||
}
|
||||
top = new Vector3(pX + currHig, pY + gap + barWidth / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yValue < 0)
|
||||
{
|
||||
plb = new Vector3(pX + gap, pY + currHig);
|
||||
plt = new Vector3(pX + gap, pY);
|
||||
prt = new Vector3(pX + gap + barWidth, pY);
|
||||
prb = new Vector3(pX + gap + barWidth, pY + currHig);
|
||||
}
|
||||
else
|
||||
{
|
||||
plb = new Vector3(pX + gap, pY);
|
||||
plt = new Vector3(pX + gap, pY + currHig);
|
||||
prt = new Vector3(pX + gap + barWidth, pY + currHig);
|
||||
prb = new Vector3(pX + gap + barWidth, pY);
|
||||
}
|
||||
top = new Vector3(pX + gap + barWidth / 2, pY + currHig);
|
||||
}
|
||||
if (serie.clip)
|
||||
{
|
||||
plb = chart.ClampInGrid(grid, plb);
|
||||
plt = chart.ClampInGrid(grid, plt);
|
||||
prt = chart.ClampInGrid(grid, prt);
|
||||
prb = chart.ClampInGrid(grid, prb);
|
||||
top = chart.ClampInGrid(grid, top);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawNormalBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex,
|
||||
bool highlight, float gap, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt,
|
||||
Vector3 prb, bool isYAxis, GridCoord grid, Axis axis, Color32 areaColor, Color32 areaToColor, double value)
|
||||
{
|
||||
var borderWidth = itemStyle.runtimeBorderWidth;
|
||||
var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, colorIndex, highlight, false);
|
||||
var cornerRadius = serie.barType == BarType.Capsule && !itemStyle.IsNeedCorner() ?
|
||||
m_CapusleDefaultCornerRadius :
|
||||
itemStyle.cornerRadius;
|
||||
var invert = value < 0;
|
||||
if (!ChartHelper.IsClearColor(backgroundColor))
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, serieData.context.backgroundRect, backgroundColor, backgroundColor, 0,
|
||||
cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert);
|
||||
}
|
||||
UGL.DrawRoundRectangle(vh, serieData.context.rect, areaColor, areaToColor, 0,
|
||||
cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert);
|
||||
if (serie.barType == BarType.Capsule)
|
||||
{
|
||||
UGL.DrawBorder(vh, serieData.context.backgroundRect, borderWidth, itemStyle.borderColor,
|
||||
0, cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert, -borderWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawBorder(vh, serieData.context.rect, borderWidth, itemStyle.borderColor,
|
||||
0, cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert, itemStyle.borderGap);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawZebraBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex,
|
||||
bool highlight, float gap, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt,
|
||||
Vector3 prb, bool isYAxis, GridCoord grid, Axis axis, Color32 barColor, Color32 barToColor)
|
||||
{
|
||||
var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, colorIndex, highlight, false);
|
||||
if (!ChartHelper.IsClearColor(backgroundColor))
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, serieData.context.backgroundRect, backgroundColor, backgroundColor, 0,
|
||||
null, isYAxis, chart.settings.cicleSmoothness, false);
|
||||
}
|
||||
if (isYAxis)
|
||||
{
|
||||
plt = (plb + plt) / 2;
|
||||
prt = (prt + prb) / 2;
|
||||
chart.DrawClipZebraLine(vh, plt, prt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap,
|
||||
barColor, barToColor, serie.clip, grid, grid.context.width);
|
||||
}
|
||||
else
|
||||
{
|
||||
plb = (prb + plb) / 2;
|
||||
plt = (plt + prt) / 2;
|
||||
chart.DrawClipZebraLine(vh, plb, plt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap,
|
||||
barColor, barToColor, serie.clip, grid, grid.context.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bd8425bf4c1b4bf2adf8940be58ddec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[Serializable]
|
||||
[SerieHandler(typeof(SimplifiedBarHandler), true)]
|
||||
[SerieConvert(typeof(SimplifiedLine), typeof(Bar))]
|
||||
[CoordOptions(typeof(GridCoord))]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[SerieExtraComponent()]
|
||||
[SerieDataExtraComponent()]
|
||||
[SerieDataExtraField()]
|
||||
public class SimplifiedBar : Serie, INeedSerieContainer, ISimplifiedSerie
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<SimplifiedBar>(serieName);
|
||||
serie.symbol.show = false;
|
||||
var lastValue = 0d;
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
if (i < 20)
|
||||
lastValue += UnityEngine.Random.Range(0, 5);
|
||||
else
|
||||
lastValue += UnityEngine.Random.Range(-3, 5);
|
||||
chart.AddData(serie.index, lastValue);
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static SimplifiedBar CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = serie.Clone<SimplifiedBar>();
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fc754e0afd4d4f138389c19611aaedb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,368 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class SimplifiedBarHandler : SerieHandler<SimplifiedBar>
|
||||
{
|
||||
private GridCoord m_SerieGrid;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category,
|
||||
marker, itemFormatter, numericFormatter);
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
DrawBarSerie(vh, serie, serie.context.colorIndex);
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter;
|
||||
var needInteract = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.context.rect.Contains(chart.pointerPos))
|
||||
{
|
||||
serie.context.pointerItemDataIndex = serieData.index;
|
||||
serie.context.pointerEnter = true;
|
||||
serieData.context.highlight = true;
|
||||
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, true);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
var barColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
var barToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
serieData.interact.SetColor(ref needInteract, barColor, barToColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBarSerie(VertexHelper vh, SimplifiedBar serie, int colorIndex)
|
||||
{
|
||||
if (!serie.show || serie.animation.HasFadeOut())
|
||||
return;
|
||||
|
||||
var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components);
|
||||
|
||||
Axis axis;
|
||||
Axis relativedAxis;
|
||||
|
||||
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);
|
||||
}
|
||||
m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
|
||||
if (axis == null)
|
||||
return;
|
||||
if (relativedAxis == null)
|
||||
return;
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
|
||||
if (showData.Count <= 0)
|
||||
return;
|
||||
|
||||
var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width;
|
||||
var axisXY = isY ? m_SerieGrid.context.y : m_SerieGrid.context.x;
|
||||
|
||||
var barCount = chart.GetSerieBarRealCount<SimplifiedBar>();
|
||||
float categoryWidth = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom);
|
||||
float barGap = chart.GetSerieBarGap<SimplifiedBar>();
|
||||
float totalBarWidth = chart.GetSerieTotalWidth<SimplifiedBar>(categoryWidth, barGap, barCount);
|
||||
float barWidth = serie.GetBarWidth(categoryWidth, barCount);
|
||||
float offset = (categoryWidth - totalBarWidth) * 0.5f;
|
||||
float barGapWidth = barWidth + barWidth * barGap;
|
||||
float gap = serie.barGap == -1 ? offset : offset + serie.index * barGapWidth;
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > showData.Count ? showData.Count : serie.maxShow) :
|
||||
showData.Count;
|
||||
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double yMinValue = relativedAxis.context.minValue;
|
||||
double yMaxValue = relativedAxis.context.maxValue;
|
||||
|
||||
var areaColor = ColorUtil.clearColor32;
|
||||
var areaToColor = ColorUtil.clearColor32;
|
||||
var interacting = false;
|
||||
|
||||
serie.containerIndex = m_SerieGrid.index;
|
||||
serie.containterInstanceId = m_SerieGrid.instanceId;
|
||||
serie.animation.InitProgress(axisXY, axisXY + axisLength);
|
||||
for (int i = serie.minShow; i < maxCount; i++)
|
||||
{
|
||||
var serieData = showData[i];
|
||||
if (!serieData.show || serie.IsIgnoreValue(serieData))
|
||||
{
|
||||
serie.context.dataPoints.Add(Vector3.zero);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (serieData.IsDataChanged())
|
||||
dataChanging = true;
|
||||
|
||||
var highlight = serieData.context.highlight || serie.highlight;
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
|
||||
var value = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse);
|
||||
var relativedValue = serieData.GetCurrData(1, dataChangeDuration, relativedAxis.inverse, yMinValue, yMaxValue);
|
||||
var borderWidth = relativedValue == 0 ? 0 : itemStyle.runtimeBorderWidth;
|
||||
|
||||
if (!serieData.interact.TryGetColor(ref areaColor, ref areaToColor, ref interacting))
|
||||
{
|
||||
areaColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, highlight);
|
||||
areaToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, highlight);
|
||||
serieData.interact.SetColor(ref interacting, areaColor, areaToColor);
|
||||
}
|
||||
|
||||
var pX = 0f;
|
||||
var pY = 0f;
|
||||
UpdateXYPosition(m_SerieGrid, isY, axis, relativedAxis, i, categoryWidth, barWidth, value, ref pX, ref pY);
|
||||
|
||||
var barHig = AxisHelper.GetAxisValueLength(m_SerieGrid, relativedAxis, categoryWidth, relativedValue);
|
||||
var currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig);
|
||||
|
||||
Vector3 plb, plt, prt, prb, top;
|
||||
UpdateRectPosition(m_SerieGrid, isY, relativedValue, pX, pY, gap, borderWidth, barWidth, currHig,
|
||||
out plb, out plt, out prt, out prb, out top);
|
||||
serieData.context.stackHeight = barHig;
|
||||
serieData.context.position = top;
|
||||
serieData.context.rect = Rect.MinMaxRect(plb.x, plb.y, prb.x, prt.y);
|
||||
serie.context.dataPoints.Add(top);
|
||||
DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, gap, barWidth,
|
||||
pX, pY, plb, plt, prt, prb, false, m_SerieGrid, areaColor, areaToColor);
|
||||
|
||||
if (serie.animation.CheckDetailBreak(top, isY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging || interacting)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateXYPosition(GridCoord grid, bool isY, Axis axis, Axis relativedAxis, int i, float categoryWidth, float barWidth,
|
||||
double value, ref float pX, ref float pY)
|
||||
{
|
||||
if (isY)
|
||||
{
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
pY = grid.context.y + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.context.minMaxRange <= 0) pY = grid.context.y;
|
||||
else pY = grid.context.y + (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * (grid.context.height - barWidth);
|
||||
}
|
||||
pX = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
pX = grid.context.x + i * categoryWidth + (axis.boundaryGap ? 0 : -categoryWidth * 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.context.minMaxRange <= 0) pX = grid.context.x;
|
||||
else pX = grid.context.x + (float) ((value - axis.context.minValue) / axis.context.minMaxRange) * (grid.context.width - barWidth);
|
||||
}
|
||||
pY = AxisHelper.GetAxisValuePosition(grid, relativedAxis, categoryWidth, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRectPosition(GridCoord grid, bool isY, double yValue, float pX, float pY, float gap, float borderWidth,
|
||||
float barWidth, float currHig,
|
||||
out Vector3 plb, out Vector3 plt, out Vector3 prt, out Vector3 prb, out Vector3 top)
|
||||
{
|
||||
if (isY)
|
||||
{
|
||||
if (yValue < 0)
|
||||
{
|
||||
plt = new Vector3(pX - borderWidth, pY + gap + barWidth - borderWidth);
|
||||
prt = new Vector3(pX + currHig + borderWidth, pY + gap + barWidth - borderWidth);
|
||||
prb = new Vector3(pX + currHig + borderWidth, pY + gap + borderWidth);
|
||||
plb = new Vector3(pX - borderWidth, pY + gap + borderWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
plt = new Vector3(pX + borderWidth, pY + gap + barWidth - borderWidth);
|
||||
prt = new Vector3(pX + currHig - borderWidth, pY + gap + barWidth - borderWidth);
|
||||
prb = new Vector3(pX + currHig - borderWidth, pY + gap + borderWidth);
|
||||
plb = new Vector3(pX + borderWidth, pY + gap + borderWidth);
|
||||
}
|
||||
top = new Vector3(pX + currHig - borderWidth, pY + gap + barWidth / 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (yValue < 0)
|
||||
{
|
||||
plb = new Vector3(pX + gap + borderWidth, pY - borderWidth);
|
||||
plt = new Vector3(pX + gap + borderWidth, pY + currHig + borderWidth);
|
||||
prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig + borderWidth);
|
||||
prb = new Vector3(pX + gap + barWidth - borderWidth, pY - borderWidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
plb = new Vector3(pX + gap + borderWidth, pY + borderWidth);
|
||||
plt = new Vector3(pX + gap + borderWidth, pY + currHig - borderWidth);
|
||||
prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig - borderWidth);
|
||||
prb = new Vector3(pX + gap + barWidth - borderWidth, pY + borderWidth);
|
||||
}
|
||||
top = new Vector3(pX + gap + barWidth / 2, pY + currHig - borderWidth);
|
||||
}
|
||||
if (serie.clip)
|
||||
{
|
||||
plb = chart.ClampInGrid(grid, plb);
|
||||
plt = chart.ClampInGrid(grid, plt);
|
||||
prt = chart.ClampInGrid(grid, prt);
|
||||
prb = chart.ClampInGrid(grid, prb);
|
||||
top = chart.ClampInGrid(grid, top);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawNormalBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex,
|
||||
bool highlight, float gap, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt,
|
||||
Vector3 prb, bool isYAxis, GridCoord grid, Color32 areaColor, Color32 areaToColor)
|
||||
{
|
||||
|
||||
var borderWidth = itemStyle.runtimeBorderWidth;
|
||||
if (isYAxis)
|
||||
{
|
||||
if (serie.clip)
|
||||
{
|
||||
prb = chart.ClampInGrid(grid, prb);
|
||||
plb = chart.ClampInGrid(grid, plb);
|
||||
plt = chart.ClampInGrid(grid, plt);
|
||||
prt = chart.ClampInGrid(grid, prt);
|
||||
}
|
||||
var itemWidth = Mathf.Abs(prb.x - plt.x);
|
||||
var itemHeight = Mathf.Abs(prt.y - plb.y);
|
||||
var center = new Vector3((plt.x + prb.x) / 2, (prt.y + plb.y) / 2);
|
||||
if (itemWidth > 0 && itemHeight > 0)
|
||||
{
|
||||
var invert = center.x < plb.x;
|
||||
if (itemStyle.IsNeedCorner())
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaToColor, 0,
|
||||
itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert);
|
||||
}
|
||||
else
|
||||
{
|
||||
chart.DrawClipPolygon(vh, plb, plt, prt, prb, areaColor, areaToColor, serie.clip, grid);
|
||||
}
|
||||
UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor,
|
||||
itemStyle.borderToColor, 0, itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (serie.clip)
|
||||
{
|
||||
prb = chart.ClampInGrid(grid, prb);
|
||||
plb = chart.ClampInGrid(grid, plb);
|
||||
plt = chart.ClampInGrid(grid, plt);
|
||||
prt = chart.ClampInGrid(grid, prt);
|
||||
}
|
||||
var itemWidth = Mathf.Abs(prt.x - plb.x);
|
||||
var itemHeight = Mathf.Abs(plt.y - prb.y);
|
||||
var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2);
|
||||
if (itemWidth > 0 && itemHeight > 0)
|
||||
{
|
||||
var invert = center.y < plb.y;
|
||||
if (itemStyle.IsNeedCorner())
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaToColor, 0,
|
||||
itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert);
|
||||
}
|
||||
else
|
||||
{
|
||||
chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaToColor,
|
||||
serie.clip, grid);
|
||||
}
|
||||
UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor,
|
||||
itemStyle.borderToColor, 0, itemStyle.cornerRadius, isYAxis, chart.settings.cicleSmoothness, invert);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: afd7226ecff7f4b9fad297101bc33b8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 641a5dafd45e6455ca9ef9558efe1083
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(CandlestickHandler), true)]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[SerieExtraComponent()]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(EmphasisItemStyle))]
|
||||
[SerieDataExtraField()]
|
||||
public class Candlestick : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Candlestick>(serieName);
|
||||
var defaultDataCount = 5;
|
||||
for (int i = 0; i < defaultDataCount; i++)
|
||||
{
|
||||
var open = Random.Range(20, 60);
|
||||
var close = Random.Range(40, 90);
|
||||
var lowest = Random.Range(0, 50);
|
||||
var heighest = Random.Range(50, 100);
|
||||
chart.AddData(serie.index, open, close, lowest, heighest);
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1fbb6247f54f4dd2a1f3e7f6bafb8c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,213 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class CandlestickHandler : SerieHandler<Candlestick>
|
||||
{
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
DrawCandlestickSerie(vh, serie);
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
if (dataIndex < 0)
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
title = category;
|
||||
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
var newMarker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
var newItemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
var newNumericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.category = category;
|
||||
param.dimension = 1;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = 0;
|
||||
param.total = 0;
|
||||
param.color = color;
|
||||
param.marker = newMarker;
|
||||
param.itemFormatter = newItemFormatter;
|
||||
param.numericFormatter = newNumericFormatter;
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(serie.serieName);
|
||||
param.columns.Add(string.Empty);
|
||||
|
||||
paramList.Add(param);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
param = new SerieParams();
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.dimension = i;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = serieData.GetData(i);
|
||||
param.total = SerieHelper.GetMaxData(serie, i);
|
||||
param.color = color;
|
||||
param.marker = newMarker;
|
||||
param.itemFormatter = newItemFormatter;
|
||||
param.numericFormatter = newNumericFormatter;
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i));
|
||||
param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCandlestickSerie(VertexHelper vh, Candlestick serie)
|
||||
{
|
||||
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 dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
float categoryWidth = AxisHelper.GetDataWidth(xAxis, grid.context.width, showData.Count, dataZoom);
|
||||
float barWidth = serie.GetBarWidth(categoryWidth);
|
||||
float gap = (categoryWidth - barWidth) / 2;
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > showData.Count ? showData.Count : serie.maxShow) :
|
||||
showData.Count;
|
||||
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double yMinValue = yAxis.context.minValue;
|
||||
double yMaxValue = yAxis.context.maxValue;
|
||||
var isYAxis = false;
|
||||
serie.containerIndex = grid.index;
|
||||
serie.containterInstanceId = grid.instanceId;
|
||||
for (int i = serie.minShow; i < maxCount; i++)
|
||||
{
|
||||
var serieData = showData[i];
|
||||
if (serie.IsIgnoreValue(serieData))
|
||||
{
|
||||
serie.context.dataPoints.Add(Vector3.zero);
|
||||
continue;
|
||||
}
|
||||
var highlight = serie.data[i].context.highlight || serie.highlight;
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
|
||||
var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var isRise = yAxis.inverse ? close<open : close> open;
|
||||
var borderWidth = open == 0 ? 0f :
|
||||
(itemStyle.runtimeBorderWidth == 0 ? theme.serie.candlestickBorderWidth :
|
||||
itemStyle.runtimeBorderWidth);
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
float pX = grid.context.x + i * categoryWidth;
|
||||
float zeroY = grid.context.y + yAxis.context.offset;
|
||||
if (!xAxis.boundaryGap) pX -= categoryWidth / 2;
|
||||
float pY = zeroY;
|
||||
var barHig = 0f;
|
||||
double valueTotal = yMaxValue - yMinValue;
|
||||
var minCut = (yMinValue > 0 ? yMinValue : 0);
|
||||
if (valueTotal != 0)
|
||||
{
|
||||
barHig = (float) ((close - open) / valueTotal * grid.context.height);
|
||||
pY += (float) ((open - minCut) / valueTotal * grid.context.height);
|
||||
}
|
||||
serieData.context.stackHeight = barHig;
|
||||
float currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig);
|
||||
Vector3 plb, plt, prt, prb, top;
|
||||
|
||||
plb = new Vector3(pX + gap + borderWidth, pY + borderWidth);
|
||||
plt = new Vector3(pX + gap + borderWidth, pY + currHig - borderWidth);
|
||||
prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig - borderWidth);
|
||||
prb = new Vector3(pX + gap + barWidth - borderWidth, pY + borderWidth);
|
||||
top = new Vector3(pX + gap + barWidth / 2, pY + currHig - borderWidth);
|
||||
if (serie.clip)
|
||||
{
|
||||
plb = chart.ClampInGrid(grid, plb);
|
||||
plt = chart.ClampInGrid(grid, plt);
|
||||
prt = chart.ClampInGrid(grid, prt);
|
||||
prb = chart.ClampInGrid(grid, prb);
|
||||
top = chart.ClampInGrid(grid, top);
|
||||
}
|
||||
serie.context.dataPoints.Add(top);
|
||||
var areaColor = isRise ?
|
||||
itemStyle.GetColor(theme.serie.candlestickColor) :
|
||||
itemStyle.GetColor0(theme.serie.candlestickColor0);
|
||||
var borderColor = isRise ?
|
||||
itemStyle.GetBorderColor(theme.serie.candlestickBorderColor) :
|
||||
itemStyle.GetBorderColor0(theme.serie.candlestickBorderColor0);
|
||||
var itemWidth = Mathf.Abs(prt.x - plb.x);
|
||||
var itemHeight = Mathf.Abs(plt.y - prb.y);
|
||||
var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2);
|
||||
var lowPos = new Vector3(center.x, zeroY + (float) ((lowest - minCut) / valueTotal * grid.context.height));
|
||||
var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height));
|
||||
var openCenterPos = new Vector3(center.x, prb.y);
|
||||
var closeCenterPos = new Vector3(center.x, prt.y);
|
||||
if (barWidth > 2f * borderWidth)
|
||||
{
|
||||
if (itemWidth > 0 && itemHeight > 0)
|
||||
{
|
||||
if (itemStyle.IsNeedCorner())
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0,
|
||||
itemStyle.cornerRadius, isYAxis, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor,
|
||||
serie.clip, grid);
|
||||
}
|
||||
UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0,
|
||||
itemStyle.cornerRadius, isYAxis, 0.5f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor);
|
||||
}
|
||||
if (isRise)
|
||||
{
|
||||
UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor);
|
||||
UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor);
|
||||
UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor);
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d530c536c5784f2593e9a7c5a57df16
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(SimplifiedCandlestickHandler), true)]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[SerieExtraComponent()]
|
||||
[SerieDataExtraComponent()]
|
||||
[SerieDataExtraField()]
|
||||
public class SimplifiedCandlestick : Serie, INeedSerieContainer, ISimplifiedSerie
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<SimplifiedCandlestick>(serieName);
|
||||
|
||||
var lastValue = 50d;
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
lastValue += UnityEngine.Random.Range(-10, 20);
|
||||
var open = lastValue + Random.Range(-10, 5);
|
||||
var close = lastValue + Random.Range(-5, 10);
|
||||
var lowest = lastValue + Random.Range(-15, -10);
|
||||
var heighest = lastValue + Random.Range(10, 20);
|
||||
chart.AddData(serie.index, open, close, lowest, heighest);
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static SimplifiedCandlestick CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = serie.Clone<SimplifiedCandlestick>();
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1202f0da64c484488bb69b8382af9918
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,214 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class SimplifiedCandlestickHandler : SerieHandler<SimplifiedCandlestick>
|
||||
{
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
DrawCandlestickSerie(vh, serie);
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
if (dataIndex < 0)
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
title = category;
|
||||
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
var newMarker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
var newItemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
var newNumericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.category = category;
|
||||
param.dimension = 1;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = 0;
|
||||
param.total = 0;
|
||||
param.color = color;
|
||||
param.marker = newMarker;
|
||||
param.itemFormatter = newItemFormatter;
|
||||
param.numericFormatter = newNumericFormatter;
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(serie.serieName);
|
||||
param.columns.Add(string.Empty);
|
||||
|
||||
paramList.Add(param);
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
param = new SerieParams();
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.dimension = i;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = serieData.GetData(i);
|
||||
param.total = SerieHelper.GetMaxData(serie, i);
|
||||
param.color = color;
|
||||
param.marker = newMarker;
|
||||
param.itemFormatter = newItemFormatter;
|
||||
param.numericFormatter = newNumericFormatter;
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(XCSettings.lang.GetCandlestickDimensionName(i));
|
||||
param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCandlestickSerie(VertexHelper vh, SimplifiedCandlestick serie)
|
||||
{
|
||||
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 dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
float categoryWidth = AxisHelper.GetDataWidth(xAxis, grid.context.width, showData.Count, dataZoom);
|
||||
float barWidth = serie.GetBarWidth(categoryWidth);
|
||||
float gap = (categoryWidth - barWidth) / 2;
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > showData.Count ? showData.Count : serie.maxShow) :
|
||||
showData.Count;
|
||||
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double yMinValue = yAxis.context.minValue;
|
||||
double yMaxValue = yAxis.context.maxValue;
|
||||
var isYAxis = false;
|
||||
var itemStyle = serie.itemStyle;
|
||||
serie.containerIndex = grid.index;
|
||||
serie.containterInstanceId = grid.instanceId;
|
||||
|
||||
for (int i = serie.minShow; i < maxCount; i++)
|
||||
{
|
||||
var serieData = showData[i];
|
||||
if (serie.IsIgnoreValue(serieData))
|
||||
{
|
||||
serie.context.dataPoints.Add(Vector3.zero);
|
||||
continue;
|
||||
}
|
||||
var open = serieData.GetCurrData(0, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var close = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var lowest = serieData.GetCurrData(2, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var heighest = serieData.GetCurrData(3, dataChangeDuration, yAxis.inverse, yMinValue, yMaxValue);
|
||||
var isRise = yAxis.inverse ? close<open : close> open;
|
||||
var borderWidth = open == 0 ? 0f :
|
||||
(itemStyle.runtimeBorderWidth == 0 ? theme.serie.candlestickBorderWidth :
|
||||
itemStyle.runtimeBorderWidth);
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
float pX = grid.context.x + i * categoryWidth;
|
||||
float zeroY = grid.context.y + yAxis.context.offset;
|
||||
if (!xAxis.boundaryGap) pX -= categoryWidth / 2;
|
||||
float pY = zeroY;
|
||||
var barHig = 0f;
|
||||
double valueTotal = yMaxValue - yMinValue;
|
||||
var minCut = (yMinValue > 0 ? yMinValue : 0);
|
||||
if (valueTotal != 0)
|
||||
{
|
||||
barHig = (float) ((close - open) / valueTotal * grid.context.height);
|
||||
pY += (float) ((open - minCut) / valueTotal * grid.context.height);
|
||||
}
|
||||
serieData.context.stackHeight = barHig;
|
||||
float currHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, barHig);
|
||||
Vector3 plb, plt, prt, prb, top;
|
||||
|
||||
plb = new Vector3(pX + gap + borderWidth, pY + borderWidth);
|
||||
plt = new Vector3(pX + gap + borderWidth, pY + currHig - borderWidth);
|
||||
prt = new Vector3(pX + gap + barWidth - borderWidth, pY + currHig - borderWidth);
|
||||
prb = new Vector3(pX + gap + barWidth - borderWidth, pY + borderWidth);
|
||||
top = new Vector3(pX + gap + barWidth / 2, pY + currHig - borderWidth);
|
||||
// if (serie.clip)
|
||||
// {
|
||||
// plb = chart.ClampInGrid(grid, plb);
|
||||
// plt = chart.ClampInGrid(grid, plt);
|
||||
// prt = chart.ClampInGrid(grid, prt);
|
||||
// prb = chart.ClampInGrid(grid, prb);
|
||||
// top = chart.ClampInGrid(grid, top);
|
||||
// }
|
||||
serie.context.dataPoints.Add(top);
|
||||
var areaColor = isRise ?
|
||||
itemStyle.GetColor(theme.serie.candlestickColor) :
|
||||
itemStyle.GetColor0(theme.serie.candlestickColor0);
|
||||
var borderColor = isRise ?
|
||||
itemStyle.GetBorderColor(theme.serie.candlestickBorderColor) :
|
||||
itemStyle.GetBorderColor0(theme.serie.candlestickBorderColor0);
|
||||
var itemWidth = Mathf.Abs(prt.x - plb.x);
|
||||
var itemHeight = Mathf.Abs(plt.y - prb.y);
|
||||
var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2);
|
||||
var lowPos = new Vector3(center.x, zeroY + (float) ((lowest - minCut) / valueTotal * grid.context.height));
|
||||
var heighPos = new Vector3(center.x, zeroY + (float) ((heighest - minCut) / valueTotal * grid.context.height));
|
||||
var openCenterPos = new Vector3(center.x, prb.y);
|
||||
var closeCenterPos = new Vector3(center.x, prt.y);
|
||||
if (barWidth > 2f * borderWidth)
|
||||
{
|
||||
if (itemWidth > 0 && itemHeight > 0)
|
||||
{
|
||||
if (itemStyle.IsNeedCorner())
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, areaColor, areaColor, 0,
|
||||
itemStyle.cornerRadius, isYAxis, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
chart.DrawClipPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaColor,
|
||||
serie.clip, grid);
|
||||
}
|
||||
UGL.DrawBorder(vh, center, itemWidth, itemHeight, 2 * borderWidth, borderColor, 0,
|
||||
itemStyle.cornerRadius, isYAxis, 0.5f);
|
||||
}
|
||||
if (isRise)
|
||||
{
|
||||
UGL.DrawLine(vh, openCenterPos, lowPos, borderWidth, borderColor);
|
||||
UGL.DrawLine(vh, closeCenterPos, heighPos, borderWidth, borderColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawLine(vh, closeCenterPos, lowPos, borderWidth, borderColor);
|
||||
UGL.DrawLine(vh, openCenterPos, heighPos, borderWidth, borderColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawLine(vh, openCenterPos, closeCenterPos, Mathf.Max(borderWidth, barWidth / 2), borderColor);
|
||||
}
|
||||
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42727a035319b4eab92ddf0742630115
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 70535a50c140c47cc8cac1820dc03170
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(HeatmapHandler), true)]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[RequireChartComponent(typeof(VisualMap))]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField()]
|
||||
public class Heatmap : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Heatmap>(serieName);
|
||||
serie.itemStyle.show = true;
|
||||
serie.itemStyle.borderWidth = 1;
|
||||
serie.itemStyle.borderColor = Color.clear;
|
||||
|
||||
var emphasis = serie.AddExtraComponent<EmphasisItemStyle>();
|
||||
emphasis.show = true;
|
||||
emphasis.borderWidth = 1;
|
||||
emphasis.borderColor = Color.black;
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a9984972d3c74a01945c4064739a826
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,236 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class HeatmapHandler : SerieHandler<Heatmap>
|
||||
{
|
||||
private GridCoord m_SerieGrid;
|
||||
|
||||
public override int defaultDimension { get { return 2; } }
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
DrawHeatmapSerie(vh, serie);
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(category))
|
||||
{
|
||||
var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex);
|
||||
if (xAxis != null)
|
||||
category = xAxis.GetData((int) serieData.GetData(0));
|
||||
}
|
||||
|
||||
title = serie.serieName;
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.dimension = defaultDimension;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.serieData = serieData;
|
||||
param.color = serieData.context.color;
|
||||
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(category);
|
||||
param.columns.Add(ChartCached.NumberToStr(serieData.GetData(defaultDimension), param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter;
|
||||
var needInteract = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
}
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
serieData.context.highlight = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (!needInteract && serieData.context.rect.Contains(chart.pointerPos))
|
||||
{
|
||||
serie.context.pointerItemDataIndex = serieData.index;
|
||||
serie.context.pointerEnter = true;
|
||||
serieData.context.highlight = true;
|
||||
needInteract = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie)
|
||||
{
|
||||
if (serie.animation.HasFadeOut()) return;
|
||||
XAxis xAxis;
|
||||
YAxis yAxis;
|
||||
if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) return;
|
||||
if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) return;
|
||||
m_SerieGrid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
xAxis.boundaryGap = true;
|
||||
yAxis.boundaryGap = true;
|
||||
var visualMap = chart.GetVisualMapOfSerie(serie);
|
||||
var emphasisItemStyle = serie.emphasisItemStyle;
|
||||
var xCount = xAxis.data.Count;
|
||||
var yCount = yAxis.data.Count;
|
||||
var xWidth = m_SerieGrid.context.width / xCount;
|
||||
var yWidth = m_SerieGrid.context.height / yCount;
|
||||
|
||||
var zeroX = m_SerieGrid.context.x;
|
||||
var zeroY = m_SerieGrid.context.y;
|
||||
var rangeMin = visualMap.rangeMin;
|
||||
var rangeMax = visualMap.rangeMax;
|
||||
var color = chart.theme.GetColor(serie.index);
|
||||
var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0;
|
||||
var rectWid = xWidth - 2 * borderWidth;
|
||||
var rectHig = yWidth - 2 * borderWidth;
|
||||
|
||||
var borderColor = serie.itemStyle.opacity > 0 ?
|
||||
serie.itemStyle.borderColor :
|
||||
ChartConst.clearColor32;
|
||||
borderColor.a = (byte) (borderColor.a * serie.itemStyle.opacity);
|
||||
|
||||
var borderToColor = serie.itemStyle.opacity > 0 ?
|
||||
serie.itemStyle.borderToColor :
|
||||
ChartConst.clearColor32;
|
||||
borderToColor.a = (byte) (borderToColor.a * serie.itemStyle.opacity);
|
||||
|
||||
serie.context.dataPoints.Clear();
|
||||
serie.animation.InitProgress(0, xCount);
|
||||
var animationIndex = serie.animation.GetCurrIndex();
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var dataChanging = false;
|
||||
serie.containerIndex = m_SerieGrid.index;
|
||||
serie.containterInstanceId = m_SerieGrid.instanceId;
|
||||
for (int n = 0; n < serie.dataCount; n++)
|
||||
{
|
||||
var serieData = serie.data[n];
|
||||
serieData.index = n;
|
||||
var i = (int) serieData.GetData(0);
|
||||
var j = (int) serieData.GetData(1);
|
||||
var dimension = VisualMapHelper.GetDimension(visualMap, serieData.data.Count);
|
||||
if (serie.IsIgnoreValue(serieData, dimension))
|
||||
{
|
||||
serie.context.dataPoints.Add(Vector3.zero);
|
||||
continue;
|
||||
}
|
||||
var value = serieData.GetCurrData(dimension, dataChangeDuration, yAxis.inverse,
|
||||
yAxis.context.minValue, yAxis.context.maxValue);
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
var pos = new Vector3(zeroX + (i + (xAxis.boundaryGap ? 0.5f : 0)) * xWidth,
|
||||
zeroY + (j + (yAxis.boundaryGap ? 0.5f : 0)) * yWidth);
|
||||
serie.context.dataPoints.Add(pos);
|
||||
serieData.context.position = pos;
|
||||
|
||||
serieData.context.canShowLabel = false;
|
||||
serieData.context.rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig);
|
||||
if (value == 0) continue;
|
||||
if ((value < rangeMin && rangeMin != visualMap.min) ||
|
||||
(value > rangeMax && rangeMax != visualMap.max))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!visualMap.IsInSelectedValue(value)) continue;
|
||||
if (animationIndex >= 0 && i > animationIndex) continue;
|
||||
color = visualMap.GetColor(value);
|
||||
if (serieData.context.highlight)
|
||||
color = ChartHelper.GetHighlightColor(color);
|
||||
|
||||
serieData.context.canShowLabel = true;
|
||||
serieData.context.color = color;
|
||||
|
||||
var highlight = (serieData.context.highlight) ||
|
||||
visualMap.context.pointerIndex > 0;
|
||||
|
||||
//UGL.DrawRectangle(vh, pos, rectWid / 2, rectHig / 2, color);
|
||||
UGL.DrawRectangle(vh, serieData.context.rect, color);
|
||||
|
||||
if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor))
|
||||
{
|
||||
UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor);
|
||||
}
|
||||
if (visualMap.hoverLink && highlight && emphasisItemStyle != null &&
|
||||
emphasisItemStyle.borderWidth > 0)
|
||||
{
|
||||
var emphasisBorderWidth = emphasisItemStyle.borderWidth;
|
||||
var emphasisBorderColor = emphasisItemStyle.opacity > 0 ?
|
||||
emphasisItemStyle.borderColor : ChartConst.clearColor32;
|
||||
var emphasisBorderToColor = emphasisItemStyle.opacity > 0 ?
|
||||
emphasisItemStyle.borderToColor : ChartConst.clearColor32;
|
||||
UGL.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor,
|
||||
emphasisBorderToColor);
|
||||
}
|
||||
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(xCount);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3a5cd70274da44d50b48fc04d8b52e21
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61f1a04d9920849e7861bebdfd070384
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[Serializable]
|
||||
[SerieHandler(typeof(LineHandler), true)]
|
||||
[SerieConvert(typeof(Bar), typeof(Pie))]
|
||||
[CoordOptions(typeof(GridCoord), typeof(PolarCoord))]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[SerieExtraComponent(
|
||||
typeof(LabelStyle),
|
||||
typeof(EndLabelStyle),
|
||||
typeof(LineArrow),
|
||||
typeof(AreaStyle),
|
||||
typeof(EmphasisItemStyle),
|
||||
typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(
|
||||
typeof(ItemStyle),
|
||||
typeof(LabelStyle),
|
||||
typeof(SerieSymbol),
|
||||
typeof(EmphasisItemStyle),
|
||||
typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField("m_Ignore")]
|
||||
public class Line : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Line>(serieName);
|
||||
serie.symbol.show = true;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
chart.AddData(serie.index, UnityEngine.Random.Range(10, 90));
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static Line CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = serie.Clone<Line>();
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 883eff3dc77e0439a80d257577790cbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,436 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// For grid coord
|
||||
/// </summary>
|
||||
internal sealed partial class LineHandler : SerieHandler<Line>
|
||||
{
|
||||
List<List<SerieData>> m_StackSerieData = new List<List<SerieData>>();
|
||||
private GridCoord m_SerieGrid;
|
||||
|
||||
public override Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label)
|
||||
{
|
||||
var invert = label.autoOffset &&
|
||||
SerieHelper.IsDownPoint(serie, serieData.index) &&
|
||||
(serie.areaStyle == null || !serie.areaStyle.show);
|
||||
if (invert)
|
||||
{
|
||||
var offset = label.GetOffset(serie.context.insideRadius);
|
||||
return new Vector3(offset.x, -offset.y, offset.z);
|
||||
}
|
||||
else
|
||||
{
|
||||
return label.GetOffset(serie.context.insideRadius);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSerieGridContext()
|
||||
{
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
serie.highlight = false;
|
||||
serie.ResetInteract();
|
||||
foreach (var serieData in serie.data)
|
||||
serieData.context.highlight = false;
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
var themeSymbolSize = chart.theme.serie.lineSymbolSize;
|
||||
var themeSymbolSelectedSize = chart.theme.serie.lineSymbolSelectedSize;
|
||||
var needInteract = false;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
}
|
||||
else if (serie.context.isTriggerByAxis)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
|
||||
if (i == serie.context.pointerItemDataIndex)
|
||||
{
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
serieData.index = i;
|
||||
var dist = Vector3.Distance(chart.pointerPos, serieData.context.position);
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
if (dist <= symbolSelectedSize)
|
||||
{
|
||||
serie.context.pointerItemDataIndex = serieData.index;
|
||||
serie.context.pointerEnter = true;
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true);
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawLinePoint(VertexHelper vh, Serie serie)
|
||||
{
|
||||
if (!serie.show || serie.IsPerformanceMode())
|
||||
return;
|
||||
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var count = serie.context.dataPoints.Count;
|
||||
var clip = SeriesHelper.IsAnyClipSerie(chart.series);
|
||||
var theme = chart.theme;
|
||||
var interacting = false;
|
||||
var lineArrow = serie.lineArrow;
|
||||
var visualMap = chart.GetVisualMapOfSerie(serie);
|
||||
var isVisualMapGradient = VisualMapHelper.IsNeedLineGradient(visualMap);
|
||||
var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components);
|
||||
|
||||
Axis axis;
|
||||
Axis relativedAxis;
|
||||
|
||||
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);
|
||||
}
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var serieData = serie.GetSerieData(i);
|
||||
if (serieData == null)
|
||||
continue;
|
||||
if (serieData.context.isClip)
|
||||
continue;
|
||||
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
|
||||
if (!symbol.show || !symbol.ShowSymbol(i, count))
|
||||
continue;
|
||||
|
||||
var pos = serie.context.dataPoints[i];
|
||||
if (lineArrow != null && lineArrow.show)
|
||||
{
|
||||
if (lineArrow.position == LineArrow.Position.Start && i == 0)
|
||||
continue;
|
||||
if (lineArrow.position == LineArrow.Position.End && i == count - 1)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ChartHelper.IsIngore(pos))
|
||||
continue;
|
||||
|
||||
var highlight = serie.data[i].context.highlight || serie.highlight;
|
||||
var symbolSize = highlight ?
|
||||
theme.serie.lineSymbolSelectedSize :
|
||||
theme.serie.lineSymbolSize;
|
||||
if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting))
|
||||
{
|
||||
symbolSize = highlight ?
|
||||
symbol.GetSelectedSize(serieData.data, symbolSize) :
|
||||
symbol.GetSize(serieData.data, symbolSize);
|
||||
serieData.interact.SetValue(ref interacting, symbolSize);
|
||||
symbolSize = serie.animation.GetSysmbolSize(symbolSize);
|
||||
}
|
||||
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);
|
||||
|
||||
if (isVisualMapGradient)
|
||||
{
|
||||
symbolColor = VisualMapHelper.GetLineGradientColor(visualMap, pos, m_SerieGrid, axis, relativedAxis, symbolColor);
|
||||
symbolToColor = symbolColor;
|
||||
}
|
||||
var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight);
|
||||
var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, theme, highlight);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
|
||||
chart.DrawClipSymbol(vh, symbol.type, symbolSize, symbolBorder, pos,
|
||||
symbolColor, symbolToColor, symbolEmptyColor, borderColor, symbol.gap, clip, cornerRadius, m_SerieGrid,
|
||||
i > 0 ? serie.context.dataPoints[i - 1] : m_SerieGrid.context.position);
|
||||
}
|
||||
if (interacting)
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawLineArrow(VertexHelper vh, Serie serie)
|
||||
{
|
||||
if (!serie.show || serie.lineArrow == null || !serie.lineArrow.show)
|
||||
return;
|
||||
|
||||
if (serie.context.dataPoints.Count < 2)
|
||||
return;
|
||||
|
||||
var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index, false);
|
||||
var startPos = Vector3.zero;
|
||||
var arrowPos = Vector3.zero;
|
||||
var lineArrow = serie.lineArrow.arrow;
|
||||
var dataPoints = serie.context.drawPoints;
|
||||
switch (serie.lineArrow.position)
|
||||
{
|
||||
case LineArrow.Position.End:
|
||||
if (dataPoints.Count < 3)
|
||||
{
|
||||
startPos = dataPoints[dataPoints.Count - 2].position;
|
||||
arrowPos = dataPoints[dataPoints.Count - 1].position;
|
||||
}
|
||||
else
|
||||
{
|
||||
startPos = dataPoints[dataPoints.Count - 3].position;
|
||||
arrowPos = dataPoints[dataPoints.Count - 2].position;
|
||||
}
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height,
|
||||
lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor));
|
||||
|
||||
break;
|
||||
|
||||
case LineArrow.Position.Start:
|
||||
startPos = dataPoints[1].position;
|
||||
arrowPos = dataPoints[0].position;
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, lineArrow.width, lineArrow.height,
|
||||
lineArrow.offset, lineArrow.dent, lineArrow.GetColor(lineColor));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawLineSerie(VertexHelper vh, Line serie)
|
||||
{
|
||||
if (!serie.show)
|
||||
return;
|
||||
if (serie.animation.HasFadeOut())
|
||||
return;
|
||||
|
||||
var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components);
|
||||
|
||||
Axis axis;
|
||||
Axis relativedAxis;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (axis == null)
|
||||
return;
|
||||
if (relativedAxis == null)
|
||||
return;
|
||||
|
||||
m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
if (m_EndLabel != null && !m_SerieGrid.context.endLabelList.Contains(m_EndLabel))
|
||||
{
|
||||
m_SerieGrid.context.endLabelList.Add(m_EndLabel);
|
||||
}
|
||||
|
||||
var visualMap = chart.GetVisualMapOfSerie(serie);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
|
||||
if (showData.Count <= 0)
|
||||
return;
|
||||
|
||||
var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width;
|
||||
var scaleWid = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom);
|
||||
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > showData.Count ? showData.Count : serie.maxShow) :
|
||||
showData.Count;
|
||||
int rate = LineHelper.GetDataAverageRate(serie, m_SerieGrid, maxCount, false);
|
||||
var totalAverage = serie.sampleAverage > 0 ?
|
||||
serie.sampleAverage :
|
||||
DataHelper.DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate);
|
||||
var dataChanging = false;
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
|
||||
var interacting = false;
|
||||
var lineWidth = LineHelper.GetLineWidth(ref interacting, serie, chart.theme.serie.lineWidth);
|
||||
|
||||
axis.context.scaleWidth = scaleWid;
|
||||
serie.containerIndex = m_SerieGrid.index;
|
||||
serie.containterInstanceId = m_SerieGrid.instanceId;
|
||||
|
||||
Serie lastSerie = null;
|
||||
var isStack = SeriesHelper.IsStack<Line>(chart.series, serie.stack);
|
||||
if (isStack)
|
||||
{
|
||||
lastSerie = SeriesHelper.GetLastStackSerie(chart.series, serie);
|
||||
SeriesHelper.UpdateStackDataList(chart.series, serie, dataZoom, m_StackSerieData);
|
||||
}
|
||||
var lp = Vector3.zero;
|
||||
for (int i = serie.minShow; i < maxCount; i += rate)
|
||||
{
|
||||
var serieData = showData[i];
|
||||
var isIgnore = serie.IsIgnoreValue(serieData);
|
||||
if (isIgnore)
|
||||
{
|
||||
serieData.context.stackHeight = 0;
|
||||
serieData.context.position = Vector3.zero;
|
||||
if (serie.ignoreLineBreak && serie.context.dataIgnores.Count > 0)
|
||||
{
|
||||
serie.context.dataIgnores[serie.context.dataIgnores.Count - 1] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var np = Vector3.zero;
|
||||
var xValue = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse);
|
||||
var relativedValue = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow,
|
||||
maxCount, totalAverage, i, dataChangeDuration, ref dataChanging, relativedAxis);
|
||||
|
||||
serieData.context.stackHeight = GetDataPoint(isY, axis, relativedAxis, m_SerieGrid, xValue, relativedValue,
|
||||
i, scaleWid, isStack, ref np);
|
||||
serieData.context.isClip = false;
|
||||
if (serie.clip && !m_SerieGrid.Contains(np))
|
||||
{
|
||||
if (m_SerieGrid.BoundaryPoint(lp, np, ref np))
|
||||
{
|
||||
serieData.context.isClip = true;
|
||||
}
|
||||
}
|
||||
serie.context.dataIgnores.Add(false);
|
||||
serieData.context.position = np;
|
||||
serie.context.dataPoints.Add(np);
|
||||
lp = np;
|
||||
}
|
||||
}
|
||||
|
||||
if (dataChanging || interacting)
|
||||
chart.RefreshPainter(serie);
|
||||
|
||||
if (serie.context.dataPoints.Count <= 0)
|
||||
return;
|
||||
|
||||
serie.animation.InitProgress(serie.context.dataPoints, isY);
|
||||
|
||||
VisualMapHelper.AutoSetLineMinMax(visualMap, serie, isY, axis, relativedAxis);
|
||||
LineHelper.UpdateSerieDrawPoints(serie, chart.settings, chart.theme, visualMap, lineWidth, isY);
|
||||
LineHelper.DrawSerieLineArea(vh, serie, lastSerie, chart.theme, visualMap, isY, axis, relativedAxis, m_SerieGrid);
|
||||
LineHelper.DrawSerieLine(vh, chart.theme, serie, visualMap, m_SerieGrid, axis, relativedAxis, lineWidth);
|
||||
|
||||
serie.context.vertCount = vh.currentVertCount;
|
||||
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize));
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord grid, double xValue,
|
||||
double yValue, int i, float scaleWid, bool isStack, ref Vector3 np)
|
||||
{
|
||||
float xPos, yPos;
|
||||
var gridXY = isY ? grid.context.x : grid.context.y;
|
||||
var valueHig = 0f;
|
||||
if (isY)
|
||||
{
|
||||
valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
xPos = gridXY + valueHig;
|
||||
yPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue);
|
||||
|
||||
if (isStack)
|
||||
{
|
||||
for (int n = 0; n < m_StackSerieData.Count - 1; n++)
|
||||
xPos += m_StackSerieData[n][i].context.stackHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
yPos = gridXY + valueHig;
|
||||
xPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue);
|
||||
|
||||
if (isStack)
|
||||
{
|
||||
for (int n = 0; n < m_StackSerieData.Count - 1; n++)
|
||||
yPos += m_StackSerieData[n][i].context.stackHeight;
|
||||
}
|
||||
}
|
||||
np = new Vector3(xPos, yPos);
|
||||
return valueHig;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34168c2605d4546c291adeb8e857fd62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,262 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// For polar coord
|
||||
/// </summary>
|
||||
internal sealed partial class LineHandler
|
||||
{
|
||||
private PolarCoord m_SeriePolar;
|
||||
|
||||
private void UpdateSeriePolarContext()
|
||||
{
|
||||
if (m_SeriePolar == null)
|
||||
return;
|
||||
|
||||
var needCheck = (chart.isPointerInChart && m_SeriePolar.IsPointerEnter()) || m_LegendEnter;
|
||||
var lineWidth = 0f;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
var needAnimation1 = false;
|
||||
lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
serie.interact.SetValue(ref needAnimation1, lineWidth, false);
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize);
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needAnimation1, symbolSize);
|
||||
}
|
||||
if (needAnimation1)
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
var themeSymbolSize = chart.theme.serie.lineSymbolSize;
|
||||
var themeSymbolSelectedSize = chart.theme.serie.lineSymbolSelectedSize;
|
||||
lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
|
||||
var needInteract = false;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
var dir = chart.pointerPos - new Vector2(m_SeriePolar.context.center.x, m_SeriePolar.context.center.y);
|
||||
var pointerAngle = ChartHelper.GetAngle360(Vector2.up, dir);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var angle0 = serieData.context.angle;
|
||||
var angle1 = i >= serie.dataCount - 1 ? angle0 : serie.data[i + 1].context.angle;
|
||||
|
||||
if (pointerAngle >= angle0 && pointerAngle < angle1)
|
||||
{
|
||||
serie.context.pointerItemDataIndex = i;
|
||||
serie.context.pointerEnter = true;
|
||||
serieData.context.highlight = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPolarLine(VertexHelper vh, Serie serie)
|
||||
{
|
||||
var datas = serie.data;
|
||||
if (datas.Count <= 0)
|
||||
return;
|
||||
|
||||
m_SeriePolar = chart.GetChartComponent<PolarCoord>(serie.polarIndex);
|
||||
if (m_SeriePolar == null)
|
||||
return;
|
||||
|
||||
var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_SeriePolar.index);
|
||||
var m_RadiusAxis = ComponentHelper.GetRadiusAxis(chart.components, m_SeriePolar.index);
|
||||
if (m_AngleAxis == null || m_RadiusAxis == null)
|
||||
return;
|
||||
|
||||
var startAngle = m_AngleAxis.startAngle;
|
||||
var radius = m_SeriePolar.context.radius;
|
||||
|
||||
var min = m_RadiusAxis.context.minValue;
|
||||
var max = m_RadiusAxis.context.maxValue;
|
||||
var firstSerieData = datas[0];
|
||||
var lp = GetPolarPos(m_SeriePolar, m_AngleAxis, firstSerieData, min, max, radius);
|
||||
var cp = Vector3.zero;
|
||||
var lineColor = SerieHelper.GetLineColor(serie, null, chart.theme, serie.index, serie.highlight);
|
||||
var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
var currDetailProgress = 0f;
|
||||
var totalDetailProgress = datas.Count;
|
||||
|
||||
serie.animation.InitProgress(currDetailProgress, totalDetailProgress);
|
||||
|
||||
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;
|
||||
bool bitp = true, bibp = true;
|
||||
for (int i = 1; i < datas.Count; i++)
|
||||
{
|
||||
if (serie.animation.CheckDetailBreak(i))
|
||||
break;
|
||||
|
||||
var serieData = datas[i];
|
||||
|
||||
cp = GetPolarPos(m_SeriePolar, m_AngleAxis, datas[i], min, max, radius);
|
||||
var np = i == datas.Count - 1 ? cp :
|
||||
GetPolarPos(m_SeriePolar, m_AngleAxis, datas[i + 1], min, max, radius);
|
||||
|
||||
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, i);
|
||||
|
||||
if (i == 1)
|
||||
{
|
||||
UGL.AddVertToVertexHelper(vh, ltp, lbp, lineColor, false);
|
||||
}
|
||||
|
||||
if (bitp == bibp)
|
||||
{
|
||||
if (bitp)
|
||||
UGL.AddVertToVertexHelper(vh, itp, ibp, lineColor, true);
|
||||
else
|
||||
{
|
||||
UGL.AddVertToVertexHelper(vh, ltp, clp, lineColor, true);
|
||||
UGL.AddVertToVertexHelper(vh, ltp, crp, lineColor, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bitp)
|
||||
{
|
||||
UGL.AddVertToVertexHelper(vh, itp, clp, lineColor, true);
|
||||
UGL.AddVertToVertexHelper(vh, itp, crp, lineColor, true);
|
||||
}
|
||||
else if (bibp)
|
||||
{
|
||||
UGL.AddVertToVertexHelper(vh, clp, ibp, lineColor, true);
|
||||
UGL.AddVertToVertexHelper(vh, crp, ibp, lineColor, true);
|
||||
}
|
||||
}
|
||||
lp = cp;
|
||||
}
|
||||
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(totalDetailProgress);
|
||||
serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize));
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPolarLineSymbol(VertexHelper vh)
|
||||
{
|
||||
for (int n = 0; n < chart.series.Count; n++)
|
||||
{
|
||||
var serie = chart.series[n];
|
||||
|
||||
if (!serie.show)
|
||||
continue;
|
||||
if (!(serie is Line))
|
||||
continue;
|
||||
|
||||
var count = serie.dataCount;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var serieData = serie.GetSerieData(i);
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
if (ChartHelper.IsIngore(serieData.context.position))
|
||||
continue;
|
||||
|
||||
bool highlight = serieData.context.highlight || serie.highlight;
|
||||
if ((!symbol.show || !symbol.ShowSymbol(i, count) || serie.IsPerformanceMode()) &&
|
||||
!serieData.context.highlight)
|
||||
continue;
|
||||
|
||||
var symbolSize = highlight ?
|
||||
symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSize) :
|
||||
symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize);
|
||||
|
||||
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 borderColor = SerieHelper.GetSymbolBorderColor(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.context.position,
|
||||
symbolColor, symbolToColor, symbolEmptyColor, borderColor, symbol.gap, cornerRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetPolarPos(PolarCoord m_Polar, AngleAxis m_AngleAxis, SerieData serieData, double min,
|
||||
double max, float polarRadius)
|
||||
{
|
||||
var angle = 0f;
|
||||
|
||||
if (!m_AngleAxis.clockwise)
|
||||
{
|
||||
angle = m_AngleAxis.GetValueAngle((float) serieData.GetData(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = m_AngleAxis.GetValueAngle((float) serieData.GetData(1));
|
||||
}
|
||||
|
||||
var value = serieData.GetData(0);
|
||||
var radius = (float) ((value - min) / (max - min) * polarRadius);
|
||||
|
||||
angle = (angle + 360) % 360;
|
||||
serieData.context.angle = angle;
|
||||
serieData.context.position = ChartHelper.GetPos(m_Polar.context.center, radius, angle, true);
|
||||
|
||||
return serieData.context.position;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8655c97b8c7e44e44852f8b81a7372b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// For grid coord
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed partial class LineHandler : SerieHandler<Line>
|
||||
{
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
if (serie.IsUseCoord<GridCoord>())
|
||||
UpdateSerieGridContext();
|
||||
else if (serie.IsUseCoord<PolarCoord>())
|
||||
UpdateSeriePolarContext();
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category,
|
||||
marker, itemFormatter, numericFormatter);
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
if (serie.IsUseCoord<PolarCoord>())
|
||||
{
|
||||
DrawPolarLine(vh, serie);
|
||||
DrawPolarLineSymbol(vh);
|
||||
}
|
||||
else if (serie.IsUseCoord<GridCoord>())
|
||||
{
|
||||
DrawLineSerie(vh, serie);
|
||||
|
||||
if (!SeriesHelper.IsStack(chart.series))
|
||||
{
|
||||
DrawLinePoint(vh, serie);
|
||||
DrawLineArrow(vh, serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void DrawTop(VertexHelper vh)
|
||||
{
|
||||
if (serie.IsUseCoord<GridCoord>())
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
{
|
||||
DrawLinePoint(vh, serie);
|
||||
DrawLineArrow(vh, serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void RefreshEndLabelInternal()
|
||||
{
|
||||
base.RefreshEndLabelInternal();
|
||||
if (m_SerieGrid == null) return;
|
||||
if (!serie.animation.IsFinish()) return;
|
||||
var endLabelList = m_SerieGrid.context.endLabelList;
|
||||
if (endLabelList.Count <= 1) return;
|
||||
|
||||
endLabelList.Sort(delegate(ChartLabel a, ChartLabel b)
|
||||
{
|
||||
if (a == null || b == null) return 1;
|
||||
return b.transform.position.y.CompareTo(a.transform.position.y);
|
||||
});
|
||||
var lastY = float.NaN;
|
||||
for (int i = 0; i < endLabelList.Count; i++)
|
||||
{
|
||||
var label = endLabelList[i];
|
||||
if (label == null) continue;
|
||||
if (!label.isAnimationEnd) continue;
|
||||
var labelPosition = label.transform.localPosition;
|
||||
if (float.IsNaN(lastY))
|
||||
{
|
||||
lastY = labelPosition.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
var labelHeight = label.GetTextHeight();
|
||||
if (labelPosition.y + labelHeight > lastY)
|
||||
{
|
||||
label.SetPosition(new Vector3(labelPosition.x, lastY - labelHeight, labelPosition.z));
|
||||
}
|
||||
lastY = label.transform.localPosition.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6e3a076ca3ee241c3b8b1088d4519dfa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,551 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
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;
|
||||
var rate = 0;
|
||||
var width = isYAxis ? grid.context.height : grid.context.width;
|
||||
if (sampleDist > 0)
|
||||
rate = (int) ((maxCount - serie.minShow) / (width / sampleDist));
|
||||
if (rate < 1)
|
||||
rate = 1;
|
||||
return rate;
|
||||
}
|
||||
|
||||
public static void DrawSerieLineArea(VertexHelper vh, Serie serie, Serie lastStackSerie,
|
||||
ThemeStyle theme, VisualMap visualMap, bool isY, Axis axis, Axis relativedAxis, GridCoord grid)
|
||||
{
|
||||
if (serie.areaStyle == null || !serie.areaStyle.show)
|
||||
return;
|
||||
|
||||
var srcAreaColor = SerieHelper.GetAreaColor(serie, null, theme, serie.context.colorIndex, false);
|
||||
var srcAreaToColor = SerieHelper.GetAreaToColor(serie, null, theme, serie.context.colorIndex, false);
|
||||
var gridXY = (isY ? grid.context.x : grid.context.y);
|
||||
if (lastStackSerie == null)
|
||||
{
|
||||
DrawSerieLineNormalArea(vh, serie, isY,
|
||||
gridXY + relativedAxis.context.offset,
|
||||
gridXY,
|
||||
gridXY + (isY ? grid.context.width : grid.context.height),
|
||||
srcAreaColor,
|
||||
srcAreaToColor,
|
||||
visualMap,
|
||||
axis,
|
||||
relativedAxis,
|
||||
grid);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSerieLineStackArea(vh, serie, lastStackSerie, isY,
|
||||
gridXY + relativedAxis.context.offset,
|
||||
gridXY,
|
||||
gridXY + (isY ? grid.context.width : grid.context.height),
|
||||
srcAreaColor,
|
||||
srcAreaToColor,
|
||||
visualMap);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawSerieLineNormalArea(VertexHelper vh, Serie serie, bool isY,
|
||||
float zero, float min, float max, Color32 areaColor, Color32 areaToColor,
|
||||
VisualMap visualMap, Axis axis, Axis relativedAxis, GridCoord grid)
|
||||
{
|
||||
var points = serie.context.drawPoints;
|
||||
var count = points.Count;
|
||||
if (count < 2)
|
||||
return;
|
||||
|
||||
var isBreak = false;
|
||||
var lp = Vector3.zero;
|
||||
var isVisualMapGradient = VisualMapHelper.IsNeedAreaGradient(visualMap);
|
||||
var areaLerp = !ChartHelper.IsValueEqualsColor(areaColor, areaToColor);
|
||||
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;
|
||||
var color = areaColor;
|
||||
var toColor = areaToColor;
|
||||
var lerp = areaLerp;
|
||||
|
||||
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 (isVisualMapGradient)
|
||||
{
|
||||
color = VisualMapHelper.GetLineGradientColor(visualMap, zp, grid, axis, relativedAxis, areaColor);
|
||||
toColor = VisualMapHelper.GetLineGradientColor(visualMap, tp, grid, axis, relativedAxis, areaToColor);
|
||||
lerp = true;
|
||||
}
|
||||
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, VisualMap visualMap)
|
||||
{
|
||||
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, float lineWidth)
|
||||
{
|
||||
if (!serie.lineStyle.show || serie.lineStyle.type == LineStyle.Type.None)
|
||||
return;
|
||||
|
||||
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.IsNeedLineGradient(visualMap);
|
||||
var isLineStyleGradient = serie.lineStyle.IsNeedGradient();
|
||||
|
||||
//var highlight = serie.highlight || serie.context.pointerEnter;
|
||||
var lineColor = SerieHelper.GetLineColor(serie, null, theme, serie.context.colorIndex, false);
|
||||
|
||||
var lastDataIsIgnore = datas[0].isIgnoreBreak;
|
||||
var smooth = serie.lineType == LineType.Smooth;
|
||||
for (int i = 1; i < dataCount; i++)
|
||||
{
|
||||
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 ip = Vector3.zero;
|
||||
var progress = serie.animation.GetCurrDetail();
|
||||
if (AnimationStyleHelper.GetAnimationPosition(serie.animation, isY, lp, cp, progress, ref ip))
|
||||
cp = np = ip;
|
||||
}
|
||||
serie.context.lineEndPostion = cp;
|
||||
serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp);
|
||||
lastDataIsIgnore = isIgnore;
|
||||
var handled = false;
|
||||
if (!smooth)
|
||||
{
|
||||
switch (serie.lineStyle.type)
|
||||
{
|
||||
case LineStyle.Type.Dashed:
|
||||
UGL.DrawDashLine(vh, lp, cp, lineWidth, lineColor, lineColor, 0, 0);
|
||||
handled = true;
|
||||
break;
|
||||
case LineStyle.Type.Dotted:
|
||||
UGL.DrawDotLine(vh, lp, cp, lineWidth, lineColor, lineColor, 0, 0);
|
||||
handled = true;
|
||||
break;
|
||||
case LineStyle.Type.DashDot:
|
||||
UGL.DrawDashDotLine(vh, lp, cp, lineWidth, lineColor, 0, 0, 0);
|
||||
handled = true;
|
||||
break;
|
||||
case LineStyle.Type.DashDotDot:
|
||||
UGL.DrawDashDotDotLine(vh, lp, cp, lineWidth, lineColor, 0, 0, 0);
|
||||
handled = true;
|
||||
break;
|
||||
case LineStyle.Type.None:
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (handled)
|
||||
{
|
||||
if (isBreak)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
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, i);
|
||||
if (i == 1)
|
||||
{
|
||||
AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient,
|
||||
visualMap, serie.lineStyle, grid, axis, relativedAxis, false, lastDataIsIgnore, isIgnore);
|
||||
if (dataCount == 2 || isBreak)
|
||||
{
|
||||
AddLineVertToVertexHelper(vh, clp, crp, lineColor, isVisualMapGradient, isLineStyleGradient,
|
||||
visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore);
|
||||
serie.context.lineEndPostion = cp;
|
||||
serie.context.lineEndValue = AxisHelper.GetAxisPositionValue(grid, relativedAxis, cp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bitp == bibp)
|
||||
{
|
||||
if (bitp)
|
||||
AddLineVertToVertexHelper(vh, itp, ibp, lineColor, isVisualMapGradient, isLineStyleGradient,
|
||||
visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore);
|
||||
else
|
||||
{
|
||||
AddLineVertToVertexHelper(vh, ltp, clp, lineColor, isVisualMapGradient, isLineStyleGradient,
|
||||
visualMap, serie.lineStyle, grid, axis, relativedAxis, true, lastDataIsIgnore, isIgnore);
|
||||
AddLineVertToVertexHelper(vh, ltp, crp, 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);
|
||||
}
|
||||
}
|
||||
|
||||
if (isBreak)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetLineWidth(ref bool interacting, Serie serie, float defaultWidth)
|
||||
{
|
||||
var lineWidth = 0f;
|
||||
if (!serie.interact.TryGetValue(ref lineWidth, ref interacting))
|
||||
{
|
||||
lineWidth = serie.lineStyle.GetWidth(defaultWidth);
|
||||
serie.interact.SetValue(ref interacting, lineWidth);
|
||||
}
|
||||
return lineWidth;
|
||||
}
|
||||
|
||||
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, VisualMap visualMap,
|
||||
float lineWidth, 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, lineWidth);
|
||||
break;
|
||||
default:
|
||||
UpdateNormalLineDrawPoints(serie, setting, visualMap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateNormalLineDrawPoints(Serie serie, Settings setting, VisualMap visualMap)
|
||||
{
|
||||
var isVisualMapGradient = VisualMapHelper.IsNeedGradient(visualMap);
|
||||
if (isVisualMapGradient)
|
||||
{
|
||||
var dataPoints = serie.context.dataPoints;
|
||||
if (dataPoints.Count > 1)
|
||||
{
|
||||
var sp = dataPoints[0];
|
||||
for (int i = 1; i < dataPoints.Count; i++)
|
||||
{
|
||||
var ep = dataPoints[i];
|
||||
var ignore = serie.context.dataIgnores[i];
|
||||
var dir = (ep - sp).normalized;
|
||||
var dist = Vector3.Distance(sp, ep);
|
||||
var segment = (int) (dist / setting.lineSegmentDistance);
|
||||
serie.context.drawPoints.Add(new PointInfo(sp, ignore));
|
||||
for (int j = 1; j < segment; j++)
|
||||
{
|
||||
var np = sp + dir * dist * j / segment;
|
||||
serie.context.drawPoints.Add(new PointInfo(np, ignore));
|
||||
}
|
||||
sp = ep;
|
||||
if (i == dataPoints.Count - 1)
|
||||
{
|
||||
serie.context.drawPoints.Add(new PointInfo(ep, ignore));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.drawPoints.Add(new PointInfo(dataPoints[0], serie.context.dataIgnores[0]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < serie.context.dataPoints.Count; i++)
|
||||
{
|
||||
serie.context.drawPoints.Add(new PointInfo(serie.context.dataPoints[i], serie.context.dataIgnores[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void UpdateSmoothLineDrawPoints(Serie serie, Settings setting, bool isY)
|
||||
{
|
||||
var points = serie.context.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.context.dataIgnores[i];
|
||||
if (isY)
|
||||
UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness, setting.lineSmoothStyle);
|
||||
else
|
||||
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness, setting.lineSmoothStyle);
|
||||
|
||||
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, float lineWidth)
|
||||
{
|
||||
var points = serie.context.dataPoints;
|
||||
var lp = points[0];
|
||||
serie.context.drawPoints.Clear();
|
||||
serie.context.drawPoints.Add(new PointInfo(lp, serie.context.dataIgnores[0]));
|
||||
for (int i = 1; i < points.Count; i++)
|
||||
{
|
||||
var cp = points[i];
|
||||
var ignore = serie.context.dataIgnores[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7292748fb01ef44709a94d08f4907dd5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[Serializable]
|
||||
[SerieHandler(typeof(SimplifiedLineHandler), true)]
|
||||
[SerieConvert(typeof(SimplifiedBar), typeof(Line))]
|
||||
[CoordOptions(typeof(GridCoord))]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[SerieExtraComponent(typeof(AreaStyle))]
|
||||
[SerieDataExtraComponent()]
|
||||
[SerieDataExtraField()]
|
||||
public class SimplifiedLine : Serie, INeedSerieContainer, ISimplifiedSerie
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<SimplifiedLine>(serieName);
|
||||
serie.symbol.show = false;
|
||||
var lastValue = 0d;
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
if (i < 20)
|
||||
lastValue += UnityEngine.Random.Range(0, 5);
|
||||
else
|
||||
lastValue += UnityEngine.Random.Range(-3, 5);
|
||||
chart.AddData(serie.index, lastValue);
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static SimplifiedLine CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = serie.Clone<SimplifiedLine>();
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5740626e12a84a0ca3a984935f61720
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,280 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// For grid coord
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class SimplifiedLineHandler : SerieHandler<SimplifiedLine>
|
||||
{
|
||||
private GridCoord m_SerieGrid;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
UpdateCoordSerieParams(ref paramList, ref title, dataIndex, showCategory, category,
|
||||
marker, itemFormatter, numericFormatter);
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
DrawLineSerie(vh, serie);
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var needCheck = (chart.isPointerInChart && m_SerieGrid.IsPointerEnter()) || m_LegendEnter;
|
||||
var lineWidth = 0f;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
var needAnimation1 = false;
|
||||
lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
serie.interact.SetValue(ref needAnimation1, lineWidth, false);
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize);
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needAnimation1, symbolSize);
|
||||
}
|
||||
if (needAnimation1)
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
var themeSymbolSize = chart.theme.serie.lineSymbolSize;
|
||||
var themeSymbolSelectedSize = chart.theme.serie.lineSymbolSelectedSize;
|
||||
lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
|
||||
var needInteract = false;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
}
|
||||
else if (serie.context.isTriggerByAxis)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true, chart.theme.serie.selectedRate);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
|
||||
if (i == serie.context.pointerItemDataIndex)
|
||||
{
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var dist = Vector3.Distance(chart.pointerPos, serieData.context.position);
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
|
||||
if (dist <= symbolSelectedSize)
|
||||
{
|
||||
serie.context.pointerItemDataIndex = serieData.index;
|
||||
serie.context.pointerEnter = true;
|
||||
serie.interact.SetValue(ref needInteract, lineWidth, true);
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
if (SeriesHelper.IsStack(chart.series))
|
||||
chart.RefreshTopPainter();
|
||||
else
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawLineSerie(VertexHelper vh, SimplifiedLine serie)
|
||||
{
|
||||
if (!serie.show)
|
||||
return;
|
||||
if (serie.animation.HasFadeOut())
|
||||
return;
|
||||
|
||||
var isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components);
|
||||
|
||||
Axis axis;
|
||||
Axis relativedAxis;
|
||||
|
||||
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);
|
||||
}
|
||||
m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
|
||||
if (axis == null)
|
||||
return;
|
||||
if (relativedAxis == null)
|
||||
return;
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var showData = serie.GetDataList(dataZoom);
|
||||
|
||||
if (showData.Count <= 0)
|
||||
return;
|
||||
|
||||
var axisLength = isY ? m_SerieGrid.context.height : m_SerieGrid.context.width;
|
||||
var scaleWid = AxisHelper.GetDataWidth(axis, axisLength, showData.Count, dataZoom);
|
||||
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > showData.Count ? showData.Count : serie.maxShow) :
|
||||
showData.Count;
|
||||
int rate = LineHelper.GetDataAverageRate(serie, m_SerieGrid, maxCount, false);
|
||||
var totalAverage = serie.sampleAverage > 0 ?
|
||||
serie.sampleAverage :
|
||||
DataHelper.DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate);
|
||||
var dataChanging = false;
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
|
||||
var interacting = false;
|
||||
var lineWidth = LineHelper.GetLineWidth(ref interacting, serie, chart.theme.serie.lineWidth);
|
||||
|
||||
axis.context.scaleWidth = scaleWid;
|
||||
serie.containerIndex = m_SerieGrid.index;
|
||||
serie.containterInstanceId = m_SerieGrid.instanceId;
|
||||
|
||||
for (int i = serie.minShow; i < maxCount; i += rate)
|
||||
{
|
||||
var serieData = showData[i];
|
||||
var isIgnore = serie.IsIgnoreValue(serieData);
|
||||
if (isIgnore)
|
||||
{
|
||||
serieData.context.stackHeight = 0;
|
||||
serieData.context.position = Vector3.zero;
|
||||
if (serie.ignoreLineBreak && serie.context.dataIgnores.Count > 0)
|
||||
{
|
||||
serie.context.dataIgnores[serie.context.dataIgnores.Count - 1] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var np = Vector3.zero;
|
||||
var xValue = axis.IsCategory() ? i : serieData.GetData(0, axis.inverse);
|
||||
var relativedValue = DataHelper.SampleValue(ref showData, serie.sampleType, rate, serie.minShow,
|
||||
maxCount, totalAverage, i, dataChangeDuration, ref dataChanging, relativedAxis);
|
||||
|
||||
serieData.context.stackHeight = GetDataPoint(isY, axis, relativedAxis, m_SerieGrid, xValue, relativedValue,
|
||||
i, scaleWid, false, ref np);
|
||||
|
||||
serieData.context.position = np;
|
||||
|
||||
serie.context.dataPoints.Add(np);
|
||||
serie.context.dataIgnores.Add(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (dataChanging || interacting)
|
||||
chart.RefreshPainter(serie);
|
||||
|
||||
if (serie.context.dataPoints.Count <= 0)
|
||||
return;
|
||||
|
||||
serie.animation.InitProgress(serie.context.dataPoints, isY);
|
||||
|
||||
LineHelper.UpdateSerieDrawPoints(serie, chart.settings, chart.theme, null, lineWidth, isY);
|
||||
LineHelper.DrawSerieLineArea(vh, serie, null, chart.theme, null, isY, axis, relativedAxis, m_SerieGrid);
|
||||
LineHelper.DrawSerieLine(vh, chart.theme, serie, null, m_SerieGrid, axis, relativedAxis, lineWidth);
|
||||
|
||||
serie.context.vertCount = vh.currentVertCount;
|
||||
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private float GetDataPoint(bool isY, Axis axis, Axis relativedAxis, GridCoord grid, double xValue,
|
||||
double yValue, int i, float scaleWid, bool isStack, ref Vector3 np)
|
||||
{
|
||||
float xPos, yPos;
|
||||
var gridXY = isY ? grid.context.x : grid.context.y;
|
||||
|
||||
if (isY)
|
||||
{
|
||||
var valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
xPos = gridXY + valueHig;
|
||||
yPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var valueHig = AxisHelper.GetAxisValueDistance(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
yPos = gridXY + valueHig;
|
||||
xPos = AxisHelper.GetAxisValuePosition(grid, axis, scaleWid, xValue);
|
||||
}
|
||||
np = new Vector3(xPos, yPos);
|
||||
return yPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c4714bd08de34548ac7be3ec6523ee1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2ba7099a74f54617b446aeaf3d95672
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(ParallelHandler), true)]
|
||||
[RequireChartComponent(typeof(ParallelCoord))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField()]
|
||||
public class Parallel : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Parallel>(serieName);
|
||||
serie.lineStyle.width = 0.8f;
|
||||
serie.lineStyle.opacity = 0.6f;
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
var data = new List<double>()
|
||||
{
|
||||
Random.Range(0f, 50f),
|
||||
Random.Range(0f, 100f),
|
||||
Random.Range(0f, 1000f),
|
||||
Random.Range(0, 5),
|
||||
};
|
||||
serie.AddData(data, "data" + i);
|
||||
}
|
||||
chart.RefreshChart();
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 283df79138f274a6ba975ff8f30c6d30
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,150 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class ParallelHandler : SerieHandler<Parallel>
|
||||
{
|
||||
private List<Vector3> m_Points = new List<Vector3>();
|
||||
|
||||
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<ParallelCoord>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 482b461d91f8c4013bf291153d5810e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5dfd0cb375a24f659bf56e113aa6fc8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieConvert(typeof(Line), typeof(Bar))]
|
||||
[SerieHandler(typeof(PieHandler), true)]
|
||||
[DefaultAnimation(AnimationType.Clockwise)]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(LabelLine), typeof(TitleStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle), typeof(EmphasisLabelLine))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(LabelLine), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle), typeof(EmphasisLabelLine))]
|
||||
[SerieDataExtraField("m_Ignore", "m_Selected", "m_Radius")]
|
||||
public class Pie : Serie
|
||||
{
|
||||
public override bool useDataNameForColor { get { return true; } }
|
||||
public override bool titleJustForSerie { get { return true; } }
|
||||
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Pie>(serieName);
|
||||
chart.AddData(serie.index, 70, "pie1");
|
||||
chart.AddData(serie.index, 20, "pie2");
|
||||
chart.AddData(serie.index, 10, "pie3");
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static Pie CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = SerieHelper.CloneSerie<Pie>(serie);
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53f0d225949a3450e9e90687759f1714
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,564 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class PieHandler : SerieHandler<Pie>
|
||||
{
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
UpdateRuntimeData(serie);
|
||||
DrawPieLabelLine(vh, serie);
|
||||
DrawPie(vh, serie);
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
UpdateItemSerieParams(ref paramList, ref title, dataIndex, category,
|
||||
marker, itemFormatter, numericFormatter);
|
||||
}
|
||||
|
||||
public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
|
||||
{
|
||||
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
|
||||
return SerieLabelHelper.GetRealLabelPosition(serie, serieData, label, labelLine);
|
||||
}
|
||||
|
||||
public override Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle)
|
||||
{
|
||||
return serie.context.center;
|
||||
}
|
||||
|
||||
public override void OnLegendButtonClick(int index, string legendName, bool show)
|
||||
{
|
||||
if (!serie.IsLegendName(legendName))
|
||||
return;
|
||||
LegendHelper.CheckDataShow(serie, legendName, show);
|
||||
chart.UpdateLegendColor(legendName, show);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
|
||||
public override void OnLegendButtonEnter(int index, string legendName)
|
||||
{
|
||||
if (!serie.IsLegendName(legendName))
|
||||
return;
|
||||
LegendHelper.CheckDataHighlighted(serie, legendName, true);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
|
||||
public override void OnLegendButtonExit(int index, string legendName)
|
||||
{
|
||||
if (!serie.IsLegendName(legendName))
|
||||
return;
|
||||
LegendHelper.CheckDataHighlighted(serie, legendName, false);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
if (!chart.HasSerie<Pie>()) return;
|
||||
if (chart.pointerPos == Vector2.zero) return;
|
||||
var refresh = false;
|
||||
for (int i = 0; i < chart.series.Count; i++)
|
||||
{
|
||||
var serie = chart.GetSerie(i);
|
||||
if (!(serie is Pie)) continue;
|
||||
var index = GetPiePosIndex(serie, chart.pointerPos);
|
||||
if (index >= 0)
|
||||
{
|
||||
refresh = true;
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
if (j == index) serie.data[j].context.selected = !serie.data[j].context.selected;
|
||||
else serie.data[j].context.selected = false;
|
||||
}
|
||||
if (chart.onPointerClickPie != null)
|
||||
{
|
||||
chart.onPointerClickPie(eventData, i, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (refresh) chart.RefreshChart();
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
var needCheck = m_LegendEnter || (chart.isPointerInChart && PointerIsInPieSerie(serie, chart.pointerPos));
|
||||
var needInteract = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName);
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValueAndColor(ref needInteract, serieData.context.outsideRadius, color, toColor);
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
var dataIndex = GetPiePosIndex(serie, chart.pointerPos);
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
if (dataIndex == i || (m_LegendEnter && m_LegendEnterIndex == i))
|
||||
{
|
||||
serie.context.pointerItemDataIndex = i;
|
||||
serieData.context.highlight = true;
|
||||
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName);
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, true);
|
||||
var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, true);
|
||||
var value = serieData.context.outsideRadius + chart.theme.serie.pieTooltipExtraRadius;
|
||||
serieData.interact.SetValueAndColor(ref needInteract, value, color, toColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName);
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
serieData.interact.SetValueAndColor(ref needInteract, serieData.context.outsideRadius, color, toColor);
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRuntimeData(Serie serie)
|
||||
{
|
||||
var data = serie.data;
|
||||
serie.context.dataMax = serie.yMax;
|
||||
serie.context.startAngle = GetStartAngle(serie);
|
||||
var runtimePieDataTotal = serie.yTotal;
|
||||
|
||||
SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
float startDegree = serie.context.startAngle;
|
||||
float totalDegree = 0;
|
||||
float zeroReplaceValue = 0;
|
||||
int showdataCount = 0;
|
||||
foreach (var sd in serie.data)
|
||||
{
|
||||
if (sd.show && serie.pieRoseType == RoseType.Area) showdataCount++;
|
||||
sd.context.canShowLabel = false;
|
||||
}
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1);
|
||||
var dataTotalFilterMinAngle = runtimePieDataTotal;
|
||||
if (isAllZeroValue)
|
||||
{
|
||||
totalDegree = 360;
|
||||
zeroReplaceValue = totalDegree / data.Count;
|
||||
serie.context.dataMax = zeroReplaceValue;
|
||||
runtimePieDataTotal = 360;
|
||||
dataTotalFilterMinAngle = 360;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataTotalFilterMinAngle = GetTotalAngle(serie, runtimePieDataTotal, ref totalDegree);
|
||||
}
|
||||
for (int n = 0; n < data.Count; n++)
|
||||
{
|
||||
var serieData = data[n];
|
||||
serieData.index = n;
|
||||
var value = isAllZeroValue ? zeroReplaceValue : serieData.GetCurrData(1, dataChangeDuration);
|
||||
serieData.context.startAngle = startDegree;
|
||||
serieData.context.toAngle = startDegree;
|
||||
serieData.context.halfAngle = startDegree;
|
||||
serieData.context.currentAngle = startDegree;
|
||||
if (!serieData.show)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float degree = serie.pieRoseType == RoseType.Area ?
|
||||
(totalDegree / showdataCount) :
|
||||
(float) (totalDegree * value / dataTotalFilterMinAngle);
|
||||
if (serie.minAngle > 0 && degree < serie.minAngle) degree = serie.minAngle;
|
||||
serieData.context.toAngle = startDegree + degree;
|
||||
if (serieData.radius > 0)
|
||||
serieData.context.outsideRadius = ChartHelper.GetActualValue(serieData.radius, Mathf.Min(chart.chartWidth, chart.chartHeight));
|
||||
else
|
||||
serieData.context.outsideRadius = serie.pieRoseType > 0 ?
|
||||
serie.context.insideRadius + (float) ((serie.context.outsideRadius - serie.context.insideRadius) * value / serie.context.dataMax) :
|
||||
serie.context.outsideRadius;
|
||||
if (serieData.context.highlight)
|
||||
{
|
||||
serieData.context.outsideRadius += chart.theme.serie.pieTooltipExtraRadius;
|
||||
}
|
||||
var offset = 0f;
|
||||
if (serie.pieClickOffset && serieData.selected)
|
||||
{
|
||||
offset += chart.theme.serie.pieSelectedOffset;
|
||||
}
|
||||
if (serie.animation.CheckDetailBreak(serieData.context.toAngle))
|
||||
{
|
||||
serieData.context.currentAngle = serie.animation.GetCurrDetail();
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.currentAngle = serieData.context.toAngle;
|
||||
}
|
||||
var halfDegree = (serieData.context.toAngle - startDegree) / 2;
|
||||
serieData.context.halfAngle = startDegree + halfDegree;
|
||||
serieData.context.offsetCenter = serie.context.center;
|
||||
serieData.context.insideRadius = serie.context.insideRadius;
|
||||
if (offset > 0)
|
||||
{
|
||||
var currRad = serieData.context.halfAngle * Mathf.Deg2Rad;
|
||||
var currSin = Mathf.Sin(currRad);
|
||||
var currCos = Mathf.Cos(currRad);
|
||||
serieData.context.offsetRadius = 0;
|
||||
serieData.context.insideRadius -= serieData.context.offsetRadius;
|
||||
serieData.context.outsideRadius -= serieData.context.offsetRadius;
|
||||
if (serie.pieClickOffset && serieData.selected)
|
||||
{
|
||||
serieData.context.offsetRadius += chart.theme.serie.pieSelectedOffset;
|
||||
if (serieData.context.insideRadius > 0)
|
||||
{
|
||||
serieData.context.insideRadius += chart.theme.serie.pieSelectedOffset;
|
||||
}
|
||||
serieData.context.outsideRadius += chart.theme.serie.pieSelectedOffset;
|
||||
}
|
||||
serieData.context.offsetCenter = new Vector3(
|
||||
serie.context.center.x + serieData.context.offsetRadius * currSin,
|
||||
serie.context.center.y + serieData.context.offsetRadius * currCos);
|
||||
}
|
||||
serieData.context.canShowLabel = serieData.context.currentAngle >= serieData.context.halfAngle;
|
||||
startDegree = serieData.context.toAngle;
|
||||
SerieLabelHelper.UpdatePieLabelPosition(serie, serieData);
|
||||
}
|
||||
SerieLabelHelper.AvoidLabelOverlap(serie, chart.theme.common);
|
||||
}
|
||||
|
||||
private double GetTotalAngle(Serie serie, double dataTotal, ref float totalAngle)
|
||||
{
|
||||
totalAngle = serie.context.startAngle + 360f;
|
||||
if (serie.minAngle > 0)
|
||||
{
|
||||
var rate = serie.minAngle / 360;
|
||||
var minAngleValue = dataTotal * rate;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var value = serieData.GetData(1);
|
||||
if (value < minAngleValue)
|
||||
{
|
||||
totalAngle -= serie.minAngle;
|
||||
dataTotal -= value;
|
||||
}
|
||||
}
|
||||
return dataTotal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dataTotal;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPieCenter(VertexHelper vh, Serie serie, ItemStyle itemStyle, float insideRadius)
|
||||
{
|
||||
if (!ChartHelper.IsClearColor(itemStyle.centerColor))
|
||||
{
|
||||
var radius = insideRadius - itemStyle.centerGap;
|
||||
UGL.DrawCricle(vh, serie.context.center, radius, itemStyle.centerColor, chart.settings.cicleSmoothness);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPie(VertexHelper vh, Serie serie)
|
||||
{
|
||||
if (!serie.show || serie.animation.HasFadeOut())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var dataChanging = false;
|
||||
var interacting = false;
|
||||
var color = ColorUtil.clearColor32;
|
||||
var toColor = ColorUtil.clearColor32;
|
||||
var data = serie.data;
|
||||
serie.animation.InitProgress(0, 360);
|
||||
for (int n = 0; n < data.Count; n++)
|
||||
{
|
||||
var serieData = data[n];
|
||||
if (!serieData.show)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (serieData.IsDataChanged())
|
||||
dataChanging = true;
|
||||
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.context.highlight);
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName);
|
||||
var outsideRadius = 0f;
|
||||
|
||||
var borderWidth = itemStyle.borderWidth;
|
||||
var borderColor = itemStyle.borderColor;
|
||||
|
||||
var progress = AnimationStyleHelper.CheckDataAnimation(chart, serie, n, 1);
|
||||
var insideRadius = serieData.context.insideRadius * progress;
|
||||
|
||||
//if (!serieData.interact.TryGetValueAndColor(ref outsideRadius, ref color, ref toColor, ref interacting))
|
||||
{
|
||||
color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight);
|
||||
toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight);
|
||||
outsideRadius = serieData.context.outsideRadius * progress;
|
||||
serieData.interact.SetValueAndColor(ref interacting, outsideRadius, color, toColor);
|
||||
}
|
||||
|
||||
if (serie.pieClickOffset && serieData.selected)
|
||||
{
|
||||
var drawEndDegree = serieData.context.currentAngle;
|
||||
var needRoundCap = serie.roundCap && insideRadius > 0;
|
||||
UGL.DrawDoughnut(vh, serieData.context.offsetCenter, insideRadius,
|
||||
outsideRadius, color, toColor, Color.clear, serieData.context.startAngle,
|
||||
drawEndDegree, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness,
|
||||
needRoundCap, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var drawEndDegree = serieData.context.currentAngle;
|
||||
var needRoundCap = serie.roundCap && insideRadius > 0;
|
||||
UGL.DrawDoughnut(vh, serie.context.center, insideRadius,
|
||||
outsideRadius, color, toColor, Color.clear, serieData.context.startAngle,
|
||||
drawEndDegree, borderWidth, borderColor, serie.gap / 2, chart.settings.cicleSmoothness,
|
||||
needRoundCap, true);
|
||||
DrawPieCenter(vh, serie, itemStyle, insideRadius);
|
||||
}
|
||||
|
||||
if (serie.animation.CheckDetailBreak(serieData.context.toAngle))
|
||||
break;
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress();
|
||||
serie.animation.CheckSymbol(serie.symbol.GetSize(null, chart.theme.serie.lineSymbolSize));
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsAnyPieClickOffset()
|
||||
{
|
||||
foreach (var serie in chart.series)
|
||||
{
|
||||
if (serie is Pie && serie.pieClickOffset)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool IsAnyPieDataHighlight()
|
||||
{
|
||||
foreach (var serie in chart.series)
|
||||
{
|
||||
if (serie is Pie)
|
||||
{
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.context.highlight)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DrawPieLabelLine(VertexHelper vh, Serie serie)
|
||||
{
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||
if (SerieLabelHelper.CanShowLabel(serie, serieData, serieLabel, 1))
|
||||
{
|
||||
int colorIndex = chart.m_LegendRealShowName.IndexOf(serieData.name);
|
||||
Color color = chart.theme.GetColor(colorIndex);
|
||||
DrawPieLabelLine(vh, serie, serieData, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPieLabelLine(VertexHelper vh, Serie serie, SerieData serieData, Color color)
|
||||
{
|
||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||
var labelLine = SerieHelper.GetSerieLabelLine(serie, serieData);
|
||||
if (serieLabel != null && serieLabel.show &&
|
||||
labelLine != null && labelLine.show &&
|
||||
(serieLabel.IsDefaultPosition(LabelStyle.Position.Outside)))
|
||||
{
|
||||
var insideRadius = serieData.context.insideRadius;
|
||||
var outSideRadius = serieData.context.outsideRadius;
|
||||
var center = serie.context.center;
|
||||
var currAngle = serieData.context.halfAngle;
|
||||
|
||||
if (!ChartHelper.IsClearColor(labelLine.lineColor))
|
||||
color = labelLine.lineColor;
|
||||
else if (labelLine.lineType == LabelLine.LineType.HorizontalLine)
|
||||
color *= color;
|
||||
|
||||
float currSin = Mathf.Sin(currAngle * Mathf.Deg2Rad);
|
||||
float currCos = Mathf.Cos(currAngle * Mathf.Deg2Rad);
|
||||
var radius1 = labelLine.lineType == LabelLine.LineType.HorizontalLine ?
|
||||
serie.context.outsideRadius : outSideRadius;
|
||||
var radius2 = serie.context.outsideRadius + labelLine.lineLength1;
|
||||
var radius3 = insideRadius + (outSideRadius - insideRadius) / 2;
|
||||
if (radius1 < serie.context.insideRadius) radius1 = serie.context.insideRadius;
|
||||
radius1 -= 0.1f;
|
||||
var pos0 = new Vector3(center.x + radius3 * currSin, center.y + radius3 * currCos);
|
||||
var pos1 = new Vector3(center.x + radius1 * currSin, center.y + radius1 * currCos);
|
||||
var pos2 = serieData.context.labelPosition;
|
||||
if (pos2.x == 0)
|
||||
{
|
||||
pos2 = new Vector3(center.x + radius2 * currSin, center.y + radius2 * currCos);
|
||||
}
|
||||
Vector3 pos4, pos6;
|
||||
var horizontalLineCircleRadius = labelLine.lineWidth * 4f;
|
||||
var lineCircleDiff = horizontalLineCircleRadius - 0.3f;
|
||||
var startAngle = serie.context.startAngle;
|
||||
if (currAngle < 90)
|
||||
{
|
||||
var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3;
|
||||
r4 += labelLine.lineLength1 - lineCircleDiff;
|
||||
pos6 = pos0 + Vector3.right * lineCircleDiff;
|
||||
pos4 = pos6 + Vector3.right * r4;
|
||||
}
|
||||
else if (currAngle < 180)
|
||||
{
|
||||
var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos * radius3, 2)) - currSin * radius3;
|
||||
r4 += labelLine.lineLength1 - lineCircleDiff;
|
||||
pos6 = pos0 + Vector3.right * lineCircleDiff;
|
||||
pos4 = pos6 + Vector3.right * r4;
|
||||
}
|
||||
else if (currAngle < 270)
|
||||
{
|
||||
var currSin1 = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad);
|
||||
var currCos1 = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad);
|
||||
var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos1 * radius3, 2)) - currSin1 * radius3;
|
||||
r4 += labelLine.lineLength1 - lineCircleDiff;
|
||||
pos6 = pos0 + Vector3.left * lineCircleDiff;
|
||||
pos4 = pos6 + Vector3.left * r4;
|
||||
}
|
||||
else
|
||||
{
|
||||
var currSin1 = Mathf.Sin((360 - currAngle) * Mathf.Deg2Rad);
|
||||
var currCos1 = Mathf.Cos((360 - currAngle) * Mathf.Deg2Rad);
|
||||
var r4 = Mathf.Sqrt(radius1 * radius1 - Mathf.Pow(currCos1 * radius3, 2)) - currSin1 * radius3;
|
||||
r4 += labelLine.lineLength1 - lineCircleDiff;
|
||||
pos6 = pos0 + Vector3.left * lineCircleDiff;
|
||||
pos4 = pos6 + Vector3.left * r4;
|
||||
}
|
||||
var pos5X = (currAngle - startAngle) % 360 > 180 ?
|
||||
pos2.x - labelLine.lineLength2 : pos2.x + labelLine.lineLength2;
|
||||
var pos5 = new Vector3(pos5X, pos2.y);
|
||||
switch (labelLine.lineType)
|
||||
{
|
||||
case LabelLine.LineType.BrokenLine:
|
||||
UGL.DrawLine(vh, pos1, pos2, pos5, labelLine.lineWidth, color);
|
||||
break;
|
||||
case LabelLine.LineType.Curves:
|
||||
UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, labelLine.lineWidth, color,
|
||||
chart.settings.lineSmoothness);
|
||||
break;
|
||||
case LabelLine.LineType.HorizontalLine:
|
||||
UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color);
|
||||
UGL.DrawLine(vh, pos6, pos4, labelLine.lineWidth, color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetPiePosIndex(Serie serie, Vector2 local)
|
||||
{
|
||||
if (!(serie is Pie))
|
||||
return -1;
|
||||
|
||||
var dist = Vector2.Distance(local, serie.context.center);
|
||||
var maxRadius = serie.context.outsideRadius + 3 * chart.theme.serie.pieSelectedOffset;
|
||||
if (dist < serie.context.insideRadius || dist > maxRadius)
|
||||
return -1;
|
||||
|
||||
var dir = local - new Vector2(serie.context.center.x, serie.context.center.y);
|
||||
var angle = ChartHelper.GetAngle360(Vector2.up, dir);
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
if (angle >= serieData.context.startAngle && angle <= serieData.context.toAngle)
|
||||
{
|
||||
var ndist = serieData.selected ?
|
||||
Vector2.Distance(local, serieData.context.offsetCenter) :
|
||||
dist;
|
||||
if (ndist >= serieData.context.insideRadius && ndist <= serieData.context.outsideRadius)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private bool PointerIsInPieSerie(Serie serie, Vector2 local)
|
||||
{
|
||||
if (!(serie is Pie))
|
||||
return false;
|
||||
|
||||
var dist = Vector2.Distance(local, serie.context.center);
|
||||
if (dist >= serie.context.insideRadius && dist <= serie.context.outsideRadius)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private float GetStartAngle(Serie serie)
|
||||
{
|
||||
return serie.clockwise ? (serie.startAngle + 360) % 360 : 360 - serie.startAngle;
|
||||
}
|
||||
|
||||
private float GetToAngle(Serie serie, float angle)
|
||||
{
|
||||
var toAngle = angle + serie.startAngle;
|
||||
if (!serie.clockwise)
|
||||
{
|
||||
toAngle = 360 - angle - serie.startAngle;
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
var currAngle = serie.animation.GetCurrDetail();
|
||||
if (serie.clockwise)
|
||||
{
|
||||
toAngle = toAngle > currAngle ? currAngle : toAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
toAngle = toAngle < 360 - currAngle ? 360 - currAngle : toAngle;
|
||||
}
|
||||
}
|
||||
return toAngle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13b8c981e5910447fbe769d539b77f96
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 375cebcd4f8c54025ab608f35b1fa8c6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(RadarHandler), true)]
|
||||
[RequireChartComponent(typeof(RadarCoord))]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(AreaStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(AreaStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField()]
|
||||
public class Radar : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
public override bool useDataNameForColor { get { return true; } }
|
||||
public override bool multiDimensionLabel { get { return radarType == RadarType.Multiple; } }
|
||||
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
chart.AddChartComponentWhenNoExist<RadarCoord>();
|
||||
var serie = chart.AddSerie<Radar>(serieName);
|
||||
serie.symbol.show = true;
|
||||
serie.symbol.type = SymbolType.Circle;
|
||||
serie.showDataName = true;
|
||||
List<double> data = new List<double>();
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
data.Add(Random.Range(20, 90));
|
||||
}
|
||||
chart.AddData(serie.index, data, "legendName");
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bda9968e18724e389ff1cbde57baeee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,504 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class RadarHandler : SerieHandler<Radar>
|
||||
{
|
||||
private RadarCoord m_RadarCoord;
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
if (!serie.show) return;
|
||||
switch (serie.radarType)
|
||||
{
|
||||
case RadarType.Multiple:
|
||||
DrawMutipleRadar(vh);
|
||||
break;
|
||||
case RadarType.Single:
|
||||
DrawSingleRadar(vh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
if (!serie.context.pointerEnter)
|
||||
return;
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
if (serie.radarType == RadarType.Single)
|
||||
{
|
||||
UpdateItemSerieParams(ref paramList, ref title, dataIndex, category,
|
||||
marker, itemFormatter, numericFormatter);
|
||||
return;
|
||||
}
|
||||
|
||||
var radar = chart.GetChartComponent<RadarCoord>(serie.radarIndex);
|
||||
if (radar == null)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, dataIndex, false);;
|
||||
title = serieData.name;
|
||||
for (int i = 0; i < serieData.data.Count; i++)
|
||||
{
|
||||
var indicator = radar.GetIndicator(i);
|
||||
if (indicator == null) continue;
|
||||
|
||||
var param = new SerieParams();
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.dimension = i;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = serieData.GetData(i);
|
||||
param.total = indicator.max;
|
||||
param.color = color;
|
||||
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(indicator.name);
|
||||
param.columns.Add(ChartCached.NumberToStr(serieData.GetData(i), param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
var needCheck = m_LegendEnter ||
|
||||
(chart.isPointerInChart && (m_RadarCoord != null && m_RadarCoord.IsPointerEnter()));
|
||||
var needInteract = false;
|
||||
var needHideAll = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag == needCheck)
|
||||
return;
|
||||
needHideAll = true;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerEnter = false;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
var areaStyle = serie.areaStyle;
|
||||
switch (serie.radarType)
|
||||
{
|
||||
case RadarType.Multiple:
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
serieData.index = i;
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, chart.theme.serie.lineSymbolSize);
|
||||
if (needHideAll || m_LegendEnter)
|
||||
{
|
||||
serieData.context.highlight = needHideAll ? false : true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize, serieData.context.highlight);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
foreach (var pos in serieData.context.dataPoints)
|
||||
{
|
||||
if (Vector3.Distance(chart.pointerPos, pos) < symbolSize * 2)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.context.pointerItemDataIndex = i;
|
||||
serieData.context.highlight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!serieData.context.highlight && areaStyle != null)
|
||||
{
|
||||
var center = m_RadarCoord.context.center;
|
||||
var dataPoints = serieData.context.dataPoints;
|
||||
for (int n = 0; n < dataPoints.Count; n++)
|
||||
{
|
||||
var p1 = dataPoints[n];
|
||||
var p2 = n >= dataPoints.Count - 1 ? dataPoints[0] : dataPoints[n + 1];
|
||||
if (UGLHelper.IsPointInTriangle(p1, center, p2, chart.pointerPos))
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.context.pointerItemDataIndex = i;
|
||||
serieData.context.highlight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize, serieData.context.highlight);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RadarType.Single:
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
serieData.index = i;
|
||||
if (Vector3.Distance(chart.pointerPos, serieData.context.position) < serie.symbol.size * 2)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.context.pointerItemDataIndex = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!serie.context.pointerEnter && areaStyle != null)
|
||||
{
|
||||
var center = m_RadarCoord.context.center;
|
||||
var dataPoints = serie.data;
|
||||
for (int n = 0; n < dataPoints.Count; n++)
|
||||
{
|
||||
var p1 = dataPoints[n];
|
||||
var p2 = n >= dataPoints.Count - 1 ? dataPoints[0] : dataPoints[n + 1];
|
||||
if (UGLHelper.IsPointInTriangle(p1.context.position, center, p2.context.position, chart.pointerPos))
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.context.pointerItemDataIndex = n;
|
||||
p1.context.highlight = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawMutipleRadar(VertexHelper vh)
|
||||
{
|
||||
if (!serie.show) return;
|
||||
m_RadarCoord = chart.GetChartComponent<RadarCoord>(serie.radarIndex);
|
||||
if (m_RadarCoord == null) return;
|
||||
|
||||
serie.containerIndex = m_RadarCoord.index;
|
||||
serie.containterInstanceId = m_RadarCoord.instanceId;
|
||||
|
||||
var startPoint = Vector3.zero;
|
||||
var toPoint = Vector3.zero;
|
||||
var firstPoint = Vector3.zero;
|
||||
var indicatorNum = m_RadarCoord.indicatorList.Count;
|
||||
var angle = 2 * Mathf.PI / indicatorNum;
|
||||
var centerPos = m_RadarCoord.context.center;
|
||||
serie.animation.InitProgress(0, 1);
|
||||
if (!serie.show || serie.animation.HasFadeOut())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var rate = serie.animation.GetCurrRate();
|
||||
var dataChanging = false;
|
||||
var interacting = false;
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
SerieHelper.GetAllMinMaxData(serie, m_RadarCoord.ceilRate);
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
var serieData = serie.data[j];
|
||||
string dataName = serieData.name;
|
||||
if (!serieData.show)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
var lineStyle = SerieHelper.GetLineStyle(serie, serieData);
|
||||
var areaStyle = SerieHelper.GetAreaStyle(serie, serieData);
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var isHighlight = serieData.context.highlight;
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName);
|
||||
var areaColor = SerieHelper.GetAreaColor(serie, serieData, chart.theme, colorIndex, isHighlight);
|
||||
var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, colorIndex, isHighlight);
|
||||
var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, colorIndex, isHighlight);
|
||||
var lineWidth = lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
int dataCount = m_RadarCoord.indicatorList.Count;
|
||||
serieData.context.dataPoints.Clear();
|
||||
for (int n = 0; n < dataCount; n++)
|
||||
{
|
||||
if (n >= serieData.data.Count) break;
|
||||
var min = m_RadarCoord.GetIndicatorMin(n);
|
||||
var max = m_RadarCoord.GetIndicatorMax(n);
|
||||
var value = serieData.GetCurrData(n, dataChangeDuration);
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
if (max == 0)
|
||||
{
|
||||
if (serie.data.Count > 1)
|
||||
{
|
||||
SerieHelper.GetMinMaxData(serie, n, out min, out max);
|
||||
min = ChartHelper.GetMinDivisibleValue(min, 0);
|
||||
max = ChartHelper.GetMaxDivisibleValue(max, 0);
|
||||
if (min > 0) min = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
max = serie.context.dataMax;
|
||||
}
|
||||
}
|
||||
var radius = (float) (m_RadarCoord.context.dataRadius * (value - min) / (max - min));
|
||||
var currAngle = (n + (m_RadarCoord.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle;
|
||||
radius *= rate;
|
||||
if (n == 0)
|
||||
{
|
||||
startPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle),
|
||||
centerPos.y + radius * Mathf.Cos(currAngle));
|
||||
firstPoint = startPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
toPoint = new Vector3(centerPos.x + radius * Mathf.Sin(currAngle),
|
||||
centerPos.y + radius * Mathf.Cos(currAngle));
|
||||
if (areaStyle != null && areaStyle.show)
|
||||
{
|
||||
UGL.DrawTriangle(vh, startPoint, toPoint, centerPos, areaColor, areaColor, areaToColor);
|
||||
}
|
||||
if (lineStyle.show)
|
||||
{
|
||||
ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, toPoint, lineColor);
|
||||
}
|
||||
startPoint = toPoint;
|
||||
}
|
||||
serieData.context.dataPoints.Add(startPoint);
|
||||
}
|
||||
if (areaStyle != null && areaStyle.show)
|
||||
{
|
||||
UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
|
||||
}
|
||||
if (lineStyle.show)
|
||||
{
|
||||
ChartDrawer.DrawLineStyle(vh, lineStyle.type, lineWidth, startPoint, firstPoint, lineColor);
|
||||
}
|
||||
if (symbol.show && symbol.type != SymbolType.None)
|
||||
{
|
||||
for (int m = 0; m < serieData.context.dataPoints.Count; m++)
|
||||
{
|
||||
var point = serieData.context.dataPoints[m];
|
||||
var symbolSize = isHighlight ?
|
||||
symbol.GetSelectedSize(null, chart.theme.serie.lineSymbolSelectedSize) :
|
||||
symbol.GetSize(null, chart.theme.serie.lineSymbolSize);
|
||||
if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting))
|
||||
{
|
||||
symbolSize = isHighlight ?
|
||||
symbol.GetSelectedSize(serieData.data, symbolSize) :
|
||||
symbol.GetSize(serieData.data, symbolSize);
|
||||
serieData.interact.SetValue(ref interacting, symbolSize);
|
||||
symbolSize = serie.animation.GetSysmbolSize(symbolSize);
|
||||
}
|
||||
var symbolColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, j, isHighlight);
|
||||
var symbolToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, j, isHighlight);
|
||||
var symbolEmptyColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, j, isHighlight, false);
|
||||
var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, chart.theme, isHighlight);
|
||||
var borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
|
||||
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, point, symbolColor,
|
||||
symbolToColor, symbolEmptyColor, borderColor, symbol.gap, cornerRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(1);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging || interacting)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSingleRadar(VertexHelper vh)
|
||||
{
|
||||
var radar = chart.GetChartComponent<RadarCoord>(serie.radarIndex);
|
||||
if (radar == null)
|
||||
return;
|
||||
|
||||
var indicatorNum = radar.indicatorList.Count;
|
||||
var angle = 2 * Mathf.PI / indicatorNum;
|
||||
var centerPos = radar.context.center;
|
||||
serie.animation.InitProgress(0, 1);
|
||||
serie.context.dataPoints.Clear();
|
||||
if (!serie.show || serie.animation.HasFadeOut())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var startPoint = Vector3.zero;
|
||||
var toPoint = Vector3.zero;
|
||||
var firstPoint = Vector3.zero;
|
||||
var lastColor = ColorUtil.clearColor32;
|
||||
var firstColor = ColorUtil.clearColor32;
|
||||
|
||||
var rate = serie.animation.GetCurrRate();
|
||||
var dataChanging = false;
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var startIndex = GetStartShowIndex(serie);
|
||||
var endIndex = GetEndShowIndex(serie);
|
||||
SerieHelper.UpdateMinMaxData(serie, 1, radar.ceilRate);
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
var serieData = serie.data[j];
|
||||
serieData.index = j;
|
||||
string dataName = serieData.name;
|
||||
|
||||
if (!serieData.show)
|
||||
{
|
||||
serieData.context.labelPosition = Vector3.zero;
|
||||
continue;
|
||||
}
|
||||
var lineStyle = SerieHelper.GetLineStyle(serie, serieData);
|
||||
var areaStyle = SerieHelper.GetAreaStyle(serie, serieData);
|
||||
var isHighlight = serie.context.pointerEnter;
|
||||
var areaColor = SerieHelper.GetAreaColor(serie, serieData, chart.theme, j, isHighlight);
|
||||
var areaToColor = SerieHelper.GetAreaToColor(serie, serieData, chart.theme, j, isHighlight);
|
||||
var lineColor = SerieHelper.GetLineColor(serie, serieData, chart.theme, j, isHighlight);
|
||||
int dataCount = radar.indicatorList.Count;
|
||||
var index = serieData.index;
|
||||
var p = radar.context.center;
|
||||
var max = radar.GetIndicatorMax(index);
|
||||
var value = serieData.GetCurrData(1, dataChangeDuration);
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
if (max == 0)
|
||||
{
|
||||
max = serie.context.dataMax;
|
||||
}
|
||||
if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
|
||||
{
|
||||
lineColor = radar.outRangeColor;
|
||||
}
|
||||
var radius = (float) (max < 0 ? radar.context.dataRadius - radar.context.dataRadius * value / max :
|
||||
radar.context.dataRadius * value / max);
|
||||
var currAngle = (index + (radar.positionType == RadarCoord.PositionType.Between ? 0.5f : 0)) * angle;
|
||||
radius *= rate;
|
||||
if (index == startIndex)
|
||||
{
|
||||
startPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
|
||||
p.y + radius * Mathf.Cos(currAngle));
|
||||
firstPoint = startPoint;
|
||||
lastColor = lineColor;
|
||||
firstColor = lineColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
toPoint = new Vector3(p.x + radius * Mathf.Sin(currAngle),
|
||||
p.y + radius * Mathf.Cos(currAngle));
|
||||
if (areaStyle != null && areaStyle.show)
|
||||
{
|
||||
UGL.DrawTriangle(vh, startPoint, toPoint, p, areaColor, areaColor, areaToColor);
|
||||
}
|
||||
if (lineStyle.show)
|
||||
{
|
||||
if (radar.connectCenter)
|
||||
ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos,
|
||||
chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor);
|
||||
ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, toPoint, chart.theme.serie.lineWidth,
|
||||
LineStyle.Type.Solid, radar.lineGradient ? lastColor : lineColor, lineColor);
|
||||
}
|
||||
startPoint = toPoint;
|
||||
lastColor = lineColor;
|
||||
}
|
||||
serieData.context.position = startPoint;
|
||||
serieData.context.labelPosition = startPoint;
|
||||
|
||||
if (areaStyle != null && areaStyle.show && j == endIndex)
|
||||
{
|
||||
UGL.DrawTriangle(vh, startPoint, firstPoint, centerPos, areaColor, areaColor, areaToColor);
|
||||
}
|
||||
if (lineStyle.show && j == endIndex)
|
||||
{
|
||||
if (radar.connectCenter)
|
||||
ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, centerPos,
|
||||
chart.theme.serie.lineWidth, LineStyle.Type.Solid, lastColor, lastColor);
|
||||
ChartDrawer.DrawLineStyle(vh, lineStyle, startPoint, firstPoint, chart.theme.serie.lineWidth,
|
||||
LineStyle.Type.Solid, lineColor, radar.lineGradient ? firstColor : lineColor);
|
||||
}
|
||||
}
|
||||
if (serie.symbol.show && serie.symbol.type != SymbolType.None)
|
||||
{
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
var serieData = serie.data[j];
|
||||
if (!serieData.show) continue;
|
||||
var isHighlight = serie.highlight || serieData.context.highlight || serie.context.pointerEnter;
|
||||
var serieIndex = serieData.index;
|
||||
var symbolSize = isHighlight ?
|
||||
serie.symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSelectedSize) :
|
||||
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 borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, chart.theme, isHighlight);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
|
||||
if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
|
||||
{
|
||||
symbolColor = radar.outRangeColor;
|
||||
symbolToColor = radar.outRangeColor;
|
||||
}
|
||||
chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.context.labelPosition, symbolColor,
|
||||
symbolToColor, symbolEmptyColor, borderColor, serie.symbol.gap, cornerRadius);
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(1);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetStartShowIndex(Serie serie)
|
||||
{
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
if (serie.data[i].show) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
private int GetEndShowIndex(Serie serie)
|
||||
{
|
||||
for (int i = serie.dataCount - 1; i >= 0; i--)
|
||||
{
|
||||
if (serie.data[i].show) return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void DrawRadarSymbol(VertexHelper vh, Serie serie, SerieData serieData, int serieIndex, bool isHighlight,
|
||||
List<Vector3> pointList)
|
||||
{
|
||||
if (serie.symbol.show && serie.symbol.type != SymbolType.None)
|
||||
{
|
||||
var symbolSize = isHighlight ?
|
||||
serie.symbol.GetSelectedSize(serieData.data, chart.theme.serie.lineSymbolSelectedSize) :
|
||||
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 borderColor = SerieHelper.GetSymbolBorderColor(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, symbolEmptyColor, borderColor, serie.symbol.gap, cornerRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8dd73709db7a4451b2fe6f03476cb7f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c15a1b60f1d3c4daca1fcd88d96ae7e7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,44 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(RingHandler), true)]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(TitleStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(TitleStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField()]
|
||||
public class Ring : Serie
|
||||
{
|
||||
public override bool useDataNameForColor { get { return true; } }
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Ring>(serieName);
|
||||
serie.roundCap = true;
|
||||
serie.gap = 10;
|
||||
serie.radius = new float[] { 0.3f, 0.35f };
|
||||
|
||||
var label = serie.AddExtraComponent<LabelStyle>();
|
||||
label.show = true;
|
||||
label.position = LabelStyle.Position.Center;
|
||||
label.formatter = "{d:f0}%";
|
||||
label.textStyle.autoColor = true;
|
||||
label.textStyle.fontSize = 28;
|
||||
|
||||
var titleStyle = serie.AddExtraComponent<TitleStyle>();
|
||||
titleStyle.show = false;
|
||||
titleStyle.offset = new Vector2(0, 30);
|
||||
|
||||
var value = Random.Range(30, 90);
|
||||
var max = 100;
|
||||
chart.AddData(serie.index, value, max, "data1");
|
||||
return serie;
|
||||
}
|
||||
|
||||
public override double GetDataTotal(int dimension, SerieData serieData = null)
|
||||
{
|
||||
if (serieData == null || serieData.data.Count <= 1)
|
||||
return base.GetDataTotal(dimension, serieData);
|
||||
return serieData.GetData(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c7fe8316f26241d8a9f4b3ce94d61bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,323 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class RingHandler : SerieHandler<Ring>
|
||||
{
|
||||
|
||||
public override int defaultDimension { get { return 0; } }
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
var needCheck = chart.isPointerInChart || m_LegendEnter;
|
||||
var needInteract = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag != needCheck)
|
||||
{
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
}
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
if (m_LegendEnter)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
serieData.context.highlight = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.context.pointerEnter = false;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
var ringIndex = GetRingIndex(chart.pointerPos);
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (!needInteract && ringIndex == serieData.index)
|
||||
{
|
||||
serie.context.pointerEnter = true;
|
||||
serie.context.pointerItemDataIndex = ringIndex;
|
||||
serieData.context.highlight = true;
|
||||
needInteract = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
if (dataIndex < 0)
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.category = category;
|
||||
param.dimension = defaultDimension;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = serieData.GetData(0);
|
||||
param.total = serieData.GetData(1);
|
||||
param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, dataIndex, false);
|
||||
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);;
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(serieData.name);
|
||||
param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
|
||||
public override Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
|
||||
{
|
||||
var centerRadius = (serieData.context.outsideRadius + serieData.context.insideRadius) / 2;
|
||||
var startAngle = serieData.context.startAngle;
|
||||
var toAngle = serieData.context.toAngle;
|
||||
switch (label.position)
|
||||
{
|
||||
case LabelStyle.Position.Bottom:
|
||||
case LabelStyle.Position.Start:
|
||||
var px1 = Mathf.Sin(startAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
var py1 = Mathf.Cos(startAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
var xDiff = serie.clockwise ? -label.distance : label.distance;
|
||||
serieData.context.labelPosition = serie.context.center + new Vector3(px1 + xDiff, py1);
|
||||
break;
|
||||
case LabelStyle.Position.Top:
|
||||
case LabelStyle.Position.End:
|
||||
startAngle += serie.clockwise ? -label.distance : label.distance;
|
||||
toAngle += serie.clockwise ? label.distance : -label.distance;
|
||||
var px2 = Mathf.Sin(toAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
var py2 = Mathf.Cos(toAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
serieData.context.labelPosition = serie.context.center + new Vector3(px2, py2);
|
||||
break;
|
||||
default: //LabelStyle.Position.Center
|
||||
serieData.context.labelPosition = serie.context.center + label.offset;
|
||||
break;
|
||||
}
|
||||
return serieData.context.labelPosition;
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
if (!serie.show || serie.animation.HasFadeOut()) return;
|
||||
var data = serie.data;
|
||||
serie.animation.InitProgress(serie.startAngle, serie.startAngle + 360);
|
||||
SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var ringWidth = serie.context.outsideRadius - serie.context.insideRadius;
|
||||
var dataChanging = false;
|
||||
for (int j = 0; j < data.Count; j++)
|
||||
{
|
||||
var serieData = data[j];
|
||||
serieData.index = j;
|
||||
if (!serieData.show) continue;
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
var value = serieData.GetFirstData(dataChangeDuration);
|
||||
var max = serieData.GetLastData();
|
||||
var degree = (float) (360 * value / max);
|
||||
var startDegree = GetStartAngle(serie);
|
||||
var toDegree = GetToAngle(serie, degree);
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.context.highlight);
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.legendName);
|
||||
var itemColor = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight);
|
||||
var itemToColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, serieData.context.highlight);
|
||||
var outsideRadius = serie.context.outsideRadius - j * (ringWidth + serie.gap);
|
||||
var insideRadius = outsideRadius - ringWidth;
|
||||
var borderWidth = itemStyle.borderWidth;
|
||||
var borderColor = itemStyle.borderColor;
|
||||
var roundCap = serie.roundCap && insideRadius > 0;
|
||||
|
||||
serieData.context.startAngle = serie.clockwise ? startDegree : toDegree;
|
||||
serieData.context.toAngle = serie.clockwise ? toDegree : startDegree;
|
||||
serieData.context.insideRadius = insideRadius;
|
||||
serieData.context.outsideRadius = serieData.radius > 0 ? serieData.radius : outsideRadius;
|
||||
DrawBackground(vh, serie, serieData, j, insideRadius, outsideRadius);
|
||||
UGL.DrawDoughnut(vh, serie.context.center, insideRadius, outsideRadius, itemColor, itemToColor,
|
||||
Color.clear, startDegree, toDegree, borderWidth, borderColor, 0, chart.settings.cicleSmoothness,
|
||||
roundCap, serie.clockwise);
|
||||
DrawCenter(vh, serie, serieData, insideRadius, j == data.Count - 1);
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(360);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLegendButtonClick(int index, string legendName, bool show)
|
||||
{
|
||||
if (!serie.IsLegendName(legendName))
|
||||
return;
|
||||
LegendHelper.CheckDataShow(serie, legendName, show);
|
||||
chart.UpdateLegendColor(legendName, show);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
|
||||
public override void OnLegendButtonEnter(int index, string legendName)
|
||||
{
|
||||
if (!serie.IsLegendName(legendName))
|
||||
return;
|
||||
LegendHelper.CheckDataHighlighted(serie, legendName, true);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
|
||||
public override void OnLegendButtonExit(int index, string legendName)
|
||||
{
|
||||
if (!serie.IsLegendName(legendName))
|
||||
return;
|
||||
LegendHelper.CheckDataHighlighted(serie, legendName, false);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{ }
|
||||
|
||||
private float GetStartAngle(Serie serie)
|
||||
{
|
||||
return serie.clockwise ? serie.startAngle : 360 - serie.startAngle;
|
||||
}
|
||||
|
||||
private float GetToAngle(Serie serie, float angle)
|
||||
{
|
||||
var toAngle = angle + serie.startAngle;
|
||||
if (!serie.clockwise)
|
||||
{
|
||||
toAngle = 360 - angle - serie.startAngle;
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
var currAngle = serie.animation.GetCurrDetail();
|
||||
if (serie.clockwise)
|
||||
{
|
||||
toAngle = toAngle > currAngle ? currAngle : toAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
toAngle = toAngle < 360 - currAngle ? 360 - currAngle : toAngle;
|
||||
}
|
||||
}
|
||||
return toAngle;
|
||||
}
|
||||
|
||||
private void DrawCenter(VertexHelper vh, Serie serie, SerieData serieData, float insideRadius, bool last)
|
||||
{
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
|
||||
if (!ChartHelper.IsClearColor(itemStyle.centerColor) && last)
|
||||
{
|
||||
var radius = insideRadius - itemStyle.centerGap;
|
||||
var smoothness = chart.settings.cicleSmoothness;
|
||||
UGL.DrawCricle(vh, serie.context.center, radius, itemStyle.centerColor, smoothness);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBackground(VertexHelper vh, Serie serie, SerieData serieData, int index, float insideRadius, float outsideRadius)
|
||||
{
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
|
||||
var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, serieData, chart.theme, index, false);
|
||||
if (itemStyle.backgroundWidth != 0)
|
||||
{
|
||||
var centerRadius = (outsideRadius + insideRadius) / 2;
|
||||
var inradius = centerRadius - itemStyle.backgroundWidth / 2;
|
||||
var outradius = centerRadius + itemStyle.backgroundWidth / 2;
|
||||
UGL.DrawDoughnut(vh, serie.context.center, inradius,
|
||||
outradius, backgroundColor, Color.clear, chart.settings.cicleSmoothness);
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawDoughnut(vh, serie.context.center, insideRadius,
|
||||
outsideRadius, backgroundColor, Color.clear, chart.settings.cicleSmoothness);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBorder(VertexHelper vh, Serie serie, SerieData serieData, float insideRadius, float outsideRadius)
|
||||
{
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData);
|
||||
if (itemStyle.show && itemStyle.borderWidth > 0 && !ChartHelper.IsClearColor(itemStyle.borderColor))
|
||||
{
|
||||
UGL.DrawDoughnut(vh, serie.context.center, outsideRadius,
|
||||
outsideRadius + itemStyle.borderWidth, itemStyle.borderColor,
|
||||
Color.clear, chart.settings.cicleSmoothness);
|
||||
UGL.DrawDoughnut(vh, serie.context.center, insideRadius,
|
||||
insideRadius + itemStyle.borderWidth, itemStyle.borderColor,
|
||||
Color.clear, chart.settings.cicleSmoothness);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetRingIndex(Vector2 local)
|
||||
{
|
||||
var dist = Vector2.Distance(local, serie.context.center);
|
||||
if (dist > serie.context.outsideRadius) return -1;
|
||||
Vector2 dir = local - new Vector2(serie.context.center.x, serie.context.center.y);
|
||||
float angle = VectorAngle(Vector2.up, dir);
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
serieData.index = i;
|
||||
if (dist >= serieData.context.insideRadius &&
|
||||
dist <= serieData.context.outsideRadius &&
|
||||
angle >= serieData.context.startAngle &&
|
||||
angle <= serieData.context.toAngle)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private float VectorAngle(Vector2 from, Vector2 to)
|
||||
{
|
||||
float angle;
|
||||
|
||||
Vector3 cross = Vector3.Cross(from, to);
|
||||
angle = Vector2.Angle(from, to);
|
||||
angle = cross.z > 0 ? -angle : angle;
|
||||
angle = (angle + 360) % 360;
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8c3c486efd6d8464a88d8f4b572b7bc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97fc5bddab1db4321aa7377ab8b8b8bc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
public class BaseScatter : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dba0ca827ad4d4b9989def35aba66665
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,350 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal class BaseScatterHandler<T> : SerieHandler<T> where T : BaseScatter
|
||||
{
|
||||
private GridCoord m_Grid;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateSerieContext();
|
||||
}
|
||||
|
||||
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
|
||||
string marker, string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title)
|
||||
{
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
title = serie.serieName;
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.category = category;
|
||||
param.dimension = 1;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.serieData = serieData;
|
||||
param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
if (!string.IsNullOrEmpty(serieData.name))
|
||||
param.columns.Add(serieData.name);
|
||||
param.columns.Add(ChartCached.NumberToStr(serieData.GetData(1), param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
|
||||
public override void DrawSerie(VertexHelper vh)
|
||||
{
|
||||
if (serie.IsUseCoord<SingleAxisCoord>())
|
||||
{
|
||||
DrawSingAxisScatterSerie(vh, serie);
|
||||
}
|
||||
else if (serie.IsUseCoord<GridCoord>())
|
||||
{
|
||||
DrawScatterSerie(vh, serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
var needCheck = m_LegendEnter || (chart.isPointerInChart && (m_Grid == null || m_Grid.IsPointerEnter()));
|
||||
|
||||
var needHideAll = false;
|
||||
if (!needCheck)
|
||||
{
|
||||
if (m_LastCheckContextFlag == needCheck)
|
||||
return;
|
||||
needHideAll = true;
|
||||
}
|
||||
m_LastCheckContextFlag = needCheck;
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
var themeSymbolSize = chart.theme.serie.scatterSymbolSize;
|
||||
var themeSymbolSelectedSize = chart.theme.serie.scatterSymbolSelectedSize;
|
||||
var needInteract = false;
|
||||
for (int i = serie.dataCount - 1; i >= 0; i--)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize);
|
||||
var symbolSelectedSize = symbol.GetSelectedSize(serieData.data, themeSymbolSelectedSize);
|
||||
if (m_LegendEnter ||
|
||||
(!needHideAll && Vector3.Distance(serieData.context.position, chart.pointerPos) <= symbolSize))
|
||||
{
|
||||
serie.context.pointerItemDataIndex = i;
|
||||
serie.context.pointerEnter = true;
|
||||
serieData.context.highlight = true;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSelectedSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.context.highlight = false;
|
||||
serieData.interact.SetValue(ref needInteract, symbolSize);
|
||||
}
|
||||
}
|
||||
if (needInteract)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DrawScatterSerie(VertexHelper vh, BaseScatter serie)
|
||||
{
|
||||
if (serie.animation.HasFadeOut())
|
||||
return;
|
||||
|
||||
if (!serie.show)
|
||||
return;
|
||||
|
||||
XAxis xAxis;
|
||||
if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex))
|
||||
return;
|
||||
|
||||
YAxis yAxis;
|
||||
if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex))
|
||||
return;
|
||||
|
||||
if (!chart.TryGetChartComponent<GridCoord>(out m_Grid, xAxis.gridIndex))
|
||||
return;
|
||||
|
||||
DataZoom xDataZoom;
|
||||
DataZoom yDataZoom;
|
||||
chart.GetDataZoomOfSerie(serie, out xDataZoom, out yDataZoom);
|
||||
|
||||
var theme = chart.theme;
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > serie.dataCount ? serie.dataCount : serie.maxShow) :
|
||||
serie.dataCount;
|
||||
serie.animation.InitProgress(0, 1);
|
||||
var rate = serie.animation.GetCurrRate();
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var dataChanging = false;
|
||||
var interacting = false;
|
||||
var dataList = serie.GetDataList(xDataZoom);
|
||||
var isEffectScatter = serie is EffectScatter;
|
||||
var colorIndex = serie.context.colorIndex;
|
||||
|
||||
serie.containerIndex = m_Grid.index;
|
||||
serie.containterInstanceId = m_Grid.instanceId;
|
||||
|
||||
foreach (var serieData in dataList)
|
||||
{
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
if (!symbol.ShowSymbol(serieData.index, maxCount))
|
||||
continue;
|
||||
|
||||
var highlight = serie.highlight || serieData.context.highlight;
|
||||
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 borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, theme, highlight);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
|
||||
double xValue = serieData.GetCurrData(0, dataChangeDuration, xAxis.inverse);
|
||||
double yValue = serieData.GetCurrData(1, dataChangeDuration, yAxis.inverse);
|
||||
|
||||
if (serieData.IsDataChanged())
|
||||
dataChanging = true;
|
||||
|
||||
float pX = m_Grid.context.x + xAxis.axisLine.GetWidth(theme.axis.lineWidth);
|
||||
float pY = m_Grid.context.y + yAxis.axisLine.GetWidth(theme.axis.lineWidth);
|
||||
float xDataHig = GetDataHig(xAxis, xValue, m_Grid.context.width);
|
||||
float yDataHig = GetDataHig(yAxis, yValue, m_Grid.context.height);
|
||||
var pos = new Vector3(pX + xDataHig, pY + yDataHig);
|
||||
|
||||
if (!m_Grid.Contains(pos))
|
||||
continue;
|
||||
|
||||
serie.context.dataPoints.Add(pos);
|
||||
serieData.context.position = pos;
|
||||
var datas = serieData.data;
|
||||
var symbolSize = serie.highlight || serieData.context.highlight ?
|
||||
theme.serie.scatterSymbolSelectedSize :
|
||||
theme.serie.scatterSymbolSize;
|
||||
if (!serieData.interact.TryGetValue(ref symbolSize, ref interacting))
|
||||
{
|
||||
symbolSize = highlight ?
|
||||
symbol.GetSelectedSize(serieData.data, symbolSize) :
|
||||
symbol.GetSize(serieData.data, symbolSize);
|
||||
serieData.interact.SetValue(ref interacting, symbolSize);
|
||||
}
|
||||
|
||||
symbolSize *= rate;
|
||||
|
||||
if (isEffectScatter)
|
||||
{
|
||||
for (int count = 0; count < symbol.animationSize.Count; count++)
|
||||
{
|
||||
var nowSize = symbol.animationSize[count];
|
||||
color.a = (byte) (255 * (symbolSize - nowSize) / symbolSize);
|
||||
chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos,
|
||||
color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius);
|
||||
}
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (symbolSize > 100) symbolSize = 100;
|
||||
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos,
|
||||
color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius);
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(1);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging || interacting)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void DrawSingAxisScatterSerie(VertexHelper vh, BaseScatter serie)
|
||||
{
|
||||
if (serie.animation.HasFadeOut())
|
||||
return;
|
||||
|
||||
if (!serie.show)
|
||||
return;
|
||||
|
||||
var axis = chart.GetChartComponent<SingleAxis>(serie.singleAxisIndex);
|
||||
if (axis == null)
|
||||
return;
|
||||
|
||||
DataZoom xDataZoom;
|
||||
DataZoom yDataZoom;
|
||||
chart.GetDataZoomOfSerie(serie, out xDataZoom, out yDataZoom);
|
||||
|
||||
var theme = chart.theme;
|
||||
int maxCount = serie.maxShow > 0 ?
|
||||
(serie.maxShow > serie.dataCount ? serie.dataCount : serie.maxShow) :
|
||||
serie.dataCount;
|
||||
serie.animation.InitProgress(0, 1);
|
||||
|
||||
var rate = serie.animation.GetCurrRate();
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var dataChanging = false;
|
||||
var dataList = serie.GetDataList(xDataZoom);
|
||||
var isEffectScatter = serie is EffectScatter;
|
||||
var colorIndex = serie.context.colorIndex;
|
||||
|
||||
serie.containerIndex = axis.index;
|
||||
serie.containterInstanceId = axis.instanceId;
|
||||
|
||||
foreach (var serieData in dataList)
|
||||
{
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
if (!symbol.ShowSymbol(serieData.index, maxCount))
|
||||
continue;
|
||||
|
||||
var highlight = serie.highlight || serieData.context.highlight;
|
||||
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 borderColor = SerieHelper.GetSymbolBorderColor(serie, serieData, theme, highlight);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
|
||||
var xValue = serieData.GetCurrData(0, dataChangeDuration, axis.inverse);
|
||||
|
||||
if (serieData.IsDataChanged())
|
||||
dataChanging = true;
|
||||
|
||||
var pos = Vector3.zero;
|
||||
if (axis.orient == Orient.Horizonal)
|
||||
{
|
||||
var xDataHig = GetDataHig(axis, xValue, axis.context.width);
|
||||
var yDataHig = axis.context.height / 2;
|
||||
pos = new Vector3(axis.context.x + xDataHig, axis.context.y + yDataHig);
|
||||
}
|
||||
else
|
||||
{
|
||||
var yDataHig = GetDataHig(axis, xValue, axis.context.width);
|
||||
var xDataHig = axis.context.height / 2;
|
||||
pos = new Vector3(axis.context.x + xDataHig, axis.context.y + yDataHig);
|
||||
}
|
||||
serie.context.dataPoints.Add(pos);
|
||||
serieData.context.position = pos;
|
||||
|
||||
var datas = serieData.data;
|
||||
var symbolSize = 0f;
|
||||
if (serie.highlight || serieData.context.highlight)
|
||||
symbolSize = symbol.GetSelectedSize(datas, theme.serie.scatterSymbolSelectedSize);
|
||||
else
|
||||
symbolSize = symbol.GetSize(datas, theme.serie.scatterSymbolSize);
|
||||
symbolSize *= rate;
|
||||
|
||||
if (isEffectScatter)
|
||||
{
|
||||
if (symbolSize > 100) symbolSize = 100;
|
||||
for (int count = 0; count < symbol.animationSize.Count; count++)
|
||||
{
|
||||
var nowSize = symbol.animationSize[count];
|
||||
color.a = (byte) (255 * (symbolSize - nowSize) / symbolSize);
|
||||
chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos,
|
||||
color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius);
|
||||
}
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (symbolSize > 100) symbolSize = 100;
|
||||
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos,
|
||||
color, toColor, emptyColor, borderColor, symbol.gap, cornerRadius);
|
||||
}
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(1);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private static float GetDataHig(Axis axis, double value, float totalWidth)
|
||||
{
|
||||
if (axis.IsLog())
|
||||
{
|
||||
int minIndex = axis.GetLogMinIndex();
|
||||
float nowIndex = axis.GetLogValue(value);
|
||||
return (nowIndex - minIndex) / axis.splitNumber * totalWidth;
|
||||
}
|
||||
else if (axis.IsCategory())
|
||||
{
|
||||
if (axis.boundaryGap)
|
||||
{
|
||||
float tick = (float) (totalWidth / (axis.context.minMaxRange + 1));
|
||||
return tick / 2 + (float) (value - axis.context.minValue) * tick;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float) ((value - axis.context.minValue) / axis.context.minMaxRange * totalWidth);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float) ((value - axis.context.minValue) / axis.context.minMaxRange * totalWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31373c1595ff249188e33330f2eff1ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(EffectScatterHandler), true)]
|
||||
[CoordOptions(typeof(GridCoord), typeof(SingleAxisCoord))]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField("m_Radius")]
|
||||
public class EffectScatter : BaseScatter
|
||||
{
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<EffectScatter>(serieName);
|
||||
serie.symbol.show = true;
|
||||
serie.symbol.type = SymbolType.Circle;
|
||||
serie.itemStyle.opacity = 0.8f;
|
||||
serie.clip = false;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
chart.AddData(serie.index, Random.Range(10, 100), Random.Range(10, 100));
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c34d4976ef53c48a4b091d52694d8a7f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class EffectScatterHandler : BaseScatterHandler<EffectScatter>
|
||||
{
|
||||
private float m_EffectScatterSpeed = 15;
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
var symbolSize = serie.symbol.GetSize(null, chart.theme.serie.scatterSymbolSize);
|
||||
for (int i = 0; i < serie.symbol.animationSize.Count; ++i)
|
||||
{
|
||||
serie.symbol.animationSize[i] += m_EffectScatterSpeed * Time.deltaTime;
|
||||
if (serie.symbol.animationSize[i] > symbolSize)
|
||||
{
|
||||
serie.symbol.animationSize[i] = i * 5;
|
||||
}
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb7c24770dff64d7b857f459de7b2333
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[SerieHandler(typeof(ScatterHandler), true)]
|
||||
[CoordOptions(typeof(GridCoord), typeof(SingleAxisCoord))]
|
||||
[SerieExtraComponent(typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraComponent(typeof(ItemStyle), typeof(LabelStyle), typeof(EmphasisItemStyle), typeof(EmphasisLabelStyle))]
|
||||
[SerieDataExtraField("m_Radius")]
|
||||
public class Scatter : BaseScatter
|
||||
{
|
||||
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Scatter>(serieName);
|
||||
serie.symbol.show = true;
|
||||
serie.symbol.type = SymbolType.Circle;
|
||||
serie.itemStyle.opacity = 0.8f;
|
||||
serie.clip = false;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
chart.AddData(serie.index, Random.Range(10, 100), Random.Range(10, 100));
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 75a031f5547984317b5659a03d7f5e32
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class ScatterHandler : BaseScatterHandler<Scatter>
|
||||
{ }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ee7d7a8f04034cd38fd9d43f1a41825
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public partial class Serie
|
||||
{
|
||||
public static Dictionary<Type, string> extraComponentMap = new Dictionary<Type, string>
|
||||
{ { typeof(LabelStyle), "m_Labels" },
|
||||
{ typeof(LabelLine), "m_LabelLines" },
|
||||
{ typeof(EndLabelStyle), "m_EndLabels" },
|
||||
{ typeof(LineArrow), "m_LineArrows" },
|
||||
{ typeof(AreaStyle), "m_AreaStyles" },
|
||||
{ typeof(TitleStyle), "m_TitleStyles" },
|
||||
{ typeof(EmphasisItemStyle), "m_EmphasisItemStyles" },
|
||||
{ typeof(EmphasisLabelStyle), "m_EmphasisLabels" },
|
||||
{ typeof(EmphasisLabelLine), "m_EmphasisLabelLines" },
|
||||
};
|
||||
|
||||
[SerializeField][IgnoreDoc] private List<LabelStyle> m_Labels = new List<LabelStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<LabelLine> m_LabelLines = new List<LabelLine>();
|
||||
[SerializeField][IgnoreDoc] private List<EndLabelStyle> m_EndLabels = new List<EndLabelStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<LineArrow> m_LineArrows = new List<LineArrow>();
|
||||
[SerializeField][IgnoreDoc] private List<AreaStyle> m_AreaStyles = new List<AreaStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<TitleStyle> m_TitleStyles = new List<TitleStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<EmphasisItemStyle> m_EmphasisItemStyles = new List<EmphasisItemStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<EmphasisLabelStyle> m_EmphasisLabels = new List<EmphasisLabelStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<EmphasisLabelLine> m_EmphasisLabelLines = new List<EmphasisLabelLine>();
|
||||
|
||||
/// <summary>
|
||||
/// The style of area.
|
||||
/// |区域填充样式。
|
||||
/// </summary>
|
||||
public AreaStyle areaStyle { get { return m_AreaStyles.Count > 0 ? m_AreaStyles[0] : null; } }
|
||||
/// <summary>
|
||||
/// Text label of graphic element,to explain some data information about graphic item like value, name and so on.
|
||||
/// |图形上的文本标签,可用于说明图形的一些数据信息,比如值,名称等。
|
||||
/// </summary>
|
||||
public LabelStyle label { get { return m_Labels.Count > 0 ? m_Labels[0] : null; } }
|
||||
public LabelStyle endLabel { get { return m_EndLabels.Count > 0 ? m_EndLabels[0] : null; } }
|
||||
/// <summary>
|
||||
/// The line of label.
|
||||
/// |标签上的视觉引导线。
|
||||
/// </summary>
|
||||
public LabelLine labelLine { get { return m_LabelLines.Count > 0 ? m_LabelLines[0] : null; } }
|
||||
/// <summary>
|
||||
/// The arrow of line.
|
||||
/// |折线图的箭头。
|
||||
/// </summary>
|
||||
public LineArrow lineArrow { get { return m_LineArrows.Count > 0 ? m_LineArrows[0] : null; } }
|
||||
/// <summary>
|
||||
/// 高亮的图形样式
|
||||
/// </summary>
|
||||
public EmphasisItemStyle emphasisItemStyle { get { return m_EmphasisItemStyles.Count > 0 ? m_EmphasisItemStyles[0] : null; } }
|
||||
/// <summary>
|
||||
/// 高亮时的标签样式
|
||||
/// </summary>
|
||||
public EmphasisLabelStyle emphasisLabel { get { return m_EmphasisLabels.Count > 0 ? m_EmphasisLabels[0] : null; } }
|
||||
/// <summary>
|
||||
/// 高亮时的标签引导线样式
|
||||
/// </summary>
|
||||
public EmphasisLabelLine emphasisLabelLine { get { return m_EmphasisLabelLines.Count > 0 ? m_EmphasisLabelLines[0] : null; } }
|
||||
/// <summary>
|
||||
/// the icon of data.
|
||||
/// |数据项标题样式。
|
||||
/// </summary>
|
||||
public TitleStyle titleStyle { get { return m_TitleStyles.Count > 0 ? m_TitleStyles[0] : null; } }
|
||||
|
||||
public void RemoveAllExtraComponent()
|
||||
{
|
||||
var serieType = GetType();
|
||||
foreach (var kv in extraComponentMap)
|
||||
{
|
||||
ReflectionUtil.InvokeListClear(this, serieType.GetField(kv.Value));
|
||||
}
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
public T AddExtraComponent<T>() where T : ChildComponent, ISerieExtraComponent
|
||||
{
|
||||
return AddExtraComponent(typeof(T)) as T;
|
||||
}
|
||||
|
||||
public ISerieExtraComponent AddExtraComponent(Type type)
|
||||
{
|
||||
if (GetType().IsDefined(typeof(SerieExtraComponentAttribute), false))
|
||||
{
|
||||
var attr = GetType().GetAttribute<SerieExtraComponentAttribute>();
|
||||
if (attr.Contains(type))
|
||||
{
|
||||
var fieldName = string.Empty;
|
||||
if (extraComponentMap.TryGetValue(type, out fieldName))
|
||||
{
|
||||
var field = typeof(Serie).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (ReflectionUtil.InvokeListCount(this, field) <= 0)
|
||||
{
|
||||
var extraComponent = Activator.CreateInstance(type) as ISerieExtraComponent;
|
||||
ReflectionUtil.InvokeListAdd(this, field, extraComponent);
|
||||
SetAllDirty();
|
||||
return extraComponent;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReflectionUtil.InvokeListGet<ISerieExtraComponent>(this, field, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new System.Exception(string.Format("Serie {0} not support extra component: {1}",
|
||||
GetType().Name, type.Name));
|
||||
}
|
||||
|
||||
public void RemoveExtraComponent<T>() where T : ISerieExtraComponent
|
||||
{
|
||||
RemoveExtraComponent(typeof(T));
|
||||
}
|
||||
|
||||
public void RemoveExtraComponent(Type type)
|
||||
{
|
||||
if (GetType().IsDefined(typeof(SerieExtraComponentAttribute), false))
|
||||
{
|
||||
var attr = GetType().GetAttribute<SerieExtraComponentAttribute>();
|
||||
if (attr.Contains(type))
|
||||
{
|
||||
var fieldName = string.Empty;
|
||||
if (extraComponentMap.TryGetValue(type, out fieldName))
|
||||
{
|
||||
var field = typeof(Serie).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
ReflectionUtil.InvokeListClear(this, field);
|
||||
SetAllDirty();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new System.Exception(string.Format("Serie {0} not support extra component: {1}",
|
||||
GetType().Name, type.Name));
|
||||
}
|
||||
|
||||
private void RemoveExtraComponentList<T>(List<T> list) where T : ISerieExtraComponent
|
||||
{
|
||||
if (list.Count > 0)
|
||||
{
|
||||
list.Clear();
|
||||
SetAllDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9c4f3a01039fd4e7fbf771a65ede0069
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa9c09045961a4ea9a34a098f099f2a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,109 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public struct PointInfo
|
||||
{
|
||||
public Vector3 position;
|
||||
public bool isIgnoreBreak;
|
||||
|
||||
public PointInfo(Vector3 pos, bool ignore)
|
||||
{
|
||||
this.position = pos;
|
||||
this.isIgnoreBreak = ignore;
|
||||
}
|
||||
}
|
||||
|
||||
public class SerieContext
|
||||
{
|
||||
/// <summary>
|
||||
/// 鼠标是否进入serie
|
||||
/// </summary>
|
||||
public bool pointerEnter;
|
||||
/// <summary>
|
||||
/// 鼠标当前指示的数据项索引(单个)
|
||||
/// </summary>
|
||||
public int pointerItemDataIndex = -1;
|
||||
/// <summary>
|
||||
/// 鼠标所在轴线上的数据项索引(可能有多个)
|
||||
/// </summary>
|
||||
public List<int> pointerAxisDataIndexs = new List<int>();
|
||||
public bool isTriggerByAxis = false;
|
||||
|
||||
/// <summary>
|
||||
/// 中心点
|
||||
/// </summary>
|
||||
public Vector3 center;
|
||||
/// <summary>
|
||||
/// 线段终点
|
||||
/// </summary>
|
||||
public Vector3 lineEndPostion;
|
||||
public double lineEndValue;
|
||||
/// <summary>
|
||||
/// 内半径
|
||||
/// </summary>
|
||||
public float insideRadius;
|
||||
/// <summary>
|
||||
/// 外半径
|
||||
/// </summary>
|
||||
public float outsideRadius;
|
||||
public float startAngle;
|
||||
/// <summary>
|
||||
/// 最大值
|
||||
/// </summary>
|
||||
public double dataMax;
|
||||
/// <summary>
|
||||
/// 最小值
|
||||
/// </summary>
|
||||
public double dataMin;
|
||||
public double checkValue;
|
||||
/// <summary>
|
||||
/// 左下角坐标X
|
||||
/// </summary>
|
||||
public float x;
|
||||
/// <summary>
|
||||
/// 左下角坐标Y
|
||||
/// </summary>
|
||||
public float y;
|
||||
/// <summary>
|
||||
/// 宽
|
||||
/// </summary>
|
||||
public float width;
|
||||
/// <summary>
|
||||
/// 高
|
||||
/// </summary>
|
||||
public float height;
|
||||
/// <summary>
|
||||
/// 矩形区域
|
||||
/// </summary>
|
||||
public Rect rect;
|
||||
/// <summary>
|
||||
/// 绘制顶点数
|
||||
/// </summary>
|
||||
public int vertCount;
|
||||
/// <summary>
|
||||
/// 数据对应的位置坐标。
|
||||
/// </summary>
|
||||
public List<Vector3> dataPoints = new List<Vector3>();
|
||||
/// <summary>
|
||||
/// 数据对应的位置坐标是否忽略(忽略时连线是透明的),dataIgnore 和 dataPoints 一一对应。
|
||||
/// </summary>
|
||||
public List<bool> dataIgnores = new List<bool>();
|
||||
/// <summary>
|
||||
/// 排序后的数据
|
||||
/// </summary>
|
||||
public List<SerieData> sortedData = new List<SerieData>();
|
||||
public List<SerieData> rootData = new List<SerieData>();
|
||||
/// <summary>
|
||||
/// theme的颜色索引
|
||||
/// </summary>
|
||||
public int colorIndex;
|
||||
/// <summary>
|
||||
/// 绘制点
|
||||
/// </summary>
|
||||
public List<PointInfo> drawPoints = new List<PointInfo>();
|
||||
public SerieParams param = new SerieParams();
|
||||
public ChartLabel titleObject { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 87f333572a32a4cb39aa0a05ed97983a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,565 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// A data item of serie.
|
||||
/// |系列中的一个数据项。可存储数据名和1-n维个数据。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class SerieData : ChildComponent
|
||||
{
|
||||
public static List<string> extraFieldList = new List<string>()
|
||||
{
|
||||
"m_Id",
|
||||
"m_ParentId",
|
||||
"m_Ignore",
|
||||
"m_Selected",
|
||||
"m_Radius"
|
||||
};
|
||||
public static Dictionary<Type, string> extraComponentMap = new Dictionary<Type, string>
|
||||
{ { typeof(ItemStyle), "m_ItemStyles" },
|
||||
{ typeof(LabelStyle), "m_Labels" },
|
||||
{ typeof(LabelLine), "m_LabelLines" },
|
||||
{ typeof(SerieSymbol), "m_Symbols" },
|
||||
{ typeof(LineStyle), "m_LineStyles" },
|
||||
{ typeof(AreaStyle), "m_AreaStyles" },
|
||||
{ typeof(TitleStyle), "m_TitleStyles" },
|
||||
{ typeof(EmphasisItemStyle), "m_EmphasisItemStyles" },
|
||||
{ typeof(EmphasisLabelStyle), "m_EmphasisLabels" },
|
||||
{ typeof(EmphasisLabelLine), "m_EmphasisLabelLines" },
|
||||
};
|
||||
|
||||
[SerializeField] private int m_Index;
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private string m_Id;
|
||||
[SerializeField] private string m_ParentId;
|
||||
[SerializeField] private bool m_Ignore;
|
||||
[SerializeField] private bool m_Selected;
|
||||
[SerializeField] private float m_Radius;
|
||||
[SerializeField][IgnoreDoc] private List<ItemStyle> m_ItemStyles = new List<ItemStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<LabelStyle> m_Labels = new List<LabelStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<LabelLine> m_LabelLines = new List<LabelLine>();
|
||||
[SerializeField][IgnoreDoc] private List<SerieSymbol> m_Symbols = new List<SerieSymbol>();
|
||||
[SerializeField][IgnoreDoc] private List<LineStyle> m_LineStyles = new List<LineStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<AreaStyle> m_AreaStyles = new List<AreaStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<TitleStyle> m_TitleStyles = new List<TitleStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<EmphasisItemStyle> m_EmphasisItemStyles = new List<EmphasisItemStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<EmphasisLabelStyle> m_EmphasisLabels = new List<EmphasisLabelStyle>();
|
||||
[SerializeField][IgnoreDoc] private List<EmphasisLabelLine> m_EmphasisLabelLines = new List<EmphasisLabelLine>();
|
||||
[SerializeField] private List<double> m_Data = new List<double>();
|
||||
|
||||
[NonSerialized] public SerieDataContext context = new SerieDataContext();
|
||||
[NonSerialized] public InteractData interact = new InteractData();
|
||||
|
||||
public ChartLabel labelObject { get; set; }
|
||||
public ChartLabel titleObject { get; set; }
|
||||
|
||||
private bool m_Show = true;
|
||||
/// <summary>
|
||||
/// the index of SerieData.
|
||||
/// |数据项索引。
|
||||
/// </summary>
|
||||
public override int index { get { return m_Index; } set { m_Index = value; } }
|
||||
/// <summary>
|
||||
/// the name of data item.
|
||||
/// |数据项名称。
|
||||
/// </summary>
|
||||
public string name { get { return m_Name; } set { m_Name = value; } }
|
||||
/// <summary>
|
||||
/// the id of data.
|
||||
/// |数据项的唯一id。唯一id不是必须设置的。
|
||||
/// </summary>
|
||||
public string id { get { return m_Id; } set { m_Id = value; } }
|
||||
/// <summary>
|
||||
/// the id of parent SerieData.
|
||||
/// |父节点id。父节点id不是必须设置的。
|
||||
/// </summary>
|
||||
public string parentId { get { return m_ParentId; } set { m_ParentId = value; } }
|
||||
/// <summary>
|
||||
/// 是否忽略数据。当为 true 时,数据不进行绘制。
|
||||
/// </summary>
|
||||
public bool ignore
|
||||
{
|
||||
get { return m_Ignore; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Ignore, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 自定义半径。可用在饼图中自定义某个数据项的半径。
|
||||
/// </summary>
|
||||
public float radius { get { return m_Radius; } set { m_Radius = value; } }
|
||||
/// <summary>
|
||||
/// Whether the data item is selected.
|
||||
/// |该数据项是否被选中。
|
||||
/// </summary>
|
||||
public bool selected { get { return m_Selected; } set { m_Selected = value; } }
|
||||
/// <summary>
|
||||
/// 数据项图例名称。当数据项名称不为空时,图例名称即为系列名称;反之则为索引index。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public string legendName { get { return string.IsNullOrEmpty(name) ? ChartCached.IntToStr(index) : name; } }
|
||||
|
||||
/// <summary>
|
||||
/// 单个数据项的标签设置。
|
||||
/// </summary>
|
||||
public LabelStyle labelStyle { get { return m_Labels.Count > 0 ? m_Labels[0] : null; } }
|
||||
public LabelLine labelLine { get { return m_LabelLines.Count > 0 ? m_LabelLines[0] : null; } }
|
||||
/// <summary>
|
||||
/// 单个数据项的样式设置。
|
||||
/// </summary>
|
||||
public ItemStyle itemStyle { get { return m_ItemStyles.Count > 0 ? m_ItemStyles[0] : null; } }
|
||||
/// <summary>
|
||||
/// 单个数据项的标记设置。
|
||||
/// </summary>
|
||||
public SerieSymbol symbol { get { return m_Symbols.Count > 0 ? m_Symbols[0] : null; } }
|
||||
public LineStyle lineStyle { get { return m_LineStyles.Count > 0 ? m_LineStyles[0] : null; } }
|
||||
public AreaStyle areaStyle { get { return m_AreaStyles.Count > 0 ? m_AreaStyles[0] : null; } }
|
||||
public TitleStyle titleStyle { get { return m_TitleStyles.Count > 0 ? m_TitleStyles[0] : null; } }
|
||||
/// <summary>
|
||||
/// 高亮的图形样式
|
||||
/// </summary>
|
||||
public EmphasisItemStyle emphasisItemStyle { get { return m_EmphasisItemStyles.Count > 0 ? m_EmphasisItemStyles[0] : null; } }
|
||||
/// <summary>
|
||||
/// 高亮时的标签样式
|
||||
/// </summary>
|
||||
public EmphasisLabelStyle emphasisLabel { get { return m_EmphasisLabels.Count > 0 ? m_EmphasisLabels[0] : null; } }
|
||||
/// <summary>
|
||||
/// 高亮时的标签引导线样式
|
||||
/// </summary>
|
||||
public EmphasisLabelLine emphasisLabelLine { get { return m_EmphasisLabelLines.Count > 0 ? m_EmphasisLabelLines[0] : null; } }
|
||||
|
||||
/// <summary>
|
||||
/// An arbitrary dimension data list of data item.
|
||||
/// |可指定任意维数的数值列表。
|
||||
/// </summary>
|
||||
public List<double> data { get { return m_Data; } set { m_Data = value; } }
|
||||
/// <summary>
|
||||
/// [default:true] Whether the data item is showed.
|
||||
/// |该数据项是否要显示。
|
||||
/// </summary>
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
|
||||
private List<double> m_PreviousData = new List<double>();
|
||||
private List<float> m_DataUpdateTime = new List<float>();
|
||||
private List<bool> m_DataUpdateFlag = new List<bool>();
|
||||
private List<Vector2> m_PolygonPoints = new List<Vector2>();
|
||||
|
||||
public override bool vertsDirty
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_VertsDirty ||
|
||||
(labelLine != null && labelLine.vertsDirty) ||
|
||||
(itemStyle != null && itemStyle.vertsDirty) ||
|
||||
(symbol != null && symbol.vertsDirty) ||
|
||||
(lineStyle != null && lineStyle.vertsDirty) ||
|
||||
(areaStyle != null && areaStyle.vertsDirty) ||
|
||||
(emphasisItemStyle != null && emphasisItemStyle.vertsDirty);
|
||||
}
|
||||
}
|
||||
public override bool componentDirty
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ComponentDirty ||
|
||||
(labelStyle != null && labelStyle.componentDirty) ||
|
||||
(labelLine != null && labelLine.componentDirty) ||
|
||||
(titleStyle != null && titleStyle.componentDirty) ||
|
||||
(emphasisLabel != null && emphasisLabel.componentDirty) ||
|
||||
(emphasisLabelLine != null && emphasisLabelLine.componentDirty);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearVerticesDirty()
|
||||
{
|
||||
base.ClearVerticesDirty();
|
||||
if (labelLine != null) labelLine.ClearVerticesDirty();
|
||||
if (itemStyle != null) itemStyle.ClearVerticesDirty();
|
||||
if (lineStyle != null) lineStyle.ClearVerticesDirty();
|
||||
if (areaStyle != null) areaStyle.ClearVerticesDirty();
|
||||
if (symbol != null) symbol.ClearVerticesDirty();
|
||||
if (emphasisItemStyle != null) emphasisItemStyle.ClearVerticesDirty();
|
||||
}
|
||||
|
||||
public override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
if (labelLine != null) labelLine.ClearComponentDirty();
|
||||
if (itemStyle != null) itemStyle.ClearComponentDirty();
|
||||
if (lineStyle != null) lineStyle.ClearComponentDirty();
|
||||
if (areaStyle != null) areaStyle.ClearComponentDirty();
|
||||
if (symbol != null) symbol.ClearComponentDirty();
|
||||
if (emphasisLabel != null) emphasisLabel.ClearComponentDirty();
|
||||
if (emphasisLabelLine != null) emphasisLabelLine.ClearComponentDirty();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
index = 0;
|
||||
m_Id = null;
|
||||
m_ParentId = null;
|
||||
labelObject = null;
|
||||
m_Name = string.Empty;
|
||||
m_Show = true;
|
||||
context.Reset();
|
||||
interact.Reset();
|
||||
m_Data.Clear();
|
||||
m_PreviousData.Clear();
|
||||
m_DataUpdateTime.Clear();
|
||||
m_DataUpdateFlag.Clear();
|
||||
m_Labels.Clear();
|
||||
m_LabelLines.Clear();
|
||||
m_ItemStyles.Clear();
|
||||
m_Symbols.Clear();
|
||||
m_LineStyles.Clear();
|
||||
m_AreaStyles.Clear();
|
||||
m_TitleStyles.Clear();
|
||||
m_EmphasisItemStyles.Clear();
|
||||
m_EmphasisLabels.Clear();
|
||||
m_EmphasisLabelLines.Clear();
|
||||
}
|
||||
|
||||
public T GetOrAddComponent<T>() where T : ChildComponent, ISerieDataComponent
|
||||
{
|
||||
return GetOrAddComponent(typeof(T)) as T;
|
||||
}
|
||||
|
||||
public ISerieDataComponent GetOrAddComponent(Type type)
|
||||
{
|
||||
if (type == typeof(ItemStyle))
|
||||
{
|
||||
if (m_ItemStyles.Count == 0)
|
||||
m_ItemStyles.Add(new ItemStyle() { show = true });
|
||||
return m_ItemStyles[0];
|
||||
}
|
||||
else if (type == typeof(LabelStyle))
|
||||
{
|
||||
if (m_Labels.Count == 0)
|
||||
m_Labels.Add(new LabelStyle() { show = true });
|
||||
return m_Labels[0];
|
||||
}
|
||||
else if (type == typeof(LabelLine))
|
||||
{
|
||||
if (m_LabelLines.Count == 0)
|
||||
m_LabelLines.Add(new LabelLine() { show = true });
|
||||
return m_LabelLines[0];
|
||||
}
|
||||
else if (type == typeof(EmphasisItemStyle))
|
||||
{
|
||||
if (m_EmphasisItemStyles.Count == 0)
|
||||
m_EmphasisItemStyles.Add(new EmphasisItemStyle() { show = true });
|
||||
return m_EmphasisItemStyles[0];
|
||||
}
|
||||
else if (type == typeof(EmphasisLabelStyle))
|
||||
{
|
||||
if (m_EmphasisLabels.Count == 0)
|
||||
m_EmphasisLabels.Add(new EmphasisLabelStyle() { show = true });
|
||||
return m_EmphasisLabels[0];
|
||||
}
|
||||
else if (type == typeof(EmphasisLabelLine))
|
||||
{
|
||||
if (m_EmphasisLabelLines.Count == 0)
|
||||
m_EmphasisLabelLines.Add(new EmphasisLabelLine() { show = true });
|
||||
return m_EmphasisLabelLines[0];
|
||||
}
|
||||
else if (type == typeof(SerieSymbol))
|
||||
{
|
||||
if (m_Symbols.Count == 0)
|
||||
m_Symbols.Add(new SerieSymbol() { show = true });
|
||||
return m_Symbols[0];
|
||||
}
|
||||
else if (type == typeof(LineStyle))
|
||||
{
|
||||
if (m_LineStyles.Count == 0)
|
||||
m_LineStyles.Add(new LineStyle() { show = true });
|
||||
return m_LineStyles[0];
|
||||
}
|
||||
else if (type == typeof(AreaStyle))
|
||||
{
|
||||
if (m_AreaStyles.Count == 0)
|
||||
m_AreaStyles.Add(new AreaStyle() { show = true });
|
||||
return m_AreaStyles[0];
|
||||
}
|
||||
else if (type == typeof(TitleStyle))
|
||||
{
|
||||
if (m_TitleStyles.Count == 0)
|
||||
m_TitleStyles.Add(new TitleStyle() { show = true });
|
||||
return m_TitleStyles[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new System.Exception("SerieData not support component:" + type);
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAllComponent()
|
||||
{
|
||||
m_ItemStyles.Clear();
|
||||
m_Labels.Clear();
|
||||
m_LabelLines.Clear();
|
||||
m_Symbols.Clear();
|
||||
m_EmphasisItemStyles.Clear();
|
||||
m_EmphasisLabels.Clear();
|
||||
m_EmphasisLabelLines.Clear();
|
||||
m_LineStyles.Clear();
|
||||
m_AreaStyles.Clear();
|
||||
m_TitleStyles.Clear();
|
||||
}
|
||||
|
||||
public void RemoveComponent<T>() where T : ISerieDataComponent
|
||||
{
|
||||
RemoveComponent(typeof(T));
|
||||
}
|
||||
|
||||
public void RemoveComponent(Type type)
|
||||
{
|
||||
if (type == typeof(ItemStyle))
|
||||
m_ItemStyles.Clear();
|
||||
else if (type == typeof(LabelStyle))
|
||||
m_Labels.Clear();
|
||||
else if (type == typeof(LabelLine))
|
||||
m_LabelLines.Clear();
|
||||
else if (type == typeof(EmphasisItemStyle))
|
||||
m_EmphasisItemStyles.Clear();
|
||||
else if (type == typeof(EmphasisLabelStyle))
|
||||
m_EmphasisLabels.Clear();
|
||||
else if (type == typeof(EmphasisLabelLine))
|
||||
m_EmphasisLabelLines.Clear();
|
||||
else if (type == typeof(SerieSymbol))
|
||||
m_Symbols.Clear();
|
||||
else if (type == typeof(LineStyle))
|
||||
m_LineStyles.Clear();
|
||||
else if (type == typeof(AreaStyle))
|
||||
m_AreaStyles.Clear();
|
||||
else if (type == typeof(TitleStyle))
|
||||
m_TitleStyles.Clear();
|
||||
else
|
||||
throw new System.Exception("SerieData not support component:" + type);
|
||||
}
|
||||
public double GetData(int index, bool inverse = false)
|
||||
{
|
||||
if (index >= 0 && index < m_Data.Count)
|
||||
{
|
||||
return inverse ? -m_Data[index] : m_Data[index];
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public double GetData(int index, double min, double max)
|
||||
{
|
||||
if (index >= 0 && index < m_Data.Count)
|
||||
{
|
||||
var value = m_Data[index];
|
||||
if (value < min) return min;
|
||||
else if (value > max) return max;
|
||||
else return value;
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public double GetPreviousData(int index, bool inverse = false)
|
||||
{
|
||||
if (index >= 0 && index < m_PreviousData.Count)
|
||||
{
|
||||
return inverse ? -m_PreviousData[index] : m_PreviousData[index];
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public double GetFirstData(float animationDuration = 500f)
|
||||
{
|
||||
if (m_Data.Count > 0) return GetCurrData(0, animationDuration);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double GetLastData()
|
||||
{
|
||||
if (m_Data.Count > 0) return m_Data[m_Data.Count - 1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double GetCurrData(int index, float animationDuration = 500f, bool inverse = false)
|
||||
{
|
||||
return GetCurrData(index, animationDuration, inverse, 0, 0);
|
||||
}
|
||||
|
||||
public double GetCurrData(int index, float animationDuration, bool inverse, double min, double max)
|
||||
{
|
||||
if (index < m_DataUpdateFlag.Count && m_DataUpdateFlag[index] && animationDuration > 0)
|
||||
{
|
||||
var time = Time.time - m_DataUpdateTime[index];
|
||||
var total = animationDuration / 1000;
|
||||
|
||||
var rate = time / total;
|
||||
if (rate > 1) rate = 1;
|
||||
if (rate < 1)
|
||||
{
|
||||
CheckLastData();
|
||||
var curr = MathUtil.Lerp(GetPreviousData(index), GetData(index), rate);
|
||||
if (min != 0 || max != 0)
|
||||
{
|
||||
if (inverse)
|
||||
{
|
||||
var temp = min;
|
||||
min = -max;
|
||||
max = -temp;
|
||||
}
|
||||
var pre = m_PreviousData[index];
|
||||
if (pre < min)
|
||||
{
|
||||
m_PreviousData[index] = min;
|
||||
curr = min;
|
||||
}
|
||||
else if (pre > max)
|
||||
{
|
||||
m_PreviousData[index] = max;
|
||||
curr = max;
|
||||
}
|
||||
}
|
||||
curr = inverse ? -curr : curr;
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DataUpdateFlag[index] = false;
|
||||
return GetData(index, inverse);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetData(index, inverse);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the maxinum value.
|
||||
/// |最大值。
|
||||
/// </summary>
|
||||
public double GetMaxData(bool inverse = false)
|
||||
{
|
||||
if (m_Data.Count == 0) return 0;
|
||||
var temp = double.MinValue;
|
||||
for (int i = 0; i < m_Data.Count; i++)
|
||||
{
|
||||
var value = GetData(i, inverse);
|
||||
if (value > temp) temp = value;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the mininum value.
|
||||
/// |最小值。
|
||||
/// </summary>
|
||||
public double GetMinData(bool inverse = false)
|
||||
{
|
||||
if (m_Data.Count == 0) return 0;
|
||||
var temp = double.MaxValue;
|
||||
for (int i = 0; i < m_Data.Count; i++)
|
||||
{
|
||||
var value = GetData(i, inverse);
|
||||
if (value < temp) temp = value;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
public double GetTotalData()
|
||||
{
|
||||
var total = 0d;
|
||||
foreach (var value in m_Data)
|
||||
total += value;
|
||||
return total;
|
||||
}
|
||||
|
||||
public bool UpdateData(int dimension, double value, bool updateAnimation, float animationDuration = 500f)
|
||||
{
|
||||
if (dimension >= 0 && dimension < data.Count)
|
||||
{
|
||||
CheckLastData();
|
||||
m_PreviousData[dimension] = GetCurrData(dimension, animationDuration);
|
||||
//m_PreviousData[dimension] = data[dimension];;
|
||||
m_DataUpdateTime[dimension] = Time.time;
|
||||
m_DataUpdateFlag[dimension] = updateAnimation;
|
||||
data[dimension] = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool UpdateData(int dimension, double value)
|
||||
{
|
||||
if (dimension >= 0 && dimension < data.Count)
|
||||
{
|
||||
data[dimension] = value;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CheckLastData()
|
||||
{
|
||||
if (m_PreviousData.Count != m_Data.Count)
|
||||
{
|
||||
m_PreviousData.Clear();
|
||||
m_DataUpdateTime.Clear();
|
||||
m_DataUpdateFlag.Clear();
|
||||
for (int i = 0; i < m_Data.Count; i++)
|
||||
{
|
||||
m_PreviousData.Add(m_Data[i]);
|
||||
m_DataUpdateTime.Add(Time.time);
|
||||
m_DataUpdateFlag.Add(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDataChanged()
|
||||
{
|
||||
for (int i = 0; i < m_DataUpdateFlag.Count; i++)
|
||||
if (m_DataUpdateFlag[i]) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public float GetLabelWidth()
|
||||
{
|
||||
if (labelObject != null) return labelObject.GetTextWidth();
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public float GetLabelHeight()
|
||||
{
|
||||
if (labelObject != null) return labelObject.GetTextHeight();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void SetLabelActive(bool flag)
|
||||
{
|
||||
if (labelObject != null) labelObject.SetActive(flag);
|
||||
}
|
||||
public void SetIconActive(bool flag)
|
||||
{
|
||||
if (labelObject != null) labelObject.SetActive(flag);
|
||||
}
|
||||
|
||||
public void SetPolygon(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4)
|
||||
{
|
||||
m_PolygonPoints.Clear();
|
||||
m_PolygonPoints.Add(p1);
|
||||
m_PolygonPoints.Add(p2);
|
||||
m_PolygonPoints.Add(p3);
|
||||
m_PolygonPoints.Add(p4);
|
||||
}
|
||||
public void SetPolygon(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, Vector2 p5)
|
||||
{
|
||||
SetPolygon(p1, p2, p3, p4);
|
||||
m_PolygonPoints.Add(p5);
|
||||
}
|
||||
|
||||
public bool IsInPolygon(Vector2 p)
|
||||
{
|
||||
return UGLHelper.IsPointInPolygon(p, m_PolygonPoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbf44007311214228976678a623479b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public class SerieDataContext
|
||||
{
|
||||
public Vector3 labelPosition;
|
||||
/// <summary>
|
||||
/// 开始角度
|
||||
/// </summary>
|
||||
public float startAngle;
|
||||
/// <summary>
|
||||
/// 结束角度
|
||||
/// </summary>
|
||||
public float toAngle;
|
||||
/// <summary>
|
||||
/// 一半时的角度
|
||||
/// </summary>
|
||||
public float halfAngle;
|
||||
/// <summary>
|
||||
/// 当前角度
|
||||
/// </summary>
|
||||
public float currentAngle;
|
||||
/// <summary>
|
||||
/// 饼图数据项的内半径
|
||||
/// </summary>
|
||||
public float insideRadius;
|
||||
/// <summary>
|
||||
/// 饼图数据项的偏移半径
|
||||
/// </summary>
|
||||
public float offsetRadius;
|
||||
public float outsideRadius;
|
||||
public Vector3 position;
|
||||
public List<Vector3> dataPoints = new List<Vector3>();
|
||||
public List<ChartLabel> dataLabels = new List<ChartLabel>();
|
||||
public List<SerieData> children = new List<SerieData>();
|
||||
/// <summary>
|
||||
/// 绘制区域。
|
||||
/// </summary>
|
||||
public Rect rect;
|
||||
public Rect backgroundRect;
|
||||
public Rect subRect;
|
||||
public int level;
|
||||
public SerieData parent;
|
||||
public Color32 color;
|
||||
public double area;
|
||||
public float angle;
|
||||
public Vector3 offsetCenter;
|
||||
public Vector3 areaCenter;
|
||||
public float stackHeight;
|
||||
public bool isClip;
|
||||
public bool canShowLabel = true;
|
||||
public Image symbol;
|
||||
/// <summary>
|
||||
/// Whether the data item is highlighted.
|
||||
/// |该数据项是否被高亮,一般由鼠标悬停或图例悬停触发高亮。
|
||||
/// </summary>
|
||||
public bool highlight
|
||||
{
|
||||
get { return m_Highligth; }
|
||||
set
|
||||
{
|
||||
m_Highligth = value;
|
||||
}
|
||||
}
|
||||
private bool m_Highligth;
|
||||
public bool selected;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
canShowLabel = true;
|
||||
highlight = false;
|
||||
parent = null;
|
||||
symbol = null;
|
||||
rect = Rect.zero;
|
||||
subRect = Rect.zero;
|
||||
children.Clear();
|
||||
dataPoints.Clear();
|
||||
dataLabels.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fa67a86e80b4456cbe76ef4b330f3fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,579 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public abstract class SerieHandler
|
||||
{
|
||||
public BaseChart chart { get; internal set; }
|
||||
public SerieHandlerAttribute attribute { get; internal set; }
|
||||
public virtual int defaultDimension { get; internal set; }
|
||||
|
||||
public virtual void InitComponent() { }
|
||||
public virtual void RemoveComponent() { }
|
||||
public virtual void CheckComponent(StringBuilder sb) { }
|
||||
public virtual void Update() { }
|
||||
public virtual void DrawBase(VertexHelper vh) { }
|
||||
public virtual void DrawSerie(VertexHelper vh) { }
|
||||
public virtual void DrawTop(VertexHelper vh) { }
|
||||
public virtual void OnPointerClick(PointerEventData eventData) { }
|
||||
public virtual void OnPointerDown(PointerEventData eventData) { }
|
||||
public virtual void OnPointerUp(PointerEventData eventData) { }
|
||||
public virtual void OnPointerEnter(PointerEventData eventData) { }
|
||||
public virtual void OnPointerExit(PointerEventData eventData) { }
|
||||
public virtual void OnDrag(PointerEventData eventData) { }
|
||||
public virtual void OnBeginDrag(PointerEventData eventData) { }
|
||||
public virtual void OnEndDrag(PointerEventData eventData) { }
|
||||
public virtual void OnScroll(PointerEventData eventData) { }
|
||||
public virtual void RefreshLabelNextFrame() { }
|
||||
public virtual void RefreshLabelInternal() { }
|
||||
public virtual void UpdateTooltipSerieParams(int dataIndex, bool showCategory,
|
||||
string category, string marker,
|
||||
string itemFormatter, string numericFormatter,
|
||||
ref List<SerieParams> paramList, ref string title) { }
|
||||
public virtual void OnLegendButtonClick(int index, string legendName, bool show) { }
|
||||
public virtual void OnLegendButtonEnter(int index, string legendName) { }
|
||||
public virtual void OnLegendButtonExit(int index, string legendName) { }
|
||||
internal abstract void SetSerie(Serie serie);
|
||||
}
|
||||
|
||||
public abstract class SerieHandler<T> : SerieHandler where T : Serie
|
||||
{
|
||||
private static readonly string s_SerieLabelObjectName = "label";
|
||||
private static readonly string s_SerieTitleObjectName = "title";
|
||||
private static readonly string s_SerieRootObjectName = "serie";
|
||||
private static readonly string s_SerieEndLabelObjectName = "end_label";
|
||||
protected GameObject m_SerieRoot;
|
||||
protected GameObject m_SerieLabelRoot;
|
||||
protected bool m_InitedLabel;
|
||||
protected bool m_NeedInitComponent;
|
||||
protected bool m_RefreshLabel;
|
||||
protected bool m_LastCheckContextFlag = false;
|
||||
protected bool m_LegendEnter = false;
|
||||
protected int m_LegendEnterIndex;
|
||||
protected ChartLabel m_EndLabel;
|
||||
|
||||
public T serie { get; internal set; }
|
||||
public GameObject labelObject { get { return m_SerieLabelRoot; } }
|
||||
|
||||
internal override void SetSerie(Serie serie)
|
||||
{
|
||||
this.serie = (T) serie;
|
||||
this.serie.context.param.serieType = typeof(T);
|
||||
m_NeedInitComponent = true;
|
||||
AnimationStyleHelper.UpdateSerieAnimation(serie);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (m_NeedInitComponent)
|
||||
{
|
||||
m_NeedInitComponent = false;
|
||||
InitComponent();
|
||||
}
|
||||
if (m_RefreshLabel)
|
||||
{
|
||||
m_RefreshLabel = false;
|
||||
RefreshLabelInternal();
|
||||
RefreshEndLabelInternal();
|
||||
}
|
||||
if (serie.dataDirty)
|
||||
{
|
||||
SeriesHelper.UpdateSerieNameList(chart, ref chart.m_LegendRealShowName);
|
||||
serie.OnDataUpdate();
|
||||
serie.dataDirty = false;
|
||||
}
|
||||
if (serie.label != null && (serie.labelDirty || serie.label.componentDirty))
|
||||
{
|
||||
serie.labelDirty = false;
|
||||
serie.label.ClearComponentDirty();
|
||||
InitSerieLabel();
|
||||
InitSerieEndLabel();
|
||||
}
|
||||
if (serie.endLabel != null && serie.endLabel.componentDirty)
|
||||
{
|
||||
serie.endLabel.ClearComponentDirty();
|
||||
InitSerieEndLabel();
|
||||
}
|
||||
if (serie.titleStyle != null && (serie.titleDirty || serie.titleStyle.componentDirty))
|
||||
{
|
||||
serie.titleDirty = false;
|
||||
serie.titleStyle.ClearComponentDirty();
|
||||
InitSerieTitle();
|
||||
}
|
||||
if (serie.nameDirty)
|
||||
{
|
||||
foreach (var component in chart.components)
|
||||
{
|
||||
if (component is Legend)
|
||||
component.SetAllDirty();
|
||||
}
|
||||
chart.RefreshChart();
|
||||
serie.ClearSerieNameDirty();
|
||||
}
|
||||
if (serie.vertsDirty)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
serie.ResetInteract();
|
||||
serie.ClearVerticesDirty();
|
||||
}
|
||||
}
|
||||
|
||||
public override void RefreshLabelNextFrame()
|
||||
{
|
||||
m_RefreshLabel = true;
|
||||
}
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
m_InitedLabel = false;
|
||||
InitRoot();
|
||||
InitSerieLabel();
|
||||
InitSerieTitle();
|
||||
InitSerieEndLabel();
|
||||
}
|
||||
|
||||
public override void RemoveComponent()
|
||||
{
|
||||
ChartHelper.SetActive(m_SerieRoot, false);
|
||||
}
|
||||
|
||||
public override void OnLegendButtonClick(int index, string legendName, bool show)
|
||||
{
|
||||
if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName))
|
||||
{
|
||||
LegendHelper.CheckDataShow(serie, legendName, show);
|
||||
chart.UpdateLegendColor(legendName, show);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
else if (serie.IsLegendName(legendName))
|
||||
{
|
||||
chart.SetSerieActive(serie, show);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLegendButtonEnter(int index, string legendName)
|
||||
{
|
||||
if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName))
|
||||
{
|
||||
LegendHelper.CheckDataHighlighted(serie, legendName, true);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
else if (serie.IsLegendName(legendName))
|
||||
{
|
||||
m_LegendEnter = true;
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnLegendButtonExit(int index, string legendName)
|
||||
{
|
||||
if (serie.useDataNameForColor && serie.IsSerieDataLegendName(legendName))
|
||||
{
|
||||
LegendHelper.CheckDataHighlighted(serie, legendName, false);
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
else if (serie.IsLegendName(legendName))
|
||||
{
|
||||
m_LegendEnter = false;
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitRoot()
|
||||
{
|
||||
if (m_SerieRoot != null)
|
||||
{
|
||||
var rect = ChartHelper.GetOrAddComponent<RectTransform>(m_SerieRoot);
|
||||
rect.localPosition = Vector3.zero;
|
||||
rect.sizeDelta = chart.chartSizeDelta;
|
||||
rect.anchorMin = chart.chartMinAnchor;
|
||||
rect.anchorMax = chart.chartMaxAnchor;
|
||||
rect.pivot = chart.chartPivot;
|
||||
return;
|
||||
}
|
||||
var objName = s_SerieRootObjectName + "_" + serie.index;
|
||||
m_SerieRoot = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
m_SerieRoot.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.SetActive(m_SerieRoot, true);
|
||||
ChartHelper.HideAllObject(m_SerieRoot);
|
||||
}
|
||||
|
||||
private void InitSerieLabel()
|
||||
{
|
||||
InitRoot();
|
||||
m_SerieLabelRoot = ChartHelper.AddObject(s_SerieLabelObjectName, m_SerieRoot.transform,
|
||||
chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
m_SerieLabelRoot.hideFlags = chart.chartHideFlags;
|
||||
SerieLabelPool.ReleaseAll(m_SerieLabelRoot.transform);
|
||||
//ChartHelper.DestroyAllChildren(m_SerieLabelRoot.transform);
|
||||
int count = 0;
|
||||
SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
var serieData = serie.data[j];
|
||||
serieData.index = count;
|
||||
serieData.labelObject = null;
|
||||
if (AddSerieLabel(m_SerieLabelRoot, serieData, ref count))
|
||||
{
|
||||
m_InitedLabel = true;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
RefreshLabelInternal();
|
||||
}
|
||||
|
||||
protected bool AddSerieLabel(GameObject serieLabelRoot, SerieData serieData, ref int count)
|
||||
{
|
||||
if (serieData == null)
|
||||
return false;
|
||||
if (serieLabelRoot == null)
|
||||
return false;
|
||||
if (serie.IsPerformanceMode())
|
||||
return false;
|
||||
|
||||
if (count == -1) count = serie.dataCount;
|
||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||
if (serieLabel == null)
|
||||
{
|
||||
serieLabel = SerieHelper.GetSerieEmphasisLabel(serie, serieData);
|
||||
if (serieLabel == null || !serieLabel.show)
|
||||
return false;
|
||||
}
|
||||
|
||||
var dataAutoColor = GetSerieDataAutoColor(serieData);
|
||||
serieData.context.dataLabels.Clear();
|
||||
if (serie.multiDimensionLabel)
|
||||
{
|
||||
for (int i = 0; i < serieData.data.Count; i++)
|
||||
{
|
||||
var textName = string.Format("{0}_{1}_{2}_{3}", s_SerieLabelObjectName, serie.index, serieData.index, i);
|
||||
var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common,
|
||||
"", dataAutoColor, TextAnchor.MiddleCenter);
|
||||
label.SetActive(serieLabel.show);
|
||||
serieData.context.dataLabels.Add(label);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var textName = ChartCached.GetSerieLabelName(s_SerieLabelObjectName, serie.index, serieData.index);
|
||||
var label = ChartHelper.AddChartLabel(textName, serieLabelRoot.transform, serieLabel, chart.theme.common,
|
||||
"", dataAutoColor, TextAnchor.MiddleCenter);
|
||||
label.SetActive(serieLabel.show);
|
||||
serieData.labelObject = label;
|
||||
}
|
||||
|
||||
if (serieData.context.children.Count > 0)
|
||||
{
|
||||
foreach (var childSerieData in serieData.context.children)
|
||||
{
|
||||
AddSerieLabel(serieLabelRoot, childSerieData, ref count);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void InitSerieEndLabel()
|
||||
{
|
||||
if (serie.endLabel == null)
|
||||
{
|
||||
if (m_EndLabel != null)
|
||||
{
|
||||
m_EndLabel.SetActive(false);
|
||||
m_EndLabel = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
InitRoot();
|
||||
var dataAutoColor = (Color) chart.GetLegendRealShowNameColor(serie.legendName);
|
||||
m_EndLabel = ChartHelper.AddChartLabel(s_SerieEndLabelObjectName, m_SerieRoot.transform, serie.endLabel,
|
||||
chart.theme.common, "", dataAutoColor, TextAnchor.MiddleLeft);
|
||||
m_EndLabel.SetActive(serie.endLabel.show);
|
||||
RefreshEndLabelInternal();
|
||||
}
|
||||
|
||||
private void InitSerieTitle()
|
||||
{
|
||||
InitRoot();
|
||||
var serieTitleRoot = ChartHelper.AddObject(s_SerieTitleObjectName, m_SerieRoot.transform,
|
||||
chart.chartMinAnchor, chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
serieTitleRoot.hideFlags = chart.chartHideFlags;
|
||||
SerieLabelPool.ReleaseAll(serieTitleRoot.transform);
|
||||
ChartHelper.RemoveComponent<Text>(serieTitleRoot);
|
||||
|
||||
SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
|
||||
if (serie.titleJustForSerie)
|
||||
{
|
||||
var titleStyle = SerieHelper.GetTitleStyle(serie, null);
|
||||
if (titleStyle != null)
|
||||
{
|
||||
var color = chart.GetItemColor(serie, null);
|
||||
var content = string.Empty;
|
||||
if (string.IsNullOrEmpty(titleStyle.formatter))
|
||||
{
|
||||
content = serie.serieName;
|
||||
}
|
||||
else
|
||||
{
|
||||
content = titleStyle.formatter;
|
||||
FormatterHelper.ReplaceContent(ref content, 0, titleStyle.numericFormatter, serie, chart);
|
||||
}
|
||||
var label = ChartHelper.AddChartLabel("title_" + 0, serieTitleRoot.transform, titleStyle, chart.theme.common,
|
||||
content, color, TextAnchor.MiddleCenter);
|
||||
serie.context.titleObject = label;
|
||||
label.SetActive(titleStyle.show);
|
||||
var labelPosition = GetSerieDataTitlePosition(null, titleStyle);
|
||||
var offset = titleStyle.GetOffset(serie.context.insideRadius);
|
||||
label.SetPosition(labelPosition + offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
var titleStyle = SerieHelper.GetTitleStyle(serie, serieData);
|
||||
if (titleStyle == null) continue;
|
||||
var color = chart.GetItemColor(serie, serieData);
|
||||
var content = string.Empty;
|
||||
if (string.IsNullOrEmpty(titleStyle.formatter))
|
||||
{
|
||||
content = serieData.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
content = titleStyle.formatter;
|
||||
FormatterHelper.ReplaceContent(ref content, 0, titleStyle.numericFormatter, serie, chart);
|
||||
}
|
||||
FormatterHelper.ReplaceContent(ref content, i, titleStyle.numericFormatter, serie, chart);
|
||||
var label = ChartHelper.AddChartLabel("title_" + i, serieTitleRoot.transform, titleStyle, chart.theme.common,
|
||||
content, color, TextAnchor.MiddleCenter);
|
||||
serieData.titleObject = label;
|
||||
label.SetActive(titleStyle.show);
|
||||
var labelPosition = GetSerieDataTitlePosition(serieData, titleStyle);
|
||||
var offset = titleStyle.GetOffset(serie.context.insideRadius);
|
||||
label.SetPosition(labelPosition + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void RefreshLabelInternal()
|
||||
{
|
||||
if (!m_InitedLabel)
|
||||
return;
|
||||
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.labelObject == null && serieData.context.dataLabels.Count <= 0)
|
||||
continue;
|
||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||
var emphasisLabel = SerieHelper.GetSerieEmphasisLabel(serie, serieData);
|
||||
var isHighlight = (serieData.context.highlight && emphasisLabel != null && emphasisLabel.show);
|
||||
var isIgnore = serie.IsIgnoreIndex(serieData.index, defaultDimension);
|
||||
var currLabel = isHighlight && emphasisLabel != null ? emphasisLabel : serieLabel;
|
||||
if (serie.show &&
|
||||
currLabel != null &&
|
||||
(currLabel.show || isHighlight) &&
|
||||
serieData.context.canShowLabel &&
|
||||
!isIgnore)
|
||||
{
|
||||
if (serie.multiDimensionLabel)
|
||||
{
|
||||
var total = serieData.GetTotalData();
|
||||
var color = chart.GetItemColor(serie, serieData);
|
||||
for (int i = 0; i < serieData.context.dataLabels.Count; i++)
|
||||
{
|
||||
if (i >= serieData.context.dataPoints.Count) continue;
|
||||
var labelObject = serieData.context.dataLabels[i];
|
||||
var value = serieData.GetCurrData(i, dataChangeDuration);
|
||||
var content = string.IsNullOrEmpty(currLabel.formatter) ?
|
||||
ChartCached.NumberToStr(value, serieLabel.numericFormatter) :
|
||||
SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
|
||||
currLabel, color);
|
||||
var offset = GetSerieDataLabelOffset(serieData, currLabel);
|
||||
labelObject.SetActive(!isIgnore);
|
||||
labelObject.SetText(content);
|
||||
labelObject.SetPosition(serieData.context.dataPoints[i] + offset);
|
||||
labelObject.UpdateIcon(currLabel.icon);
|
||||
if (currLabel.textStyle.autoColor)
|
||||
{
|
||||
var dataAutoColor = GetSerieDataAutoColor(serieData);
|
||||
if (!ChartHelper.IsClearColor(dataAutoColor))
|
||||
labelObject.SetTextColor(dataAutoColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var value = serieData.GetCurrData(defaultDimension, dataChangeDuration);
|
||||
var total = serie.GetDataTotal(defaultDimension, serieData);
|
||||
var color = chart.GetItemColor(serie, serieData);
|
||||
var content = string.IsNullOrEmpty(currLabel.formatter) ?
|
||||
ChartCached.NumberToStr(value, serieLabel.numericFormatter) :
|
||||
SerieLabelHelper.GetFormatterContent(serie, serieData, value, total,
|
||||
currLabel, color);
|
||||
serieData.SetLabelActive(!isIgnore);
|
||||
serieData.labelObject.UpdateIcon(currLabel.icon);
|
||||
serieData.labelObject.SetText(content);
|
||||
UpdateLabelPosition(serieData, currLabel);
|
||||
if (currLabel.textStyle.autoColor)
|
||||
{
|
||||
var dataAutoColor = GetSerieDataAutoColor(serieData);
|
||||
if (!ChartHelper.IsClearColor(dataAutoColor))
|
||||
serieData.labelObject.SetTextColor(dataAutoColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.SetLabelActive(false);
|
||||
foreach (var labelObject in serieData.context.dataLabels)
|
||||
{
|
||||
labelObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RefreshEndLabelInternal()
|
||||
{
|
||||
if (m_EndLabel == null)
|
||||
return;
|
||||
var endLabelStyle = serie.endLabel;
|
||||
if (endLabelStyle == null)
|
||||
return;
|
||||
var dataCount = serie.context.drawPoints.Count;
|
||||
var active = endLabelStyle.show && dataCount > 0;
|
||||
m_EndLabel.SetActive(active);
|
||||
if (active)
|
||||
{
|
||||
var value = serie.context.lineEndValue;
|
||||
var content = SerieLabelHelper.GetFormatterContent(serie, null, value, 0,
|
||||
endLabelStyle, Color.clear);
|
||||
m_EndLabel.SetText(content);
|
||||
m_EndLabel.SetPosition(serie.context.lineEndPostion + endLabelStyle.offset);
|
||||
}
|
||||
m_EndLabel.isAnimationEnd = serie.animation.IsFinish();
|
||||
}
|
||||
|
||||
private void UpdateLabelPosition(SerieData serieData, LabelStyle currLabel)
|
||||
{
|
||||
var labelPosition = GetSerieDataLabelPosition(serieData, currLabel);
|
||||
var offset = GetSerieDataLabelOffset(serieData, currLabel);
|
||||
serieData.labelObject.SetPosition(labelPosition + offset);
|
||||
}
|
||||
|
||||
public virtual Vector3 GetSerieDataLabelPosition(SerieData serieData, LabelStyle label)
|
||||
{
|
||||
return ChartHelper.IsZeroVector(serieData.context.labelPosition) ?
|
||||
serieData.context.position :
|
||||
serieData.context.labelPosition;
|
||||
}
|
||||
|
||||
public virtual Vector3 GetSerieDataLabelOffset(SerieData serieData, LabelStyle label)
|
||||
{
|
||||
return label.GetOffset(serie.context.insideRadius);
|
||||
}
|
||||
|
||||
public virtual Vector3 GetSerieDataTitlePosition(SerieData serieData, TitleStyle titleStyle)
|
||||
{
|
||||
return serieData.context.position;
|
||||
}
|
||||
|
||||
public virtual Color GetSerieDataAutoColor(SerieData serieData)
|
||||
{
|
||||
var colorIndex = serie.useDataNameForColor ? serieData.index : serie.index;
|
||||
return (Color) SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false, false);
|
||||
}
|
||||
|
||||
protected void UpdateCoordSerieParams(ref List<SerieParams> paramList, ref string title,
|
||||
int dataIndex, bool showCategory, string category, string marker,
|
||||
string itemFormatter, string numericFormatter)
|
||||
{
|
||||
if (dataIndex < 0)
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
if (TooltipHelper.IsIgnoreItemFormatter(itemFormatter))
|
||||
return;
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.category = category;
|
||||
param.dimension = 1;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = serieData.GetData(1);
|
||||
param.total = serie.yTotal;
|
||||
param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serie.context.colorIndex, false);
|
||||
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
param.itemFormatter = itemFormatter;
|
||||
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(showCategory ? category : serie.serieName);
|
||||
param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
|
||||
protected void UpdateItemSerieParams(ref List<SerieParams> paramList, ref string title,
|
||||
int dataIndex, string category, string marker,
|
||||
string itemFormatter, string numericFormatter, int dimension = 1)
|
||||
{
|
||||
if (dataIndex < 0)
|
||||
dataIndex = serie.context.pointerItemDataIndex;
|
||||
|
||||
if (dataIndex < 0)
|
||||
return;
|
||||
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData == null)
|
||||
return;
|
||||
|
||||
itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
|
||||
if (TooltipHelper.IsIgnoreItemFormatter(itemFormatter))
|
||||
return;
|
||||
|
||||
var colorIndex = chart.GetLegendRealShowNameIndex(serieData.name);
|
||||
|
||||
var param = serie.context.param;
|
||||
param.serieName = serie.serieName;
|
||||
param.serieIndex = serie.index;
|
||||
param.category = category;
|
||||
param.dimension = dimension;
|
||||
param.serieData = serieData;
|
||||
param.dataCount = serie.dataCount;
|
||||
param.value = serieData.GetData(param.dimension);
|
||||
param.total = SerieHelper.GetMaxData(serie, dimension);
|
||||
param.color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
|
||||
param.itemFormatter = itemFormatter;
|
||||
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
|
||||
param.columns.Clear();
|
||||
|
||||
param.columns.Add(param.marker);
|
||||
param.columns.Add(serieData.name);
|
||||
param.columns.Add(ChartCached.NumberToStr(param.value, param.numericFormatter));
|
||||
|
||||
paramList.Add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7f2bc0a6a80a84eae9c87842c954bc32
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public class SerieParams
|
||||
{
|
||||
public Type serieType;
|
||||
public int serieIndex;
|
||||
public string serieName;
|
||||
public string marker = "●";
|
||||
public string category;
|
||||
public int dimension;
|
||||
public SerieData serieData;
|
||||
public int dataCount;
|
||||
public double value;
|
||||
public double total;
|
||||
public Color32 color;
|
||||
public string itemFormatter;
|
||||
public string numericFormatter;
|
||||
public List<string> columns = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c46808eb5842743c5b02d03c4c503228
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user