mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-28 03:58:49 +00:00
3.0 - unitypackage
This commit is contained in:
39
Runtime/Serie/Line/Line.cs
Normal file
39
Runtime/Serie/Line/Line.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[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(IconStyle),
|
||||
typeof(Emphasis))]
|
||||
public class Line : Serie, INeedSerieContainer
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
public static void 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));
|
||||
}
|
||||
}
|
||||
|
||||
public static Line CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = serie.Clone<Line>();
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Serie/Line/Line.cs.meta
Normal file
11
Runtime/Serie/Line/Line.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 883eff3dc77e0439a80d257577790cbc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
447
Runtime/Serie/Line/LineHandler.GridCoord.cs
Normal file
447
Runtime/Serie/Line/LineHandler.GridCoord.cs
Normal file
@@ -0,0 +1,447 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// For grid coord
|
||||
/// </summary>
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed partial class LineHandler : SerieHandler<Line>
|
||||
{
|
||||
List<List<SerieData>> m_StackSerieData = new List<List<SerieData>>();
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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 isY = ComponentHelper.IsAnyCategoryOfYAxis(chart.components);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var serieData = serie.GetSerieData(i);
|
||||
if (serieData == null)
|
||||
continue;
|
||||
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
|
||||
if (!symbol.show || !symbol.ShowSymbol(i, count))
|
||||
continue;
|
||||
|
||||
var pos = serie.context.dataPoints[i];
|
||||
// if (serie.animation.CheckDetailBreak(pos, isY))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
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);
|
||||
var symbolBorder = SerieHelper.GetSymbolBorder(serie, serieData, theme, highlight);
|
||||
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
|
||||
|
||||
chart.DrawClipSymbol(vh, symbol.type, symbolSize, symbolBorder, pos,
|
||||
symbolColor, symbolToColor, symbolEmptyColor, 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, 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);
|
||||
}
|
||||
m_SerieGrid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
|
||||
if (axis == null)
|
||||
return;
|
||||
if (relativedAxis == null)
|
||||
return;
|
||||
if (m_SerieGrid == null)
|
||||
return;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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.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);
|
||||
|
||||
VisualMapHelper.AutoSetLineMinMax(visualMap, serie, isY, axis, relativedAxis);
|
||||
LineHelper.UpdateSerieDrawPoints(serie, chart.settings, chart.theme, lineWidth, isY);
|
||||
LineHelper.DrawSerieLineArea(vh, serie, lastSerie, chart.theme, 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;
|
||||
|
||||
if (isY)
|
||||
{
|
||||
var valueHig = AxisHelper.GetAxisValueLength(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
xPos = gridXY + valueHig;
|
||||
yPos = AxisHelper.GetAxisPosition(grid, axis, scaleWid, xValue);
|
||||
|
||||
if (isStack)
|
||||
{
|
||||
for (int n = 0; n < m_StackSerieData.Count - 1; n++)
|
||||
xPos += m_StackSerieData[n][i].context.stackHeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var valueHig = AxisHelper.GetAxisValueLength(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
yPos = gridXY + valueHig;
|
||||
xPos = AxisHelper.GetAxisPosition(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 yPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Serie/Line/LineHandler.GridCoord.cs.meta
Normal file
11
Runtime/Serie/Line/LineHandler.GridCoord.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34168c2605d4546c291adeb8e857fd62
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
127
Runtime/Serie/Line/LineHandler.PolarCoord.cs
Normal file
127
Runtime/Serie/Line/LineHandler.PolarCoord.cs
Normal file
@@ -0,0 +1,127 @@
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// For polar coord
|
||||
/// </summary>
|
||||
internal sealed partial class LineHandler
|
||||
{
|
||||
private void DrawPolarLine(VertexHelper vh, Serie serie)
|
||||
{
|
||||
var datas = serie.data;
|
||||
if (datas.Count <= 0)
|
||||
return;
|
||||
|
||||
var m_Polar = chart.GetChartComponent<PolarCoord>(serie.polarIndex);
|
||||
if (m_Polar == null)
|
||||
return;
|
||||
|
||||
var m_AngleAxis = ComponentHelper.GetAngleAxis(chart.components, m_Polar.index);
|
||||
var m_RadiusAxis = ComponentHelper.GetRadiusAxis(chart.components, m_Polar.index);
|
||||
if (m_AngleAxis == null || m_RadiusAxis == null)
|
||||
return;
|
||||
|
||||
var startAngle = m_AngleAxis.startAngle;
|
||||
var radius = m_Polar.context.radius;
|
||||
|
||||
var min = m_RadiusAxis.context.minValue;
|
||||
var max = m_RadiusAxis.context.maxValue;
|
||||
var firstSerieData = datas[0];
|
||||
var startPos = GetPolarPos(m_Polar, m_AngleAxis, firstSerieData, min, max, radius);
|
||||
var nextPos = Vector3.zero;
|
||||
var lineColor = SerieHelper.GetLineColor(serie, 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);
|
||||
|
||||
for (int i = 1; i < datas.Count; i++)
|
||||
{
|
||||
if (serie.animation.CheckDetailBreak(i))
|
||||
break;
|
||||
|
||||
var serieData = datas[i];
|
||||
nextPos = GetPolarPos(m_Polar, m_AngleAxis, datas[i], min, max, radius);
|
||||
UGL.DrawLine(vh, startPos, nextPos, lineWidth, lineColor);
|
||||
startPos = nextPos;
|
||||
}
|
||||
|
||||
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 cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
|
||||
|
||||
symbolSize = serie.animation.GetSysmbolSize(symbolSize);
|
||||
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, serieData.context.position,
|
||||
symbolColor, symbolToColor, symbolEmptyColor, 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.startAngle - (float)serieData.GetData(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = m_AngleAxis.startAngle + (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;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Serie/Line/LineHandler.PolarCoord.cs.meta
Normal file
11
Runtime/Serie/Line/LineHandler.PolarCoord.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8655c97b8c7e44e44852f8b81a7372b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
451
Runtime/Serie/Line/LineHelper.cs
Normal file
451
Runtime/Serie/Line/LineHelper.cs
Normal file
@@ -0,0 +1,451 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
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, bool isY, Axis axis, Axis relativedAxis, GridCoord grid)
|
||||
{
|
||||
if (serie.areaStyle == null || !serie.areaStyle.show)
|
||||
return;
|
||||
|
||||
var srcAreaColor = SerieHelper.GetAreaColor(serie, theme, serie.context.colorIndex, false);
|
||||
var srcAreaToColor = SerieHelper.GetAreaToColor(serie, theme, serie.context.colorIndex, false);
|
||||
var gridXY = (isY ? grid.context.x : grid.context.y);
|
||||
if (lastStackSerie == null)
|
||||
{
|
||||
LineHelper.DrawSerieLineNormalArea(vh, serie, isY,
|
||||
gridXY + relativedAxis.context.offset,
|
||||
gridXY,
|
||||
gridXY + (isY ? grid.context.width : grid.context.height),
|
||||
srcAreaColor,
|
||||
srcAreaToColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
LineHelper.DrawSerieLineStackArea(vh, serie, lastStackSerie, isY,
|
||||
gridXY + relativedAxis.context.offset,
|
||||
gridXY,
|
||||
gridXY + (isY ? grid.context.width : grid.context.height),
|
||||
srcAreaColor,
|
||||
srcAreaToColor);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawSerieLineNormalArea(VertexHelper vh, Serie serie, bool isY,
|
||||
float zero, float min, float max, Color32 color, Color32 toColor)
|
||||
{
|
||||
var points = serie.context.drawPoints;
|
||||
var count = points.Count;
|
||||
if (count < 2)
|
||||
return;
|
||||
|
||||
var isBreak = false;
|
||||
var lp = Vector3.zero;
|
||||
var lerp = !ChartHelper.IsValueEqualsColor(color, toColor);
|
||||
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;
|
||||
|
||||
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 (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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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.IsNeedGradient(visualMap);
|
||||
var isLineStyleGradient = serie.lineStyle.IsNeedGradient();
|
||||
|
||||
//var highlight = serie.highlight || serie.context.pointerEnter;
|
||||
var lineColor = SerieHelper.GetLineColor(serie, theme, serie.context.colorIndex, false);
|
||||
|
||||
var lastDataIsIgnore = datas[0].isIgnoreBreak;
|
||||
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;
|
||||
}
|
||||
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 (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);
|
||||
}
|
||||
}
|
||||
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, 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:
|
||||
for (int i = 0; i < serie.context.dataPoints.Count; i++)
|
||||
{
|
||||
serie.context.drawPoints.Add(new PointInfo(serie.context.dataPoints[i], serie.context.dataIgnores[i]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
else
|
||||
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Serie/Line/LineHelper.cs.meta
Normal file
11
Runtime/Serie/Line/LineHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7292748fb01ef44709a94d08f4907dd5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
39
Runtime/Serie/Line/SimplifiedLine.cs
Normal file
39
Runtime/Serie/Line/SimplifiedLine.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[Serializable]
|
||||
[SerieHandler(typeof(SimplifiedLineHandler), true)]
|
||||
[SerieConvert(typeof(SimplifiedBar), typeof(Line))]
|
||||
[CoordOptions(typeof(GridCoord))]
|
||||
[DefaultAnimation(AnimationType.LeftToRight)]
|
||||
[SerieExtraComponent(typeof(AreaStyle))]
|
||||
public class SimplifiedLine : Serie, INeedSerieContainer, ISimplifiedSerie
|
||||
{
|
||||
public int containerIndex { get; internal set; }
|
||||
public int containterInstanceId { get; internal set; }
|
||||
|
||||
public static void 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);
|
||||
}
|
||||
}
|
||||
|
||||
public static SimplifiedLine CovertSerie(Serie serie)
|
||||
{
|
||||
var newSerie = serie.Clone<SimplifiedLine>();
|
||||
return newSerie;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Serie/Line/SimplifiedLine.cs.meta
Normal file
11
Runtime/Serie/Line/SimplifiedLine.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5740626e12a84a0ca3a984935f61720
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
281
Runtime/Serie/Line/SimplifiedLineHandler.cs
Normal file
281
Runtime/Serie/Line/SimplifiedLineHandler.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <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, lineWidth, isY);
|
||||
LineHelper.DrawSerieLineArea(vh, serie, null, chart.theme, 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.GetAxisValueLength(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
xPos = gridXY + valueHig;
|
||||
yPos = AxisHelper.GetAxisPosition(grid, axis, scaleWid, xValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var valueHig = AxisHelper.GetAxisValueLength(grid, relativedAxis, scaleWid, yValue);
|
||||
valueHig = AnimationStyleHelper.CheckDataAnimation(chart, serie, i, valueHig);
|
||||
|
||||
yPos = gridXY + valueHig;
|
||||
xPos = AxisHelper.GetAxisPosition(grid, axis, scaleWid, xValue);
|
||||
}
|
||||
np = new Vector3(xPos, yPos);
|
||||
return yPos;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Runtime/Serie/Line/SimplifiedLineHandler.cs.meta
Normal file
11
Runtime/Serie/Line/SimplifiedLineHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3c4714bd08de34548ac7be3ec6523ee1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user