增加PieChartminAngle参数支持设置最小扇区角度 #117

This commit is contained in:
monitor1394
2021-03-06 08:25:43 +08:00
parent 404430e4b2
commit 117ab9e31a
3 changed files with 81 additions and 21 deletions

View File

@@ -108,6 +108,7 @@ namespace XCharts
PropertyField(prop, "m_Space"); PropertyField(prop, "m_Space");
PropertyTwoFiled(prop, "m_Center"); PropertyTwoFiled(prop, "m_Center");
PropertyTwoFiled(prop, "m_Radius"); PropertyTwoFiled(prop, "m_Radius");
PropertyField(prop, "m_MinAngle");
PropertyField(prop, "m_RoundCap"); PropertyField(prop, "m_RoundCap");
PropertyField(prop, "m_Ignore"); PropertyField(prop, "m_Ignore");
PropertyField(prop, "m_IgnoreValue"); PropertyField(prop, "m_IgnoreValue");

View File

@@ -256,6 +256,7 @@ namespace XCharts
[SerializeField] private float m_Max; [SerializeField] private float m_Max;
[SerializeField] private float m_StartAngle; [SerializeField] private float m_StartAngle;
[SerializeField] private float m_EndAngle; [SerializeField] private float m_EndAngle;
[SerializeField] private float m_MinAngle;
[SerializeField] private bool m_Clockwise = true; [SerializeField] private bool m_Clockwise = true;
[FormerlySerializedAs("m_ArcShaped")] [FormerlySerializedAs("m_ArcShaped")]
[SerializeField] private bool m_RoundCap; [SerializeField] private bool m_RoundCap;
@@ -632,6 +633,15 @@ namespace XCharts
set { if (PropertyUtil.SetStruct(ref m_EndAngle, value)) SetVerticesDirty(); } set { if (PropertyUtil.SetStruct(ref m_EndAngle, value)) SetVerticesDirty(); }
} }
/// <summary> /// <summary>
/// The minimum angle of sector(0-360). It prevents some sector from being too small when value is small.
/// 最小的扇区角度0-360。用于防止某个值过小导致扇区太小影响交互。
/// </summary>
public float minAngle
{
get { return m_MinAngle; }
set { if (PropertyUtil.SetStruct(ref m_MinAngle, value)) SetVerticesDirty(); }
}
/// <summary>
/// 是否顺时针。 /// 是否顺时针。
/// </summary> /// </summary>
public bool clockwise public bool clockwise

View File

@@ -168,10 +168,11 @@ namespace XCharts
var data = serie.data; var data = serie.data;
serie.runtimeDataMax = serie.yMax; serie.runtimeDataMax = serie.yMax;
serie.runtimePieDataTotal = serie.yTotal; serie.runtimePieDataTotal = serie.yTotal;
serie.animation.InitProgress(data.Count, 0, 360);
SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight); SerieHelper.UpdateCenter(serie, chart.chartPosition, chart.chartWidth, chart.chartHeight);
float totalDegree = 360f; float totalDegree = 0;
float startDegree = 0; float startDegree = 0;
float zeroReplaceValue = 0;
int showdataCount = 0; int showdataCount = 0;
foreach (var sd in serie.data) foreach (var sd in serie.data)
{ {
@@ -180,12 +181,19 @@ namespace XCharts
} }
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration(); float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1); bool isAllZeroValue = SerieHelper.IsAllZeroValue(serie, 1);
float zeroReplaceValue = totalDegree / data.Count; var dataTotalFilterMinAngle = serie.runtimePieDataTotal;
if (isAllZeroValue) if (isAllZeroValue)
{ {
totalDegree = 360;
zeroReplaceValue = totalDegree / data.Count;
serie.runtimeDataMax = zeroReplaceValue; 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++) for (int n = 0; n < data.Count; n++)
{ {
var serieData = data[n]; var serieData = data[n];
@@ -199,12 +207,14 @@ namespace XCharts
{ {
continue; continue;
} }
float degree = serie.pieRoseType == RoseType.Area ? float degree = serie.pieRoseType == RoseType.Area
(totalDegree / showdataCount) : (totalDegree * value / serie.runtimePieDataTotal); ? (totalDegree / showdataCount)
: (totalDegree * value / dataTotalFilterMinAngle);
if (serie.minAngle > 0 && degree < serie.minAngle) degree = serie.minAngle;
serieData.runtimePieToAngle = startDegree + degree; serieData.runtimePieToAngle = startDegree + degree;
serieData.runtimePieOutsideRadius = serie.pieRoseType > 0 ? 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; serie.runtimeOutsideRadius;
if (serieData.highlighted) if (serieData.highlighted)
{ {
@@ -238,10 +248,14 @@ namespace XCharts
if (serie.pieClickOffset && serieData.selected) if (serie.pieClickOffset && serieData.selected)
{ {
serieData.runtimePieOffsetRadius += chart.theme.serie.pieSelectedOffset; 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.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); serie.runtimeCenterPos.y + serieData.runtimePieOffsetRadius * currCos);
} }
serieData.canShowLabel = serieData.runtimePieCurrAngle >= serieData.runtimePieHalfAngle; serieData.canShowLabel = serieData.runtimePieCurrAngle >= serieData.runtimePieHalfAngle;
@@ -251,6 +265,30 @@ namespace XCharts
SerieLabelHelper.AvoidLabelOverlap(serie); 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) private void DrawPieCenter(VertexHelper vh, Serie serie, ItemStyle itemStyle, float insideRadius)
{ {
if (!ChartHelper.IsClearColor(itemStyle.centerColor)) if (!ChartHelper.IsClearColor(itemStyle.centerColor))
@@ -279,8 +317,10 @@ namespace XCharts
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted); var itemStyle = SerieHelper.GetItemStyle(serie, serieData, serieData.highlighted);
if (serieData.IsDataChanged()) dataChanging = true; if (serieData.IsDataChanged()) dataChanging = true;
var serieNameCount = chart.m_LegendRealShowName.IndexOf(serieData.legendName); var serieNameCount = chart.m_LegendRealShowName.IndexOf(serieData.legendName);
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieNameCount, serieData.highlighted); var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, serieNameCount,
var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieNameCount, serieData.highlighted); serieData.highlighted);
var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, serieNameCount,
serieData.highlighted);
var borderWidth = itemStyle.borderWidth; var borderWidth = itemStyle.borderWidth;
var borderColor = itemStyle.borderColor; var borderColor = itemStyle.borderColor;
@@ -289,16 +329,18 @@ namespace XCharts
var drawEndDegree = serieData.runtimePieCurrAngle; var drawEndDegree = serieData.runtimePieCurrAngle;
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0; var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
UGL.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius, UGL.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius,
serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle, drawEndDegree, serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle,
borderWidth, borderColor, serie.pieSpace / 2, chart.settings.cicleSmoothness, needRoundCap, true); drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2, chart.settings.cicleSmoothness,
needRoundCap, true);
} }
else else
{ {
var drawEndDegree = serieData.runtimePieCurrAngle; var drawEndDegree = serieData.runtimePieCurrAngle;
var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0; var needRoundCap = serie.roundCap && serieData.runtimePieInsideRadius > 0;
UGL.DrawDoughnut(vh, serie.runtimeCenterPos, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius, UGL.DrawDoughnut(vh, serie.runtimeCenterPos, serieData.runtimePieInsideRadius,
color, toColor, Color.clear, serieData.runtimePieStartAngle, drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2, serieData.runtimePieOutsideRadius, color, toColor, Color.clear, serieData.runtimePieStartAngle,
chart.settings.cicleSmoothness, needRoundCap, true); drawEndDegree, borderWidth, borderColor, serie.pieSpace / 2, chart.settings.cicleSmoothness,
needRoundCap, true);
DrawPieCenter(vh, serie, itemStyle, serieData.runtimePieInsideRadius); DrawPieCenter(vh, serie, itemStyle, serieData.runtimePieInsideRadius);
} }
if (!serie.animation.CheckDetailBreak(serieData.runtimePieToAngle)) serie.animation.SetDataFinish(n); if (!serie.animation.CheckDetailBreak(serieData.runtimePieToAngle)) serie.animation.SetDataFinish(n);
@@ -432,14 +474,16 @@ namespace XCharts
pos6 = pos0 + Vector3.left * lineCircleDiff; pos6 = pos0 + Vector3.left * lineCircleDiff;
pos4 = pos6 + Vector3.left * r4; 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) switch (serieLabel.lineType)
{ {
case SerieLabel.LineType.BrokenLine: case SerieLabel.LineType.BrokenLine:
UGL.DrawLine(vh, pos1, pos2, pos5, serieLabel.lineWidth, color); UGL.DrawLine(vh, pos1, pos2, pos5, serieLabel.lineWidth, color);
break; break;
case SerieLabel.LineType.Curves: 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; break;
case SerieLabel.LineType.HorizontalLine: case SerieLabel.LineType.HorizontalLine:
UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color); UGL.DrawCricle(vh, pos0, horizontalLineCircleRadius, color);
@@ -472,7 +516,10 @@ namespace XCharts
Color color = serieColor; Color color = serieColor;
if (isHighlight) 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)) else if (!ChartHelper.IsClearColor(serieLabel.textStyle.color))
{ {
@@ -485,7 +532,9 @@ namespace XCharts
var fontSize = isHighlight var fontSize = isHighlight
? serie.emphasis.label.textStyle.GetFontSize(chart.theme.common) ? serie.emphasis.label.textStyle.GetFontSize(chart.theme.common)
: serieLabel.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.SetColor(color);
serieData.labelObject.label.SetFontSize(fontSize); serieData.labelObject.label.SetFontSize(fontSize);