diff --git a/Assets/XCharts/Editor/PropertyDrawers/SerieDrawer.cs b/Assets/XCharts/Editor/PropertyDrawers/SerieDrawer.cs
index 4701cfd7..40e7d8a2 100644
--- a/Assets/XCharts/Editor/PropertyDrawers/SerieDrawer.cs
+++ b/Assets/XCharts/Editor/PropertyDrawers/SerieDrawer.cs
@@ -108,6 +108,7 @@ namespace XCharts
PropertyField(prop, "m_Space");
PropertyTwoFiled(prop, "m_Center");
PropertyTwoFiled(prop, "m_Radius");
+ PropertyField(prop, "m_MinAngle");
PropertyField(prop, "m_RoundCap");
PropertyField(prop, "m_Ignore");
PropertyField(prop, "m_IgnoreValue");
diff --git a/Assets/XCharts/Runtime/Component/Main/Serie.cs b/Assets/XCharts/Runtime/Component/Main/Serie.cs
index 61426656..71c4f1bb 100644
--- a/Assets/XCharts/Runtime/Component/Main/Serie.cs
+++ b/Assets/XCharts/Runtime/Component/Main/Serie.cs
@@ -256,6 +256,7 @@ namespace XCharts
[SerializeField] private float m_Max;
[SerializeField] private float m_StartAngle;
[SerializeField] private float m_EndAngle;
+ [SerializeField] private float m_MinAngle;
[SerializeField] private bool m_Clockwise = true;
[FormerlySerializedAs("m_ArcShaped")]
[SerializeField] private bool m_RoundCap;
@@ -632,6 +633,15 @@ namespace XCharts
set { if (PropertyUtil.SetStruct(ref m_EndAngle, value)) SetVerticesDirty(); }
}
///
+ /// The minimum angle of sector(0-360). It prevents some sector from being too small when value is small.
+ /// 最小的扇区角度(0-360)。用于防止某个值过小导致扇区太小影响交互。
+ ///
+ public float minAngle
+ {
+ get { return m_MinAngle; }
+ set { if (PropertyUtil.SetStruct(ref m_MinAngle, value)) SetVerticesDirty(); }
+ }
+ ///
/// 是否顺时针。
///
public bool clockwise
diff --git a/Assets/XCharts/Runtime/Internal/DrawSeriePie.cs b/Assets/XCharts/Runtime/Internal/DrawSeriePie.cs
index 9053e073..0abc4900 100644
--- a/Assets/XCharts/Runtime/Internal/DrawSeriePie.cs
+++ b/Assets/XCharts/Runtime/Internal/DrawSeriePie.cs
@@ -168,10 +168,11 @@ namespace XCharts
var data = serie.data;
serie.runtimeDataMax = serie.yMax;
serie.runtimePieDataTotal = serie.yTotal;
- serie.animation.InitProgress(data.Count, 0, 360);
+
SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
- float totalDegree = 360f;
+ float totalDegree = 0;
float startDegree = 0;
+ float zeroReplaceValue = 0;
int showdataCount = 0;
foreach (var sd in serie.data)
{
@@ -180,12 +181,19 @@ namespace XCharts
}
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1);
- float zeroReplaceValue = totalDegree / data.Count;
+ var dataTotalFilterMinAngle = serie.runtimePieDataTotal;
if (isAllZeroValue)
{
+ totalDegree = 360;
+ zeroReplaceValue = totalDegree / data.Count;
serie.runtimeDataMax = zeroReplaceValue;
- serie.runtimePieDataTotal = totalDegree;
+ serie.runtimePieDataTotal = 360;
}
+ else
+ {
+ dataTotalFilterMinAngle = GetTotalAngle(serie, serie.runtimePieDataTotal, ref totalDegree);
+ }
+ serie.animation.InitProgress(data.Count, 0, 360);
for (int n = 0; n < data.Count; n++)
{
var serieData = data[n];
@@ -199,12 +207,14 @@ namespace XCharts
{
continue;
}
- float degree = serie.pieRoseType == RoseType.Area ?
- (totalDegree / showdataCount) : (totalDegree * value / serie.runtimePieDataTotal);
+ float degree = serie.pieRoseType == RoseType.Area
+ ? (totalDegree / showdataCount)
+ : (totalDegree * value / dataTotalFilterMinAngle);
+ if (serie.minAngle > 0 && degree < serie.minAngle) degree = serie.minAngle;
serieData.runtimePieToAngle = startDegree + degree;
-
serieData.runtimePieOutsideRadius = serie.pieRoseType > 0 ?
- serie.runtimeInsideRadius + (serie.runtimeOutsideRadius - serie.runtimeInsideRadius) * value / serie.runtimeDataMax :
+ serie.runtimeInsideRadius +
+ (serie.runtimeOutsideRadius - serie.runtimeInsideRadius) * value / serie.runtimeDataMax :
serie.runtimeOutsideRadius;
if (serieData.highlighted)
{
@@ -238,10 +248,14 @@ namespace XCharts
if (serie.pieClickOffset && serieData.selected)
{
serieData.runtimePieOffsetRadius += chart.theme.serie.pieSelectedOffset;
- if (serieData.runtimePieInsideRadius > 0) serieData.runtimePieInsideRadius += chart.theme.serie.pieSelectedOffset;
+ if (serieData.runtimePieInsideRadius > 0)
+ {
+ serieData.runtimePieInsideRadius += chart.theme.serie.pieSelectedOffset;
+ }
serieData.runtimePieOutsideRadius += chart.theme.serie.pieSelectedOffset;
}
- serieData.runtiemPieOffsetCenter = new Vector3(serie.runtimeCenterPos.x + serieData.runtimePieOffsetRadius * currSin,
+ serieData.runtiemPieOffsetCenter = new Vector3(
+ serie.runtimeCenterPos.x + serieData.runtimePieOffsetRadius * currSin,
serie.runtimeCenterPos.y + serieData.runtimePieOffsetRadius * currCos);
}
serieData.canShowLabel = serieData.runtimePieCurrAngle >= serieData.runtimePieHalfAngle;
@@ -251,6 +265,30 @@ namespace XCharts
SerieLabelHelper.AvoidLabelOverlap(serie);
}
+ private float GetTotalAngle(Serie serie, float dataTotal, ref float totalAngle)
+ {
+ totalAngle = 360f;
+ if (serie.minAngle > 0)
+ {
+ var rate = serie.minAngle / 360;
+ var minAngleValue = dataTotal * rate;
+ foreach (var serieData in serie.data)
+ {
+ var value = serieData.GetData(1);
+ if (value < minAngleValue)
+ {
+ totalAngle -= serie.minAngle;
+ dataTotal -= value;
+ }
+ }
+ return dataTotal;
+ }
+ else
+ {
+ return dataTotal;
+ }
+ }
+
private void DrawPieCenter(VertexHelper vh, Serie serie, ItemStyle itemStyle, float insideRadius)
{
if (!ChartHelper.IsClearColor(itemStyle.centerColor))
@@ -279,8 +317,10 @@ namespace XCharts
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
if (serieData.IsDataChanged()) dataChanging = true;
var serieNameCount = chart.m_LegendRealShowName.IndexOf(serieData.legendName);
- var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieNameCount, serieData.highlighted);
- var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieNameCount, serieData.highlighted);
+ var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieNameCount,
+ serieData.highlighted);
+ var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieNameCount,
+ serieData.highlighted);
var borderWidth = itemStyle.borderWidth;
var borderColor = itemStyle.borderColor;
@@ -289,16 +329,18 @@ namespace XCharts
var drawEndDegree = serieData.runtimePieCurrAngle;
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
UGL.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius,
- serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle, drawEndDegree,
- borderWidth, borderColor, serie.pieSpace / 2, chart.settings.cicleSmoothness, needRoundCap, true);
+ serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle,
+ drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2, chart.settings.cicleSmoothness,
+ needRoundCap, true);
}
else
{
var drawEndDegree = serieData.runtimePieCurrAngle;
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
- UGL.DrawDoughnut(vh, serie.runtimeCenterPos, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
- color, toColor, Color.clear, serieData.runtimePieStartAngle, drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2,
- chart.settings.cicleSmoothness, needRoundCap, true);
+ UGL.DrawDoughnut(vh, serie.runtimeCenterPos, serieData.runtimePieInsideRadius,
+ serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle,
+ drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2, chart.settings.cicleSmoothness,
+ needRoundCap, true);
DrawPieCenter(vh, serie, itemStyle, serieData.runtimePieInsideRadius);
}
if (!serie.animation.CheckDetailBreak(serieData.runtimePieToAngle)) serie.animation.SetDataFinish(n);
@@ -432,14 +474,16 @@ namespace XCharts
pos6 = pos0 + Vector3.left * lineCircleDiff;
pos4 = pos6 + Vector3.left * r4;
}
- var pos5 = new Vector3(currAngle > 180 ? pos2.x - serieLabel.lineLength2 : pos2.x + serieLabel.lineLength2, pos2.y);
+ var pos5X = currAngle > 180 ? pos2.x - serieLabel.lineLength2 : pos2.x + serieLabel.lineLength2;
+ var pos5 = new Vector3(pos5X, pos2.y);
switch (serieLabel.lineType)
{
case SerieLabel.LineType.BrokenLine:
UGL.DrawLine(vh, pos1, pos2, pos5, serieLabel.lineWidth, color);
break;
case SerieLabel.LineType.Curves:
- UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, serieLabel.lineWidth, color, chart.settings.lineSmoothness);
+ UGL.DrawCurves(vh, pos1, pos5, pos1, pos2, serieLabel.lineWidth, color,
+ chart.settings.lineSmoothness);
break;
case SerieLabel.LineType.HorizontalLine:
UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color);
@@ -472,7 +516,10 @@ namespace XCharts
Color color = serieColor;
if (isHighlight)
{
- if (!ChartHelper.IsClearColor(serie.emphasis.label.textStyle.color)) color = serie.emphasis.label.textStyle.color;
+ if (!ChartHelper.IsClearColor(serie.emphasis.label.textStyle.color))
+ {
+ color = serie.emphasis.label.textStyle.color;
+ }
}
else if (!ChartHelper.IsClearColor(serieLabel.textStyle.color))
{
@@ -485,7 +532,9 @@ namespace XCharts
var fontSize = isHighlight
? serie.emphasis.label.textStyle.GetFontSize(chart.theme.common)
: serieLabel.textStyle.GetFontSize(chart.theme.common);
- var fontStyle = isHighlight ? serie.emphasis.label.textStyle.fontStyle : serieLabel.textStyle.fontStyle;
+ var fontStyle = isHighlight
+ ? serie.emphasis.label.textStyle.fontStyle
+ : serieLabel.textStyle.fontStyle;
serieData.labelObject.label.SetColor(color);
serieData.labelObject.label.SetFontSize(fontSize);