增加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");
PropertyTwoFiled(prop, "m_Center");
PropertyTwoFiled(prop, "m_Radius");
PropertyField(prop, "m_MinAngle");
PropertyField(prop, "m_RoundCap");
PropertyField(prop, "m_Ignore");
PropertyField(prop, "m_IgnoreValue");

View File

@@ -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(); }
}
/// <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>
public bool clockwise

View File

@@ -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);