3.0 - LineChart

This commit is contained in:
monitor1394
2021-12-08 08:31:32 +08:00
parent f39cddaa5e
commit a5469c0996
34 changed files with 890 additions and 1934 deletions

View File

@@ -205,7 +205,7 @@ namespace XCharts
var componentNum = m_IconStyle.arraySize + m_Label.arraySize + m_ItemStyle.arraySize + m_Emphasis.arraySize
+ m_Symbol.arraySize;
var title = "Component";
if (componentNum == 0) title += " (No Component)";
if (componentNum == 0) title += " (None)";
m_DataComponentFoldout = ChartEditorHelper.DrawHeader(title, m_DataComponentFoldout, false, null, null,
new HeaderMenuInfo("Add ItemStyle", () =>
{

View File

@@ -7,8 +7,8 @@ namespace XCharts
{
public class EditorCustomStyles
{
static readonly Color splitterDark = new Color(0.12f, 0.12f, 0.12f, 0.3f);
static readonly Color splitterLight = new Color(0.6f, 0.6f, 0.6f, 0.3f);
static readonly Color splitterDark = new Color(0.12f, 0.12f, 0.12f, 0.5f);
static readonly Color splitterLight = new Color(0.6f, 0.6f, 0.6f, 0.5f);
static readonly Texture2D paneOptionsIconDark = (Texture2D)EditorGUIUtility.Load("Builtin Skins/DarkSkin/Images/pane options.png");
static readonly Texture2D paneOptionsIconLight = (Texture2D)EditorGUIUtility.Load("Builtin Skins/LightSkin/Images/pane options.png");
static readonly Color headerBackgroundDark = new Color(0.1f, 0.1f, 0.1f, 0.2f);

View File

@@ -96,22 +96,22 @@ namespace XCharts.Examples
yield return new WaitForSeconds(1);
chart.GetChartComponent<Title>().subText = "LineTyle - 虚线";
serie.lineType = LineType.Dash;
serie.lineStyle.type = LineStyle.Type.Dashed;
chart.RefreshChart();
yield return new WaitForSeconds(1);
chart.GetChartComponent<Title>().subText = "LineTyle - 点线";
serie.lineType = LineType.Dot;
serie.lineStyle.type = LineStyle.Type.Dotted;
chart.RefreshChart();
yield return new WaitForSeconds(1);
chart.GetChartComponent<Title>().subText = "LineTyle - 点划线";
serie.lineType = LineType.DashDot;
serie.lineStyle.type = LineStyle.Type.DashDot;
chart.RefreshChart();
yield return new WaitForSeconds(1);
chart.GetChartComponent<Title>().subText = "LineTyle - 双点划线";
serie.lineType = LineType.DashDotDot;
serie.lineStyle.type = LineStyle.Type.DashDotDot;
chart.RefreshChart();
serie.lineType = LineType.Normal;

View File

@@ -400,10 +400,8 @@ namespace XCharts
var tempX = xAxis.Clone();
xAxis.Copy(yAxis);
yAxis.Copy(tempX);
xAxis.context.xOffset = 0;
xAxis.context.yOffset = 0;
yAxis.context.xOffset = 0;
yAxis.context.yOffset = 0;
xAxis.context.offset = 0;
yAxis.context.offset = 0;
xAxis.context.minValue = 0;
xAxis.context.maxValue = 0;
yAxis.context.minValue = 0;

View File

@@ -43,8 +43,7 @@ namespace XCharts
{
chart.m_IsPlayingAnimation = true;
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
axis.context.xOffset = 0;
axis.context.yOffset = 0;
axis.context.offset = 0;
axis.context.lastCheckInverse = axis.inverse;
if (updateChart)
{

View File

@@ -34,15 +34,10 @@ namespace XCharts
/// </summary>
public double maxValue { get; internal set; }
/// <summary>
/// the x offset of zero position.
/// 坐标轴原点在X轴的偏移。
/// the offset of zero position.
/// 坐标轴原点在坐标轴的偏移。
/// </summary>
public float xOffset { get; internal set; }
/// <summary>
/// the y offset of zero position.
/// 坐标轴原点在Y轴的偏移。
/// </summary>
public float yOffset { get; internal set; }
public float offset { get; internal set; }
public double minMaxRange { get; internal set; }
public float scaleWidth { get; internal set; }
public float startAngle { get; set; }

View File

@@ -84,7 +84,7 @@ namespace XCharts
{
var yRate = axis.context.minMaxRange / grid.context.height;
var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.yOffset);
var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.offset);
if (axis.context.minValue > 0)
yValue += axis.context.minValue;
@@ -96,7 +96,7 @@ namespace XCharts
{
var xRate = axis.context.minMaxRange / grid.context.width;
var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.xOffset);
var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.offset);
if (axis.context.minValue > 0)
xValue += axis.context.minValue;
@@ -135,8 +135,7 @@ namespace XCharts
chart.m_IsPlayingAnimation = true;
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
axis.context.xOffset = 0;
axis.context.yOffset = 0;
axis.context.offset = 0;
axis.context.lastCheckInverse = axis.inverse;
UpdateAxisTickValueList(axis);
@@ -146,7 +145,7 @@ namespace XCharts
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
if (grid != null && axis is XAxis && axis.IsValue())
{
axis.context.xOffset = axis.context.minValue > 0
axis.context.offset = axis.context.minValue > 0
? 0
: (axis.context.maxValue < 0
? grid.context.width
@@ -156,7 +155,7 @@ namespace XCharts
}
if (grid != null && axis is YAxis && axis.IsValue())
{
axis.context.yOffset = axis.context.minValue > 0
axis.context.offset = axis.context.minValue > 0
? 0
: (axis.context.maxValue < 0
? grid.context.height
@@ -443,7 +442,7 @@ namespace XCharts
var axisNameTextStyle = axis.axisName.textStyle;
var offset = axisNameTextStyle.offset;
var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.yOffset);
var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset);
var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist);
if (orient == Orient.Horizonal)
@@ -555,7 +554,7 @@ namespace XCharts
if (orient == Orient.Horizonal)
{
if (axis.axisLabel.onZero && relativedAxis != null)
axisStartY += relativedAxis.context.yOffset;
axisStartY += relativedAxis.context.offset;
if (axis.IsTop())
axisStartY += relativedLength;
@@ -570,7 +569,7 @@ namespace XCharts
else
{
if (axis.axisLabel.onZero && relativedAxis != null)
axisStartX += relativedAxis.context.yOffset;
axisStartX += relativedAxis.context.offset;
if (axis.IsRight())
axisStartX += relativedLength;

View File

@@ -190,18 +190,21 @@ namespace XCharts
if (axis.IsCategory())
{
var data = axis.GetDataList(dataZoom);
var dataCount = axis.GetDataList(dataZoom).Count;
var scaleNum = 0;
if (axis.boundaryGap)
{
scaleNum = data.Count % splitNum == 0 ? splitNum + 1 : splitNum + 2;
scaleNum = dataCount > 2 && dataCount % splitNum == 0
? splitNum + 1
: splitNum + 2;
}
else
{
if (data.Count < splitNum)
scaleNum = splitNum;
else
scaleNum = data.Count % splitNum == 0 ? splitNum : splitNum + 1;
if (dataCount < splitNum) scaleNum = splitNum;
else scaleNum = dataCount > 2 && dataCount % splitNum == 0
? splitNum
: splitNum + 1;
}
return scaleNum;
}
@@ -475,5 +478,31 @@ namespace XCharts
}
}
public static float GetAxisPosition(GridCoord grid, Axis axis, float scaleWidth, double value)
{
var isY = axis is YAxis;
var gridHeight = isY ? grid.context.height : grid.context.width;
var gridXY = isY ? grid.context.y : grid.context.x;
if (axis.IsLog())
{
int minIndex = axis.GetLogMinIndex();
float nowIndex = axis.GetLogValue(value);
return gridXY + (nowIndex - minIndex) / axis.splitNumber * gridHeight;
}
else if (axis.IsCategory())
{
var categoryIndex = (int)value;
var categoryStart = gridXY + (axis.boundaryGap ? scaleWidth / 2 : 0);
return categoryStart + scaleWidth * categoryIndex;
}
else
{
var yDataHig = (axis.context.minMaxRange == 0) ? 0f :
(float)((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
return gridXY + yDataHig;
}
}
}
}

View File

@@ -42,8 +42,7 @@ namespace XCharts
{
chart.m_IsPlayingAnimation = true;
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
axis.context.xOffset = 0;
axis.context.yOffset = 0;
axis.context.offset = 0;
axis.context.lastCheckInverse = axis.inverse;
if (updateChart)

View File

@@ -127,6 +127,7 @@ namespace XCharts
private int m_DestDataProgress { get; set; }
[SerializeField] private float m_CurrDetailProgress;
[SerializeField] private float m_DestDetailProgress;
[SerializeField] private float m_TotalDetailProgress;
private float m_CurrSymbolProgress;
private Vector3 m_LinePathLastPos;
private float m_LinePathCurrTotalDist = 0f;
@@ -254,6 +255,7 @@ namespace XCharts
m_IsInit = true;
m_DestDataProgress = data;
m_TotalDetailProgress = dest - curr;
if (m_FadeOut)
{
@@ -267,6 +269,33 @@ namespace XCharts
}
}
public void InitProgress(List<Vector3> paths, bool isY)
{
if (paths.Count < 1) return;
var sp = paths[0];
var ep = paths[paths.Count - 1];
var currDetailProgress = isY ? sp.y : sp.x;
var totalDetailProgress = isY ? ep.y : ep.x;
if (m_AlongWithLinePath)
{
currDetailProgress = 0;
totalDetailProgress = 0;
var lp = sp;
for (int i = 1; i < paths.Count; i++)
{
var np = paths[i];
totalDetailProgress += Vector3.Distance(np, lp);
lp = np;
}
SetLinePathStartPos(sp);
}
else
{
InitProgress(paths.Count, currDetailProgress, totalDetailProgress);
}
}
public void SetDataFinish(int dataIndex)
{
if (m_IsEnd)
@@ -418,6 +447,11 @@ namespace XCharts
return dataIndex <= m_CurrDataProgress;
}
internal void CheckProgress()
{
CheckProgress(m_TotalDetailProgress);
}
internal void CheckProgress(double total)
{
if (IsFinish())

View File

@@ -18,37 +18,53 @@ namespace XCharts
public enum SymbolType
{
/// <summary>
/// 空心圆
/// 不显示标记
/// </summary>
EmptyCircle,
None,
/// <summary>
/// 自定义标记。
/// </summary>
Custom,
/// <summary>
/// 圆形。
/// </summary>
Circle,
/// <summary>
/// 空心圆。
/// </summary>
EmptyCircle,
/// <summary>
/// 正方形。可通过设置`itemStyle`的`cornerRadius`变成圆角矩形。
/// </summary>
Rect,
/// <summary>
/// 空心正方形。
/// </summary>
EmptyRect,
/// <summary>
/// 三角形。
/// </summary>
Triangle,
/// <summary>
/// 空心三角形。
/// </summary>
EmptyTriangle,
/// <summary>
/// 菱形。
/// </summary>
Diamond,
/// <summary>
/// 不显示标记
/// 空心菱形
/// </summary>
None,
EmptyDiamond,
/// <summary>
/// 箭头。
/// </summary>
Arrow,
/// <summary>
/// 自定义标记
/// 空心箭头
/// </summary>
Custom
EmptyArrow
}
/// <summary>

View File

@@ -19,8 +19,8 @@ namespace XCharts
[SerializeField]
private TextStyle m_TextStyle = new TextStyle()
{
fontSize = 16,
backgroundColor = new Color32(32, 32, 32, 151),
fontSize = 18,
backgroundColor = new Color32(32, 32, 32, 170),
color = Color.white
};
@@ -30,6 +30,7 @@ namespace XCharts
private static readonly float MAXCACHE = 20;
private int m_FrameCount = 0;
private float m_LastTime = 0f;
private float m_LastCheckShowTime = 0f;
private int m_LastRefreshCount = 0;
private BaseChart m_Chart;
private ChartLabel m_Label;
@@ -39,6 +40,7 @@ namespace XCharts
public float fps { get; private set; }
public float avgFps { get; private set; }
public int refreshCount { get; internal set; }
internal int clickChartCount { get; set; }
public void Init(BaseChart chart)
{
@@ -48,7 +50,22 @@ namespace XCharts
public void Update()
{
if (!m_Show || m_Label == null) return;
if (clickChartCount >= 2)
{
m_Show = !m_Show;
ChartHelper.SetActive(m_Label.transform, m_Show);
clickChartCount = 0;
m_LastCheckShowTime = Time.realtimeSinceStartup;
return;
}
if (Time.realtimeSinceStartup - m_LastCheckShowTime > 0.5f)
{
m_LastCheckShowTime = Time.realtimeSinceStartup;
clickChartCount = 0;
}
if (!m_Show || m_Label == null)
return;
m_FrameCount++;
if (Time.realtimeSinceStartup - m_LastTime >= INTERVAL)
{
@@ -70,15 +87,37 @@ namespace XCharts
if (m_Label != null)
{
s_Sb.Length = 0;
s_Sb.AppendFormat("v{0}\n", XChartsMgr.version);
s_Sb.AppendFormat("fps : {0:f0} / {1:f0}\n", fps, avgFps);
s_Sb.AppendFormat("data : {0}\n", m_Chart.GetAllSerieDataCount());
s_Sb.AppendFormat("draw : {0}", refreshCount);
s_Sb.AppendFormat("draw : {0}\n", refreshCount);
var dataCount = m_Chart.GetAllSerieDataCount();
SetValueWithKInfo(s_Sb, "data", dataCount);
var vertCount = 0;
foreach (var serie in m_Chart.series)
vertCount += serie.context.vertCount;
SetValueWithKInfo(s_Sb, "b-vert", m_Chart.m_BasePainterVertCount);
SetValueWithKInfo(s_Sb, "s-vert", vertCount);
SetValueWithKInfo(s_Sb, "t-vert", m_Chart.m_TopPainterVertCount, false);
m_Label.SetText(s_Sb.ToString());
}
}
}
private float GetAvg(List<float> list)
private static void SetValueWithKInfo(StringBuilder s_Sb, string key, int value, bool newLine = true)
{
if (value >= 1000)
s_Sb.AppendFormat("{0} : {1:f1}k", key, value * 0.001f);
else
s_Sb.AppendFormat("{0} : {1}", key, value);
if (newLine)
s_Sb.Append("\n");
}
private static float GetAvg(List<float> list)
{
var total = 0f;
foreach (var v in list) total += v;
@@ -94,14 +133,11 @@ namespace XCharts
var sizeDelta = new Vector2(100, 100);
var labelGameObject = ChartHelper.AddObject(name, parent, anchorMin, anchorMax, pivot, sizeDelta);
var active = m_Chart.debugModel && m_Show;
ChartHelper.SetActive(labelGameObject, active);
if (!active)
{
return null;
}
var label = ChartHelper.GetOrAddComponent<ChartLabel>(labelGameObject);
labelGameObject.transform.SetAsLastSibling();
labelGameObject.hideFlags = m_Chart.chartHideFlags;
ChartHelper.SetActive(labelGameObject, m_Show);
var label = ChartHelper.GetOrAddComponent<ChartLabel>(labelGameObject);
label.labelBackground = label;
label.labelBackground.color = textStyle.backgroundColor;
label.labelBackground.raycastTarget = false;

View File

@@ -255,7 +255,7 @@ namespace XCharts
var tickness = SerieHelper.GetSymbolBorder(serie, null, theme, false);
var cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, null, false);
chart.DrawClipSymbol(vh, symbol.type, symbolSize, tickness, pos, lineColor, lineColor,
symbol.gap, true, cornerRadius, grid, startPos);
ColorUtil.clearColor32, symbol.gap, true, cornerRadius, grid, startPos);
}
private void GetStartEndPos(Axis xAxis, Axis yAxis, GridCoord grid, double value, ref Vector3 sp, ref Vector3 ep)

View File

@@ -12,13 +12,15 @@ namespace XCharts
{
public static class VisualMapHelper
{
public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, XAxis xAxis, YAxis yAxis)
public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)
{
if (!IsNeedGradient(visualMap) || !visualMap.autoMinMax)
return;
double min = 0;
double max = 0;
var xAxis = isY ? relativedAxis : axis;
var yAxis = isY ? axis : relativedAxis;
if (visualMap.dimension == 0)
{
min = xAxis.IsCategory() ? 0 : xAxis.context.minValue;
@@ -66,8 +68,8 @@ namespace XCharts
}
}
public static Color32 GetLineGradientColor(VisualMap visualMap, Vector3 pos, BaseChart chart, Axis axis,
Color32 defaultColor)
public static Color32 GetLineGradientColor(VisualMap visualMap, Vector3 pos, GridCoord grid, Axis axis,
Axis relativedAxis, Color32 defaultColor)
{
double value = 0;
double min = 0;
@@ -77,7 +79,6 @@ namespace XCharts
{
min = axis.context.minValue;
max = axis.context.maxValue;
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
if (axis.IsCategory() && axis.boundaryGap)
{
float startX = grid.context.x + axis.context.scaleWidth / 2;
@@ -90,25 +91,13 @@ namespace XCharts
}
else
{
Axis yAxis;
if (axis is YAxis)
{
yAxis = chart.GetChartComponent<XAxis>(axis.index);
min = yAxis.context.minValue;
max = yAxis.context.maxValue;
}
else
{
yAxis = chart.GetChartComponent<YAxis>(axis.index);
min = yAxis.context.minValue;
max = yAxis.context.maxValue;
}
min = relativedAxis.context.minValue;
max = relativedAxis.context.maxValue;
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
if (yAxis.IsCategory() && yAxis.boundaryGap)
if (relativedAxis.IsCategory() && relativedAxis.boundaryGap)
{
float startY = grid.context.y + yAxis.context.scaleWidth / 2;
value = (int)(min + (pos.y - startY) / (grid.context.height - yAxis.context.scaleWidth) * (max - min));
float startY = grid.context.y + relativedAxis.context.scaleWidth / 2;
value = (int)(min + (pos.y - startY) / (grid.context.height - relativedAxis.context.scaleWidth) * (max - min));
}
else
{
@@ -145,12 +134,11 @@ namespace XCharts
return color;
}
public static Color32 GetLineStyleGradientColor(LineStyle lineStyle, Vector3 pos, BaseChart chart,
public static Color32 GetLineStyleGradientColor(LineStyle lineStyle, Vector3 pos, GridCoord grid,
Axis axis, Color32 defaultColor)
{
var min = axis.context.minValue;
var max = axis.context.maxValue;
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
var value = min + (pos.x - grid.context.x) / grid.context.width * (max - min);
var rate = (value - min) / (max - min);
var color = lineStyle.GetGradientColor((float)rate, defaultColor);

View File

@@ -170,8 +170,7 @@ namespace XCharts
chart.m_IsPlayingAnimation = true;
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
axis.context.xOffset = 0;
axis.context.yOffset = 0;
axis.context.offset = 0;
axis.context.lastCheckInverse = axis.inverse;
AxisHandler<ParallelAxis>.UpdateAxisTickValueList(axis);

View File

@@ -89,12 +89,12 @@ namespace XCharts
}
public void DrawClipSymbol(VertexHelper vh, SymbolType type, float symbolSize, float tickness,
Vector3 pos, Color32 color, Color32 toColor, float gap, bool clip, float[] cornerRadius, GridCoord grid,
Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, float gap, bool clip, float[] cornerRadius, GridCoord grid,
Vector3 startPos)
{
if (!IsInChart(pos)) return;
if (!clip || (clip && (grid.Contains(pos))))
DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, cornerRadius, startPos);
DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, emptyColor, gap, cornerRadius, startPos);
}
public void DrawClipZebraLine(VertexHelper vh, Vector3 p1, Vector3 p2, float size, float zebraWidth,
@@ -106,18 +106,20 @@ namespace XCharts
}
public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize,
float tickness, Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius)
float tickness, Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, float gap, float[] cornerRadius)
{
DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap, cornerRadius, Vector3.zero);
DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, emptyColor, gap, cornerRadius, Vector3.zero);
}
public void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize,
float tickness, Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius, Vector3 startPos)
float tickness, Vector3 pos, Color32 color, Color32 toColor, Color32 emptyColor, float gap, float[] cornerRadius, Vector3 startPos)
{
var backgroundColor = theme.GetBackgroundColor(GetChartComponent<Background>());
if (ChartHelper.IsClearColor(emptyColor))
emptyColor = backgroundColor;
var smoothness = settings.cicleSmoothness;
ChartDrawer.DrawSymbol(vh, type, symbolSize, tickness, pos, color, toColor, gap,
cornerRadius, backgroundColor, smoothness, startPos);
cornerRadius, emptyColor, backgroundColor, smoothness, startPos);
}
public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)

View File

@@ -97,6 +97,8 @@ namespace XCharts
internal protected List<string> m_LegendRealShowName = new List<string>();
protected List<Painter> m_PainterList = new List<Painter>();
internal Painter m_PainterTop;
internal int m_BasePainterVertCount;
internal int m_TopPainterVertCount;
private ThemeType m_CheckTheme = 0;
@@ -430,6 +432,7 @@ namespace XCharts
public override void OnPointerClick(PointerEventData eventData)
{
m_DebugInfo.clickChartCount++;
base.OnPointerClick(eventData);
foreach (var handler in m_SerieHandlers) handler.OnPointerClick(eventData);
foreach (var handler in m_ComponentHandlers) handler.OnPointerClick(eventData);
@@ -556,6 +559,7 @@ namespace XCharts
{
m_OnCustomDrawBaseCallback(vh);
}
m_BasePainterVertCount = vh.currentVertCount;
}
protected virtual void OnDrawPainterSerie(VertexHelper vh, Painter painter)
@@ -585,6 +589,7 @@ namespace XCharts
{
m_OnCustomDrawSerieAfterCallback(vh, serie);
}
serie.context.vertCount = vh.currentVertCount;
}
}
@@ -597,6 +602,7 @@ namespace XCharts
{
m_OnCustomDrawTopCallback(vh);
}
m_TopPainterVertCount = vh.currentVertCount;
}
protected virtual void DrawPainterSerie(VertexHelper vh, Serie serie)

View File

@@ -18,7 +18,7 @@ namespace XCharts
public static void DrawSymbol(VertexHelper vh, SymbolType type, float symbolSize,
float tickness, Vector3 pos, Color32 color, Color32 toColor, float gap, float[] cornerRadius,
Color32 backgroundColor, float smoothness, Vector3 startPos)
Color32 emptyColor, Color32 backgroundColor, float smoothness, Vector3 startPos)
{
switch (type)
{
@@ -38,11 +38,11 @@ namespace XCharts
if (gap > 0)
{
UGL.DrawCricle(vh, pos, symbolSize + gap, backgroundColor, smoothness);
UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, backgroundColor, smoothness);
UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, emptyColor, smoothness);
}
else
{
UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, backgroundColor, smoothness);
UGL.DrawEmptyCricle(vh, pos, symbolSize, tickness, color, color, emptyColor, smoothness);
}
break;
case SymbolType.Rect:
@@ -56,6 +56,17 @@ namespace XCharts
UGL.DrawRoundRectangle(vh, pos, symbolSize, symbolSize, color, color, 0, cornerRadius, true);
}
break;
case SymbolType.EmptyRect:
if (gap > 0)
{
UGL.DrawSquare(vh, pos, symbolSize + gap, backgroundColor);
UGL.DrawBorder(vh, pos, symbolSize / 2, symbolSize / 2, tickness, color);
}
else
{
UGL.DrawBorder(vh, pos, symbolSize / 2, symbolSize / 2, tickness, color);
}
break;
case SymbolType.Triangle:
if (gap > 0)
{

View File

@@ -72,7 +72,7 @@ namespace XCharts
if (component is YAxis)
{
var yAxis = component as YAxis;
if (yAxis.IsValue() && yAxis.gridIndex == axis.gridIndex) return yAxis.context.yOffset;
if (yAxis.IsValue() && yAxis.gridIndex == axis.gridIndex) return yAxis.context.offset;
}
}
return 0;
@@ -86,7 +86,7 @@ namespace XCharts
if (component is XAxis)
{
var xAxis = component as XAxis;
if (xAxis.IsValue() && xAxis.gridIndex == axis.gridIndex) return xAxis.context.xOffset;
if (xAxis.IsValue() && xAxis.gridIndex == axis.gridIndex) return xAxis.context.offset;
}
}
return 0;

View File

@@ -12,7 +12,8 @@ namespace XCharts
{
internal static class DataHelper
{
public static double DataAverage(ref List<SerieData> showData, SampleType sampleType, int minCount, int maxCount, int rate)
public static double DataAverage(ref List<SerieData> showData, SampleType sampleType,
int minCount, int maxCount, int rate)
{
double totalAverage = 0;
if (rate > 1 && sampleType == SampleType.Peak)
@@ -32,13 +33,14 @@ namespace XCharts
ref bool dataChanging, Axis axis)
{
var inverse = axis.inverse;
double minValue = axis.context.minValue;
double MaxValue = axis.context.maxValue;
var minValue = axis.context.minValue;
var maxValue = axis.context.maxValue;
if (rate <= 1 || index == minCount)
{
if (showData[index].IsDataChanged()) dataChanging = true;
//Debug.LogError("sample:"+index+","+rate+","+(showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue))+","+showData[index].GetData(1));
return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
if (showData[index].IsDataChanged())
dataChanging = true;
return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue);
}
switch (sampleType)
{
@@ -48,49 +50,68 @@ namespace XCharts
var count = 0;
for (int i = index; i > index - rate; i--)
{
count ++;
total += showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
if (showData[i].IsDataChanged()) dataChanging = true;
count++;
total += showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue);
if (showData[i].IsDataChanged())
dataChanging = true;
}
//Debug.LogError("sample:"+index+","+rate+","+count+","+total);
if (sampleType == SampleType.Average) return total / rate;
else return total;
if (sampleType == SampleType.Average)
return total / rate;
else
return total;
case SampleType.Max:
double max = double.MinValue;
for (int i = index; i > index - rate; i--)
{
var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
if (value > max) max = value;
if (showData[i].IsDataChanged()) dataChanging = true;
var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue);
if (value > max)
max = value;
if (showData[i].IsDataChanged())
dataChanging = true;
}
return max;
case SampleType.Min:
double min = double.MaxValue;
for (int i = index; i > index - rate; i--)
{
var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
if (value < min) min = value;
if (showData[i].IsDataChanged()) dataChanging = true;
var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue);
if (value < min)
min = value;
if (showData[i].IsDataChanged())
dataChanging = true;
}
return min;
case SampleType.Peak:
max = double.MinValue;
min = double.MaxValue;
total = 0;
for (int i = index; i > index - rate; i--)
{
var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
var value = showData[i].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue);
total += value;
if (value < min) min = value;
if (value > max) max = value;
if (showData[i].IsDataChanged()) dataChanging = true;
if (value < min)
min = value;
if (value > max)
max = value;
if (showData[i].IsDataChanged())
dataChanging = true;
}
var average = total / rate;
if (average >= totalAverage) return max;
else return min;
if (average >= totalAverage)
return max;
else
return min;
}
if (showData[index].IsDataChanged()) dataChanging = true;
return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, MaxValue);
if (showData[index].IsDataChanged())
dataChanging = true;
return showData[index].GetCurrData(1, dataChangeDuration, inverse, minValue, maxValue);
}
}
}

View File

@@ -150,7 +150,7 @@ namespace XCharts
float pY = grid.context.y + i * categoryWidth;
if (!yAxis.boundaryGap) pY -= categoryWidth / 2;
float pX = grid.context.x + xAxis.context.xOffset + axisLineWidth;
float pX = grid.context.x + xAxis.context.offset + axisLineWidth;
if (isStack)
{
for (int n = 0; n < m_StackSerieData.Count - 1; n++)
@@ -299,7 +299,7 @@ namespace XCharts
{
if (!xAxis.boundaryGap) pX -= categoryWidth / 2;
}
float zeroY = grid.context.y + yAxis.context.yOffset;
float zeroY = grid.context.y + yAxis.context.offset;
float axisLineWidth = value == 0 ? 0 :
((value < 0 ? -1 : 1) * xAxis.axisLine.GetWidth(chart.theme.axis.lineWidth));
float pY = zeroY + axisLineWidth;

View File

@@ -68,7 +68,7 @@ namespace XCharts
: itemStyle.runtimeBorderWidth);
if (serieData.IsDataChanged()) dataChanging = true;
float pX = grid.context.x + i * categoryWidth;
float zeroY = grid.context.y + yAxis.context.yOffset;
float zeroY = grid.context.y + yAxis.context.offset;
if (!xAxis.boundaryGap) pX -= categoryWidth / 2;
float pY = zeroY;
var barHig = 0f;

File diff suppressed because it is too large Load Diff

View File

@@ -97,12 +97,13 @@ namespace XCharts
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.runtimePosition,
symbolColor, symbolToColor, symbol.gap, cornerRadius);
symbolColor, symbolToColor, symbolEmptyColor, symbol.gap, cornerRadius);
}
}
}

View File

@@ -7,11 +7,15 @@
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;
@@ -24,93 +28,424 @@ namespace XCharts
return rate;
}
public static Vector3 GetNNPos(List<Vector3> dataPoints, int index, Vector3 np, bool ignoreLineBreak)
public static void DrawSerieLineArea(VertexHelper vh, Serie serie, Serie lastStackSerie,
ThemeStyle theme, bool isY, Axis axis, Axis relativedAxis, GridCoord grid)
{
int size = dataPoints.Count;
if (index >= size)
return np;
for (int i = index + 1; i < size; i++)
{
if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
return dataPoints[i];
}
return np;
}
if (!serie.areaStyle.show)
return;
public static Vector3 GetStartPos(List<Vector3> dataPoints, ref int start, bool ignoreLineBreak)
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)
{
for (int i = 0; i < dataPoints.Count; i++)
{
if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
{
start = i;
return dataPoints[i];
LineHelper.DrawSerieLineNormalArea(vh, serie, isY,
gridXY + relativedAxis.context.offset,
gridXY,
gridXY + (isY ? grid.context.width : grid.context.height),
srcAreaColor,
srcAreaToColor);
}
}
return Vector3.zero;
}
public static Vector3 GetEndPos(List<Vector3> dataPoints, ref int end, bool ignoreLineBreak)
{
for (int i = dataPoints.Count - 1; i >= 0; i--)
{
if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
{
end = i;
return dataPoints[i];
}
}
return Vector3.zero;
}
public static Vector3 GetLastPos(List<Vector3> dataPoints, int index, Vector3 pos, bool ignoreLineBreak)
{
if (index <= 0)
return pos;
for (int i = index - 1; i >= 0; i--)
{
if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
return dataPoints[i];
}
return pos;
}
public static Vector3 GetLLPos(List<Vector3> dataPoints, int index, Vector3 lp, bool ignoreLineBreak)
{
if (index <= 1)
return lp;
for (int i = index - 2; i >= 0; i--)
{
if (dataPoints[i] != Vector3.zero || ignoreLineBreak)
return dataPoints[i];
}
return lp;
}
public static bool IsInRightOrUp(bool isYAxis, Vector3 lp, Vector3 rp)
{
return ChartHelper.IsZeroVector(lp)
|| ((isYAxis && rp.y > lp.y)
|| (!isYAxis && rp.x > lp.x));
}
public static bool IsInRightOrUpNotCheckZero(bool isYAxis, Vector3 lp, Vector3 rp)
{
return (isYAxis && rp.y > lp.y) || (!isYAxis && rp.x > lp.x);
}
public static bool WasTooClose(bool isYAxis, Vector3 lp, Vector3 rp, bool ignore)
{
if (ignore)
return false;
if (lp == Vector3.zero || rp == Vector3.zero)
return false;
if (isYAxis)
return Mathf.Abs(rp.y - lp.y) < 1f;
else
return Mathf.Abs(rp.x - lp.x) < 1f;
{
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)
{
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.highlighted || serie.context.pointerEnter;
var lineWidth = serie.lineStyle.GetWidth(theme.serie.lineWidth);
var lineColor = SerieHelper.GetLineColor(serie, theme, serie.context.colorIndex, highlight);
var lastDataIsIgnore = datas[0].isIgnoreBreak;
for (int i = 1; i < dataCount; i++)
{
if (!serie.animation.NeedAnimation(i))
break;
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 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, cp, axisStartPos, axisEndPos, 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);
if (i == 1)
{
AddLineVertToVertexHelper(vh, ltp, lbp, lineColor, isVisualMapGradient, isLineStyleGradient,
visualMap, serie.lineStyle, grid, axis, relativedAxis, false, lastDataIsIgnore, isIgnore);
}
if (bitp == bibp)
{
AddLineVertToVertexHelper(vh, itp, ibp, 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)
serie.animation.SetDataFinish(i);
else
break;
}
}
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, 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);
break;
default:
for (int i = 0; i < serie.dataPoints.Count; i++)
{
serie.context.drawPoints.Add(new PointInfo(serie.dataPoints[i], serie.dataIgnore[i]));
}
break;
}
}
private static void UpdateSmoothLineDrawPoints(Serie serie, Settings setting, bool isY)
{
var points = serie.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.dataIgnore[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)
{
var points = serie.dataPoints;
var lp = points[0];
var lineWidth = serie.lineStyle.GetWidth(theme.serie.lineWidth);
serie.context.drawPoints.Clear();
serie.context.drawPoints.Add(new PointInfo(lp, serie.dataIgnore[0]));
for (int i = 1; i < points.Count; i++)
{
var cp = points[i];
var ignore = serie.dataIgnore[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;
}
}
}
}

View File

@@ -226,10 +226,11 @@ namespace XCharts
: serie.symbol.GetSize(null, 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 cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor,
symbolToColor, serie.symbol.gap, cornerRadius);
symbolToColor, symbolEmptyColor, serie.symbol.gap, cornerRadius);
}
}
}
@@ -413,6 +414,7 @@ namespace XCharts
: 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 cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
if (!radar.IsInIndicatorRange(j, serieData.GetData(1)))
@@ -421,7 +423,7 @@ namespace XCharts
symbolToColor = radar.outRangeColor;
}
chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, serieData.labelPosition, symbolColor,
symbolToColor, serie.symbol.gap, cornerRadius);
symbolToColor, symbolEmptyColor, serie.symbol.gap, cornerRadius);
}
}
if (!serie.animation.IsFinish())
@@ -462,12 +464,13 @@ namespace XCharts
: 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 cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, isHighlight);
foreach (var point in pointList)
{
chart.DrawSymbol(vh, serie.symbol.type, symbolSize, symbolBorder, point, symbolColor,
symbolToColor, serie.symbol.gap, cornerRadius);
symbolToColor, symbolEmptyColor, serie.symbol.gap, cornerRadius);
}
}
}

View File

@@ -168,6 +168,7 @@ namespace XCharts
var highlight = serie.highlighted || serieData.highlighted;
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 cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
double xValue = serieData.GetCurrData(0, dataChangeDuration, xAxis.inverse);
@@ -206,14 +207,14 @@ namespace XCharts
{
var nowSize = symbol.animationSize[count];
color.a = (byte)(255 * (symbolSize - nowSize) / symbolSize);
chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius);
chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, color, toColor, emptyColor, symbol.gap, cornerRadius);
}
chart.RefreshPainter(serie);
}
else
{
if (symbolSize > 100) symbolSize = 100;
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius);
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, toColor, emptyColor, symbol.gap, cornerRadius);
}
}
@@ -269,6 +270,7 @@ namespace XCharts
var highlight = serie.highlighted || serieData.highlighted;
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 cornerRadius = SerieHelper.GetSymbolCornerRadius(serie, serieData, highlight);
var xValue = serieData.GetCurrData(0, dataChangeDuration, axis.inverse);
@@ -307,14 +309,16 @@ namespace XCharts
{
var nowSize = symbol.animationSize[count];
color.a = (byte)(255 * (symbolSize - nowSize) / symbolSize);
chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius);
chart.DrawSymbol(vh, symbol.type, nowSize, symbolBorder, pos,
color, toColor, emptyColor, symbol.gap, cornerRadius);
}
chart.RefreshPainter(serie);
}
else
{
if (symbolSize > 100) symbolSize = 100;
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos, color, toColor, symbol.gap, cornerRadius);
chart.DrawSymbol(vh, symbol.type, symbolSize, symbolBorder, pos,
color, toColor, emptyColor, symbol.gap, cornerRadius);
}
}
if (!serie.animation.IsFinish())

View File

@@ -50,11 +50,6 @@ namespace XCharts
/// </summary>
Smooth,
/// <summary>
/// the smooth-dash line chart
/// 平滑虚线。
/// </summary>
SmoothDash,
/// <summary>
/// step line.
/// 阶梯线图:当前点。
/// </summary>
@@ -68,23 +63,7 @@ namespace XCharts
/// step line.
/// 阶梯线图:下一个拐点。
/// </summary>
StepEnd,
/// <summary>
/// 虚线
/// </summary>
Dash,
/// <summary>
/// 点线
/// </summary>
Dot,
/// <summary>
/// 点划线
/// </summary>
DashDot,
/// <summary>
/// 双点划线
/// </summary>
DashDotDot
StepEnd
}
public enum BarType
@@ -294,6 +273,7 @@ namespace XCharts
[NonSerialized] private Dictionary<int, List<Vector3>> m_UpSmoothPoints = new Dictionary<int, List<Vector3>>();
[NonSerialized] private Dictionary<int, List<Vector3>> m_DownSmoothPoints = new Dictionary<int, List<Vector3>>();
[NonSerialized] private List<Vector3> m_DataPoints = new List<Vector3>();
[NonSerialized] private List<bool> m_DataIgnore = new List<bool>();
[NonSerialized] private bool m_NameDirty;
/// <summary>
@@ -1017,6 +997,7 @@ namespace XCharts
/// 数据项位置坐标。
/// </summary>
public List<Vector3> dataPoints { get { return m_DataPoints; } }
public List<bool> dataIgnore { get { return m_DataIgnore; } }
/// <summary>
/// 饼图的中心点位置。
/// </summary>

View File

@@ -6,9 +6,21 @@
/************************************************/
using System.Collections.Generic;
using UnityEngine;
namespace XCharts
{
public struct PointInfo
{
public Vector3 position;
public bool isIgnoreBreak;
public PointInfo(Vector3 pos, bool ignore)
{
this.position = pos;
this.isIgnoreBreak = ignore;
}
}
[System.Serializable]
public class SerieContext
{
@@ -25,5 +37,9 @@ namespace XCharts
/// </summary>
public List<int> pointerAxisDataIndexs = new List<int>();
public int vertCount;
internal int colorIndex;
internal List<PointInfo> drawPoints = new List<PointInfo>();
}
}

View File

@@ -32,7 +32,7 @@ namespace XCharts
[SerializeField] private List<double> m_Data = new List<double>();
[SerializeField] private List<int> m_Children = new List<int>();
public SerieDataContext context = new SerieDataContext();
public ChartLabel labelObject { get; set; }
private bool m_Show = true;

View File

@@ -11,5 +11,7 @@ using UnityEngine.UI;
namespace XCharts
{
public class SerieDataContext
{
}
}

View File

@@ -140,31 +140,70 @@ namespace XUGL
}
else
{
var lineLT = Vector3.zero;
var lineLB = Vector3.zero;
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 ctp = Vector3.zero;
var cbp = Vector3.zero;
for (int i = 1; i < points.Count - 1; i++)
{
bool bitp = true, bibp = true;
UGLHelper.GetLinePoints(points[i - 1], points[i], points[i + 1], width,
ref ltp, ref lbp, ref ntp, ref nbp, ref itp, ref ibp);
ref ltp, ref lbp,
ref ntp, ref nbp,
ref itp, ref ibp,
ref ctp, ref cbp,
ref bitp, ref bibp);
if (i == 1)
{
lineLT = ltp;
lineLB = lbp;
vh.AddVert(ltp, color, Vector2.zero);
vh.AddVert(lbp, color, Vector2.zero);
}
if (bitp == bibp)
{
AddVertToVertexHelper(vh, itp, ibp, color);
}
else
{
if (bitp)
{
AddVertToVertexHelper(vh, itp, ctp, color);
AddVertToVertexHelper(vh, itp, cbp, color);
}
else
{
AddVertToVertexHelper(vh, ctp, ibp, color);
AddVertToVertexHelper(vh, cbp, ibp, color);
}
}
}
AddVertToVertexHelper(vh, ntp, nbp, color);
}
}
DrawQuadrilateral(vh, lineLB, ibp, itp, lineLT, color);
lineLT = itp;
lineLB = ibp;
public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top,
Vector3 bottom, Color32 color, bool needTriangle = true)
{
AddVertToVertexHelper(vh, top, bottom, color, color, needTriangle);
}
DrawQuadrilateral(vh, lineLB, nbp, ntp, lineLT, color);
public static void AddVertToVertexHelper(VertexHelper vh, Vector3 top,
Vector3 bottom, Color32 topColor, Color32 bottomColor, bool needTriangle = true)
{
var lastVertCount = vh.currentVertCount;
vh.AddVert(top, topColor, Vector2.zero);
vh.AddVert(bottom, bottomColor, Vector2.zero);
if (needTriangle)
{
var indexRt = lastVertCount;
var indexRb = indexRt + 1;
var indexLt = indexRt - 2;
var indexLb = indexLt + 1;
vh.AddTriangle(indexLt, indexRb, indexLb);
vh.AddTriangle(indexLt, indexRt, indexRb);
}
}
@@ -545,14 +584,23 @@ namespace XUGL
/// <param name="toColor"></param>
public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
Color32 startColor, Color32 toColor)
{
DrawQuadrilateral(vh, p1, p2, p3, p4, startColor, startColor, toColor, toColor);
}
public static void DrawQuadrilateral(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
Color32 color1, Color32 color2, Color32 color3, Color32 color4)
{
s_Vertex[0].position = p1;
s_Vertex[1].position = p2;
s_Vertex[2].position = p3;
s_Vertex[3].position = p4;
s_Vertex[0].color = color1;
s_Vertex[1].color = color2;
s_Vertex[2].color = color3;
s_Vertex[3].color = color4;
for (int j = 0; j < 4; j++)
{
s_Vertex[j].color = j >= 2 ? toColor : startColor;
s_Vertex[j].uv0 = s_ZeroVector2;
}
vh.AddUIVertexQuad(s_Vertex);
@@ -1673,20 +1721,19 @@ namespace XUGL
var ep = points[i + 1];
var lsp = i > 0 ? points[i - 1] : sp;
var nep = i < points.Count - 2 ? points[i + 2] : ep;
var smoothness2 = smoothness;
if (currProgress != float.PositiveInfinity)
{
var smoothness2 = 0f;
if (isYAxis)
smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f;
else
smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f;
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2);
}
if (isYAxis)
UGLHelper.GetBezierListVertical(ref s_CurvesPosList, sp, ep, smoothness2);
else
{
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness);
}
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2);
DrawCurvesInternal(vh, s_CurvesPosList, width, color, currProgress, isYAxis);
}
}
@@ -1702,6 +1749,11 @@ namespace XUGL
var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth;
var startUp = start - diff;
var startDn = start + diff;
var toUp = Vector3.zero;
var toDn = Vector3.zero;
var lastVertCount = vh.currentVertCount;
AddVertToVertexHelper(vh, startUp, startDn, lineColor, false);
for (int i = 1; i < curvesPosList.Count; i++)
{
to = curvesPosList[i];
@@ -1714,13 +1766,16 @@ namespace XUGL
}
diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth;
var toUp = to - diff;
var toDn = to + diff;
DrawQuadrilateral(vh, startUp, toUp, toDn, startDn, lineColor);
toUp = to - diff;
toDn = to + diff;
AddVertToVertexHelper(vh, toUp, toDn, lineColor);
startUp = toUp;
startDn = toDn;
start = to;
}
AddVertToVertexHelper(vh, toUp, toDn, lineColor);
}
}
}

View File

@@ -288,29 +288,43 @@ namespace XUGL
internal static void GetLinePoints(Vector3 lp, Vector3 cp, Vector3 np, float width,
ref Vector3 ltp, ref Vector3 lbp,
ref Vector3 ntp, ref Vector3 nbp,
ref Vector3 itp, ref Vector3 ibp)
ref Vector3 itp, ref Vector3 ibp,
ref Vector3 clp, ref Vector3 crp,
ref bool bitp, ref bool bibp
)
{
var dir1 = (cp - lp).normalized;
var dir2 = (cp - np).normalized;
var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized;
var dir2v = Vector3.Cross(dir2, Vector3.back).normalized;
ltp = lp + dir1v * width;
lbp = lp - dir1v * width;
ltp = lp - dir1v * width;
lbp = lp + dir1v * width;
ntp = np + dir2v * width;
nbp = np - dir2v * width;
ntp = np - dir2v * width;
nbp = np + dir2v * width;
var ldist = 1.3f * Vector3.Distance(cp, lp) * dir1;
var rdist = 1.3f * Vector3.Distance(cp, np) * dir2;
clp = cp - dir2v * width;
crp = cp + dir2v * width;
var ldist = (Vector3.Distance(cp, lp) + 1) * dir1;
var rdist = (Vector3.Distance(cp, np) + 1) * dir2;
bitp = true;
if (!UGLHelper.GetIntersection(ltp, ltp + ldist, ntp, ntp + rdist, ref itp))
{
itp = cp + dir1v * width;
itp = cp - dir1v * width;
clp = cp - dir1v * width;
crp = cp - dir2v * width;
bitp = false;
}
bibp = true;
if (!UGLHelper.GetIntersection(lbp, lbp + ldist, nbp, nbp + rdist, ref ibp))
{
ibp = cp - dir1v * width;
ibp = cp + dir1v * width;
clp = cp + dir1v * width;
crp = cp + dir2v * width;
bibp = false;
}
}
}

View File

@@ -166,7 +166,7 @@ QualitySettings:
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
vSyncCount: 0
lodBias: 2
maximumLODLevel: 0
particleRaycastBudget: 4096