LineChart增加负数值支持

This commit is contained in:
monitor1394
2019-05-13 09:48:47 +08:00
parent 60c3f7b036
commit 698b7d8b9a
10 changed files with 13071 additions and 795 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -44,7 +44,6 @@ namespace XCharts
float scaleWid = m_YAxis.GetDataWidth(coordinateHig);
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
float offset = (scaleWid - barWid * seriesCount - m_Bar.space * (seriesCount - 1)) / 2;
float max = GetMaxValue();
int serieCount = 0;
for (int j = 0; j < seriesCount; j++)
{
@@ -68,7 +67,7 @@ namespace XCharts
float pX = seriesCurrHig[i] + zeroX + m_Coordinate.tickness;
float pY = zeroY + i * scaleWid;
if (!m_YAxis.boundaryGap) pY -= scaleWid / 2;
float barHig = data / max * coordinateWid;
float barHig = data / maxValue * coordinateWid;
float space = offset + j * (barWid + m_Bar.space);
seriesCurrHig[i] += barHig;
Vector3 p1 = new Vector3(pX, pY + space + barWid);
@@ -105,7 +104,6 @@ namespace XCharts
float scaleWid = m_XAxis.GetDataWidth(coordinateWid);
float barWid = m_Bar.barWidth > 1 ? m_Bar.barWidth : scaleWid * m_Bar.barWidth;
float offset = (scaleWid - barWid * seriesCount - m_Bar.space * (seriesCount - 1)) / 2;
float max = GetMaxValue();
int serieCount = 0;
for (int j = 0; j < seriesCount; j++)
{
@@ -129,7 +127,7 @@ namespace XCharts
float pX = zeroX + i * scaleWid;
if (!m_XAxis.boundaryGap) pX -= scaleWid / 2;
float pY = seriesCurrHig[i] + zeroY + m_Coordinate.tickness;
float barHig = data / max * coordinateHig;
float barHig = data / maxValue * coordinateHig;
seriesCurrHig[i] += barHig;
float space = offset + j * (barWid + m_Bar.space);
Vector3 p1 = new Vector3(pX + space, pY);

View File

@@ -130,11 +130,12 @@ namespace XCharts
return coordinateWidth / (m_BoundaryGap ? data.Count : data.Count - 1);
}
public string GetScaleName(int index, float maxData = 0)
public string GetScaleName(int index, float minValue = 0, float maxValue = 0)
{
if (m_Type == AxisType.Value)
{
return ((int)(maxData * index / (GetSplitNumber() -1))).ToString();
float value = (minValue + (maxValue - minValue) * index / (GetSplitNumber() - 1));
return (value).ToString();
}
int dataCount = data.Count;
if (dataCount <= 0) return "";

View File

@@ -215,12 +215,6 @@ namespace XCharts
return m_Legend.location.GetPosition(chartWidth, chartHeight);
}
protected float GetMaxValue()
{
if (m_Series == null) return 100;
else return m_Series.GetMaxValue(m_Legend);
}
protected float GetMaxValue(int index)
{
if (m_Series == null) return 100;

View File

@@ -15,17 +15,21 @@ namespace XCharts
[SerializeField] protected XAxis m_XAxis = XAxis.defaultXAxis;
[SerializeField] protected YAxis m_YAxis = YAxis.defaultYAxis;
[NonSerialized] private float m_LastXMaxValue;
[NonSerialized] private float m_LastYMaxValue;
[NonSerialized] private XAxis m_CheckXAxis = XAxis.defaultXAxis;
[NonSerialized] private YAxis m_CheckYAxis = YAxis.defaultYAxis;
[NonSerialized] private Coordinate m_CheckCoordinate = Coordinate.defaultCoordinate;
private float m_ZeroXOffset;
private float m_ZeroYOffset;
protected List<Text> m_SplitYTextList = new List<Text>();
protected List<Text> m_SplitXTextList = new List<Text>();
private XAxis m_CheckXAxis = XAxis.defaultXAxis;
private YAxis m_CheckYAxis = YAxis.defaultYAxis;
private Coordinate m_CheckCoordinate = Coordinate.defaultCoordinate;
private List<Text> m_SplitYTextList = new List<Text>();
private List<Text> m_SplitXTextList = new List<Text>();
public float zeroX { get { return m_Coordinate.left; } }
public float zeroY { get { return m_Coordinate.bottom; } }
public int minValue { get; private set; }
public int maxValue { get; private set; }
public float zeroX { get { return coordinateX + m_ZeroXOffset; } }
public float zeroY { get { return coordinateY + m_ZeroYOffset; } }
public float coordinateX { get { return m_Coordinate.left; } }
public float coordinateY { get { return m_Coordinate.bottom; } }
public float coordinateWid { get { return chartWidth - m_Coordinate.left - m_Coordinate.right; } }
public float coordinateHig { get { return chartHeight - m_Coordinate.top - m_Coordinate.bottom; } }
public Axis xAxis { get { return m_XAxis; } }
@@ -34,6 +38,7 @@ namespace XCharts
protected override void Awake()
{
base.Awake();
CheckMinMaxValue();
InitSplitX();
InitSplitY();
}
@@ -43,7 +48,7 @@ namespace XCharts
base.Update();
CheckYAxis();
CheckXAxis();
CheckMaxValue();
CheckMinMaxValue();
CheckCoordinate();
}
@@ -226,7 +231,6 @@ namespace XCharts
private void InitSplitY()
{
m_SplitYTextList.Clear();
float max = GetMaxValue();
float splitWidth = m_YAxis.GetScaleWidth(coordinateHig);
var titleObject = ChartHelper.AddObject(s_DefaultSplitNameY, transform, chartAnchorMin,
@@ -241,7 +245,7 @@ namespace XCharts
Vector2.zero, new Vector2(1, 0.5f), new Vector2(m_Coordinate.left, 20),
m_Coordinate.fontSize, m_XAxis.textRotation);
txt.transform.localPosition = GetSplitYPosition(splitWidth, i);
txt.text = m_YAxis.GetScaleName(i, max);
txt.text = m_YAxis.GetScaleName(i, minValue, maxValue);
txt.gameObject.SetActive(m_YAxis.show);
m_SplitYTextList.Add(txt);
}
@@ -250,7 +254,6 @@ namespace XCharts
public void InitSplitX()
{
m_SplitXTextList.Clear();
float max = GetMaxValue();
float splitWidth = m_XAxis.GetScaleWidth(coordinateWid);
var titleObject = ChartHelper.AddObject(s_DefaultSplitNameX, transform, chartAnchorMin,
@@ -266,7 +269,7 @@ namespace XCharts
m_Coordinate.fontSize, m_XAxis.textRotation);
txt.transform.localPosition = GetSplitXPosition(splitWidth, i);
txt.text = m_XAxis.GetScaleName(i, max);
txt.text = m_XAxis.GetScaleName(i, minValue, maxValue);
txt.gameObject.SetActive(m_XAxis.show);
m_SplitXTextList.Add(txt);
}
@@ -276,13 +279,13 @@ namespace XCharts
{
if (m_YAxis.boundaryGap)
{
return new Vector3(zeroX - m_YAxis.axisTick.length - 2f,
zeroY + (i + 0.5f) * scaleWid, 0);
return new Vector3(coordinateX - m_YAxis.axisTick.length - 2f,
coordinateY + (i + 0.5f) * scaleWid, 0);
}
else
{
return new Vector3(zeroX - m_YAxis.axisTick.length - 2f,
zeroY + i * scaleWid, 0);
return new Vector3(coordinateX - m_YAxis.axisTick.length - 2f,
coordinateY + i * scaleWid, 0);
}
}
@@ -290,12 +293,12 @@ namespace XCharts
{
if (m_XAxis.boundaryGap)
{
return new Vector3(zeroX + (i + 1) * scaleWid, zeroY - m_XAxis.axisTick.length - 5, 0);
return new Vector3(coordinateX + (i + 1) * scaleWid, coordinateY - m_XAxis.axisTick.length - 5, 0);
}
else
{
return new Vector3(zeroX + (i + 1 - 0.5f) * scaleWid,
zeroY - m_XAxis.axisTick.length - 10, 0);
return new Vector3(coordinateX + (i + 1 - 0.5f) * scaleWid,
coordinateY - m_XAxis.axisTick.length - 10, 0);
}
}
@@ -326,27 +329,29 @@ namespace XCharts
}
}
private void CheckMaxValue()
private void CheckMinMaxValue()
{
if (m_XAxis.type == Axis.AxisType.Value)
int tempMinValue = 0;
int tempMaxValue = 100;
if(m_Series != null)
{
float max = GetMaxValue();
if (m_LastXMaxValue != max)
m_Series.GetMinMaxValue(m_Legend, out tempMinValue, out tempMaxValue);
}
if (tempMinValue != minValue || tempMaxValue != maxValue)
{
minValue = tempMinValue;
maxValue = tempMaxValue;
if (m_XAxis.type == Axis.AxisType.Value)
{
m_LastXMaxValue = max;
m_ZeroXOffset = Mathf.Abs(minValue) * (coordinateWid / (Mathf.Abs(minValue) + Mathf.Abs(maxValue)));
OnXMaxValueChanged();
}
}
else if (m_YAxis.type == Axis.AxisType.Value)
{
float max = GetMaxValue();
if (m_LastYMaxValue != max)
else if (m_YAxis.type == Axis.AxisType.Value)
{
m_LastYMaxValue = max;
m_ZeroYOffset = Mathf.Abs(minValue) * (coordinateHig / (Mathf.Abs(minValue) + Mathf.Abs(maxValue)));
OnYMaxValueChanged();
}
RefreshChart();
}
}
@@ -366,15 +371,6 @@ namespace XCharts
InitSplitX();
}
protected virtual void OnXMaxValueChanged()
{
float max = GetMaxValue();
for (int i = 0; i < m_SplitXTextList.Count; i++)
{
m_SplitXTextList[i].text = m_XAxis.GetScaleName(i, max);
}
}
protected override void OnSizeChanged()
{
base.OnSizeChanged();
@@ -384,10 +380,17 @@ namespace XCharts
protected override void OnYMaxValueChanged()
{
float max = GetMaxValue();
for (int i = 0; i < m_SplitYTextList.Count; i++)
{
m_SplitYTextList[i].text = m_YAxis.GetScaleName(i, max);
m_SplitYTextList[i].text = m_YAxis.GetScaleName(i, minValue, maxValue);
}
}
protected virtual void OnXMaxValueChanged()
{
for (int i = 0; i < m_SplitXTextList.Count; i++)
{
m_SplitXTextList[i].text = m_XAxis.GetScaleName(i, minValue, maxValue);
}
}
@@ -396,63 +399,66 @@ namespace XCharts
#region draw tick and splitline
if (m_YAxis.show)
{
for (int i = 1; i < m_YAxis.GetScaleNumber(); i++)
for (int i = 0; i < m_YAxis.GetScaleNumber(); i++)
{
float pX = zeroX - m_YAxis.axisTick.length;
float pY = zeroY + i * m_YAxis.GetScaleWidth(coordinateHig);
float pX = coordinateX - m_YAxis.axisTick.length;
float pY = coordinateY + i * m_YAxis.GetScaleWidth(coordinateHig);
if (m_YAxis.boundaryGap && m_YAxis.axisTick.alignWithLabel)
{
pY -= m_YAxis.GetScaleWidth(coordinateHig) / 2;
}
if (m_YAxis.axisTick.show)
{
ChartHelper.DrawLine(vh, new Vector3(pX, pY), new Vector3(zeroX, pY),
ChartHelper.DrawLine(vh, new Vector3(pX, pY), new Vector3(coordinateX, pY),
m_Coordinate.tickness, m_ThemeInfo.axisLineColor);
}
if (m_YAxis.showSplitLine)
{
DrawSplitLine(vh, true, m_YAxis.splitLineType, new Vector3(zeroX, pY),
new Vector3(zeroX + coordinateWid, pY));
DrawSplitLine(vh, true, m_YAxis.splitLineType, new Vector3(coordinateX, pY),
new Vector3(coordinateX + coordinateWid, pY));
}
}
}
if (m_XAxis.show)
{
for (int i = 1; i < m_XAxis.GetScaleNumber(); i++)
for (int i = 0; i < m_XAxis.GetScaleNumber(); i++)
{
float pX = zeroX + i * m_XAxis.GetScaleWidth(coordinateWid);
float pY = zeroY - m_XAxis.axisTick.length - 2;
float pX = coordinateX + i * m_XAxis.GetScaleWidth(coordinateWid);
float pY = 0;
if (m_XAxis.boundaryGap && m_XAxis.axisTick.alignWithLabel)
{
pX -= m_XAxis.GetScaleWidth(coordinateWid) / 2;
}
if (m_XAxis.axisTick.show)
{
pY += zeroY - m_XAxis.axisTick.length - 2;
ChartHelper.DrawLine(vh, new Vector3(pX, zeroY), new Vector3(pX, pY), m_Coordinate.tickness,
m_ThemeInfo.axisLineColor);
}
if (m_XAxis.showSplitLine)
{
DrawSplitLine(vh, false, m_XAxis.splitLineType, new Vector3(pX, zeroY),
new Vector3(pX, zeroY + coordinateHig));
pY += coordinateY - m_XAxis.axisTick.length - 2;
DrawSplitLine(vh, false, m_XAxis.splitLineType, new Vector3(pX, coordinateY),
new Vector3(pX, coordinateY + coordinateHig));
}
}
}
#endregion
//draw x,y axis
#region draw x,y axis
if (m_YAxis.show)
{
ChartHelper.DrawLine(vh, new Vector3(zeroX, zeroY - m_YAxis.axisTick.length),
new Vector3(zeroX, zeroY + coordinateHig + 2), m_Coordinate.tickness,
m_ThemeInfo.axisLineColor);
ChartHelper.DrawLine(vh, new Vector3(coordinateX, coordinateY),
new Vector3(coordinateX, coordinateY + coordinateHig), m_Coordinate.tickness,
m_ThemeInfo.axisLineColor);
}
if (m_XAxis.show)
{
ChartHelper.DrawLine(vh, new Vector3(zeroX - m_XAxis.axisTick.length, zeroY),
new Vector3(zeroX + coordinateWid + 2, zeroY), m_Coordinate.tickness,
m_ThemeInfo.axisLineColor);
new Vector3(zeroX + coordinateWid + 2, zeroY), m_Coordinate.tickness,
m_ThemeInfo.axisLineColor);
}
#endregion
}
private void DrawSplitLine(VertexHelper vh, bool isYAxis, Axis.SplitLineType type, Vector3 startPos,

View File

@@ -42,6 +42,22 @@ namespace XCharts
}
}
public float Min
{
get
{
float min = int.MaxValue;
foreach (var data in data)
{
if (data < min)
{
min = data;
}
}
return min;
}
}
public float Total
{
get

View File

@@ -28,15 +28,15 @@ namespace XCharts
public void ClearData()
{
foreach(var serie in m_Series)
foreach (var serie in m_Series)
{
serie.ClearData();
}
}
public float GetData(int serieIndex,int dataIndex)
public float GetData(int serieIndex, int dataIndex)
{
if(serieIndex >= 0 && serieIndex < Count)
if (serieIndex >= 0 && serieIndex < Count)
{
return m_Series[serieIndex].GetData(dataIndex);
}
@@ -90,8 +90,9 @@ namespace XCharts
}
}
public float GetMaxValue(Legend legend)
public void GetMinMaxValue(Legend legend, out int minVaule, out int maxValue)
{
float min = int.MaxValue;
float max = int.MinValue;
if (IsStack())
{
@@ -109,35 +110,51 @@ namespace XCharts
seriesTotalValue[j] = seriesTotalValue[j] + serie.data[j];
}
}
float tmax = 0;
float tmax = int.MinValue;
float tmin = int.MaxValue;
foreach (var tt in seriesTotalValue)
{
if (tt.Value > tmax) tmax = tt.Value;
if (tt.Value < tmin) tmin = tt.Value;
}
if (tmax > max) max = tmax;
if (tmin < min) min = tmin;
}
}
else
{
for (int i = 0; i < m_Series.Count; i++)
{
if (legend.IsShowSeries(i) && m_Series[i].Max > max) max = m_Series[i].Max;
if (legend.IsShowSeries(i))
{
if (m_Series[i].Max > max) max = m_Series[i].Max;
if (m_Series[i].Min < min) min = m_Series[i].Min;
}
}
}
if (max == int.MinValue) return 100;
if (max < 1 && max > -1) return max;
int bigger = (int)Mathf.Abs(max);
int n = 1;
while (bigger / (Mathf.Pow(10, n)) > 10)
if (max == int.MinValue && min == int.MaxValue)
{
n++;
minVaule = 0;
maxValue = 100;
}
else if (max > 0 && min > 0)
{
minVaule = 0;
maxValue = ChartHelper.GetMaxDivisibleValue(max);
}
else if (min < 0 && max < 0)
{
minVaule = ChartHelper.GetMaxDivisibleValue(min);
maxValue = 0;
}
else
{
minVaule = ChartHelper.GetMaxDivisibleValue(min);
maxValue = ChartHelper.GetMaxDivisibleValue(max);
}
float mm = bigger < 10 ? bigger : ((bigger - bigger % (Mathf.Pow(10, n))) + Mathf.Pow(10, n));
if (max < 0) return -mm;
else return mm;
}
public float GetMaxValue(int index,int splitNumber = 0)
public float GetMaxValue(int index, int splitNumber = 0)
{
float max = int.MinValue;
float min = int.MaxValue;
@@ -154,16 +171,7 @@ namespace XCharts
}
if (max < 1 && max > -1) return max;
if (max < 0 && min < 0) max = min;
int bigger = (int)Mathf.Abs(max);
int n = 1;
while (bigger / (Mathf.Pow(10, n)) > 10)
{
n++;
}
float mm = bigger < 10 ? bigger : ((bigger - bigger % (Mathf.Pow(10, n))) + Mathf.Pow(10, n));
if (max < 1 && max > -1) return max;
else if (max < 0) return -mm;
else return mm;
return ChartHelper.GetMaxDivisibleValue(max);
}
public bool IsStack()

View File

@@ -27,7 +27,6 @@ namespace XCharts
{
base.DrawChart(vh);
int seriesCount = m_Series.Count;
float max = GetMaxValue();
float scaleWid = m_XAxis.GetDataWidth(coordinateWid);
for (int j = 0; j < seriesCount; j++)
{
@@ -41,11 +40,12 @@ namespace XCharts
int maxCount = maxShowDataNumber > 0 ?
(maxShowDataNumber > serie.data.Count ? serie.data.Count : maxShowDataNumber)
: serie.data.Count;
for (int i = minShowDataNumber; i < maxCount; i++)
{
float value = serie.data[i];
np = new Vector3(startX + i * scaleWid, zeroY + value * coordinateHig / max);
float dataHig = coordinateY + (value - minValue) / (maxValue - minValue) * coordinateHig;
np = new Vector3(startX + i * scaleWid, dataHig);
if (i > 0)
{
if (m_Line.smooth)
@@ -79,9 +79,8 @@ namespace XCharts
for (int i = 0; i < serie.data.Count; i++)
{
float value = serie.data[i];
Vector3 p = new Vector3(startX + i * scaleWid,
zeroY + value * coordinateHig / max);
float dataHig = coordinateY + (value - minValue) / (maxValue - minValue) * coordinateHig;
Vector3 p = new Vector3(startX + i * scaleWid,dataHig);
float pointWid = m_Line.pointWidth;
if (m_Tooltip.show && i == m_Tooltip.dataIndex - 1)
{

View File

@@ -436,5 +436,31 @@ namespace XCharts
ColorUtility.TryParseHtmlString(hexColorStr, out color);
return (Color32)color;
}
public static int GetMaxDivisibleValue(float max)
{
if (max == 0) return 0;
int bigger = (int)Mathf.Abs(max);
int n = 1;
while (bigger / (Mathf.Pow(10, n)) > 10)
{
n++;
}
float mm = bigger;
if(mm > 10)
{
mm = bigger - bigger % (Mathf.Pow(10, n));
//if (mm + Mathf.Pow(10, n) / 2 > bigger)
//{
// mm += Mathf.Pow(10, n) / 2;
//}
//else
{
mm += Mathf.Pow(10, n);
}
}
if (max < 0) return (int)-mm;
else return (int)mm;
}
}
}