diff --git a/Assets/XCharts/Scripts/Editor/PropertyDrawers/SerieDrawer.cs b/Assets/XCharts/Scripts/Editor/PropertyDrawers/SerieDrawer.cs
index 51481688..a581026c 100644
--- a/Assets/XCharts/Scripts/Editor/PropertyDrawers/SerieDrawer.cs
+++ b/Assets/XCharts/Scripts/Editor/PropertyDrawers/SerieDrawer.cs
@@ -31,6 +31,8 @@ namespace XCharts
SerializedProperty m_LineArrow = prop.FindPropertyRelative("m_LineArrow");
SerializedProperty m_LineType = prop.FindPropertyRelative("m_LineType");
SerializedProperty m_SampleDist = prop.FindPropertyRelative("m_SampleDist");
+ SerializedProperty m_SampleType = prop.FindPropertyRelative("m_SampleType");
+ SerializedProperty m_SampleAverage = prop.FindPropertyRelative("m_SampleAverage");
SerializedProperty m_BarWidth = prop.FindPropertyRelative("m_BarWidth");
SerializedProperty m_BarGap = prop.FindPropertyRelative("m_BarGap");
SerializedProperty m_BarCategoryGap = prop.FindPropertyRelative("m_BarCategoryGap");
@@ -98,6 +100,10 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SampleDist);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(drawRect, m_SampleType);
+ drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
+ EditorGUI.PropertyField(drawRect, m_SampleAverage);
+ drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
if (serieType == SerieType.Line
|| serieType == SerieType.Scatter
@@ -361,7 +367,7 @@ namespace XCharts
if (serieType == SerieType.Line)
{
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_LineArrow"));
- height += 2 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
+ height += 4 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing;
}
if (serieType == SerieType.Bar)
{
@@ -371,7 +377,7 @@ namespace XCharts
{
SerializedProperty m_Data = prop.FindPropertyRelative("m_Data");
int num = m_Data.arraySize + 2;
- if (num > 30) num = 14;
+ if (num > 30) num = 15;
if (prop.FindPropertyRelative("m_ShowDataIcon").boolValue)
{
num *= 5;
diff --git a/Assets/XCharts/Scripts/UI/Component/Serie.cs b/Assets/XCharts/Scripts/UI/Component/Serie.cs
index 6369554f..6110dc20 100644
--- a/Assets/XCharts/Scripts/UI/Component/Serie.cs
+++ b/Assets/XCharts/Scripts/UI/Component/Serie.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.ComponentModel;
using UnityEngine;
-using UnityEngine.Serialization;
namespace XCharts
{
@@ -111,6 +110,33 @@ namespace XCharts
DashDotDot
}
+ ///
+ /// 采样类型
+ ///
+ public enum SampleType
+ {
+ ///
+ /// 取峰值。
+ ///
+ Peak,
+ ///
+ /// 取过滤点的平均值。
+ ///
+ Average,
+ ///
+ /// 取过滤点的最大值。
+ ///
+ Max,
+ ///
+ /// 取过滤点的最小值。
+ ///
+ Min,
+ ///
+ /// 取过滤点的和。
+ ///
+ Sum
+ }
+
///
/// 系列。每个系列通过 type 决定自己的图表类型。
///
@@ -130,6 +156,9 @@ namespace XCharts
[SerializeField] private SerieSymbol m_Symbol = new SerieSymbol();
[SerializeField] private LineType m_LineType = LineType.Normal;
[SerializeField] private float m_SampleDist = 0;
+ [SerializeField] private SampleType m_SampleType = SampleType.Average;
+ [SerializeField] private float m_SampleAverage = 0;
+
[SerializeField] private LineStyle m_LineStyle = new LineStyle();
[SerializeField] private float m_BarWidth = 0.6f;
[SerializeField] private float m_BarGap = 0.3f; // 30%
@@ -242,6 +271,16 @@ namespace XCharts
///
public float sampleDist { get { return m_SampleDist; } set { m_SampleDist = value < 0 ? 0 : value; } }
///
+ /// the type of sample.
+ /// 采样类型。当sampleDist大于0时有效。
+ ///
+ public SampleType sampleType { get { return m_SampleType; } set { m_SampleType = value; } }
+ ///
+ /// 设定的采样平均值。当sampleType 为 Peak 时,用于和过滤数据的平均值做对比是取最大值还是最小值。默认为0时会实时计算所有数据的平均值。
+ ///
+ ///
+ public float sampleAverage { get { return m_SampleAverage; } set { m_SampleAverage = value; } }
+ ///
/// The style of line.
/// 线条样式。
///
diff --git a/Assets/XCharts/Scripts/UI/Internal/CoordinateChart_DrawLine.cs b/Assets/XCharts/Scripts/UI/Internal/CoordinateChart_DrawLine.cs
index 7f9bef6c..a373d6f9 100644
--- a/Assets/XCharts/Scripts/UI/Internal/CoordinateChart_DrawLine.cs
+++ b/Assets/XCharts/Scripts/UI/Internal/CoordinateChart_DrawLine.cs
@@ -101,6 +101,8 @@ namespace XCharts
if (sampleDist > 0) rate = (int)((maxCount - serie.minShow) / (coordinateWid / sampleDist));
if (rate < 1) rate = 1;
var includeLastData = false;
+ var totalAverage = serie.sampleAverage > 0 ? serie.sampleAverage :
+ DataAverage(ref showData, serie.sampleType, serie.minShow, maxCount, rate);
for (i = serie.minShow; i < maxCount; i += rate)
{
if (i == maxCount - 1) includeLastData = true;
@@ -108,7 +110,7 @@ namespace XCharts
{
for (int j = 0; j < rate; j++) seriesHig.Add(0);
}
- float yValue = showData[i].data[1];
+ float yValue = SampleValue(ref showData, serie.sampleType, rate, serie.minShow, maxCount, totalAverage, i);
seriesHig[i] += GetDataPoint(xAxis, yAxis, showData, yValue, startX, i, scaleWid, seriesHig[i], ref np);
serie.dataPoints.Add(np);
}
@@ -186,6 +188,71 @@ namespace XCharts
}
}
+ private float DataAverage(ref List showData, SampleType sampleType, int minCount, int maxCount, int rate)
+ {
+ var totalAverage = 0f;
+ if (rate > 1 && sampleType == SampleType.Peak)
+ {
+ var total = 0f;
+ for (int i = minCount; i < maxCount; i++)
+ {
+ total += showData[i].data[1];
+ }
+ totalAverage = total / (maxCount - minCount);
+ }
+ return totalAverage;
+ }
+
+ private float SampleValue(ref List showData, SampleType sampleType, int rate,
+ int minCount, int maxCount, float totalAverage, int index)
+ {
+ if (rate <= 1 || index == minCount) return showData[index].data[1];
+ switch (sampleType)
+ {
+ case SampleType.Sum:
+ case SampleType.Average:
+ float total = 0;
+ for (int i = index; i > index - rate; i--)
+ {
+ total += showData[i].data[1];
+ }
+ if (sampleType == SampleType.Average) return total / rate;
+ else return total;
+ case SampleType.Max:
+ float max = float.MinValue;
+ for (int i = index; i > index - rate; i--)
+ {
+ var value = showData[i].data[1];
+ if (value > max) max = value;
+ }
+ return max;
+ case SampleType.Min:
+ float min = float.MaxValue;
+ for (int i = index; i > index - rate; i--)
+ {
+ var value = showData[i].data[1];
+ if (value < min) min = value;
+ }
+ return min;
+ case SampleType.Peak:
+ max = float.MinValue;
+ min = float.MaxValue;
+ total = 0;
+ for (int i = index; i > index - rate; i--)
+ {
+ var value = showData[i].data[1];
+ total += value;
+ if (value < min) min = value;
+ if (value > max) max = value;
+ }
+ var average = total / rate;
+ if (average >= totalAverage) return max;
+ else return min;
+
+ }
+ return showData[index].data[1];
+ }
+
private float GetDetailProgress(Serie serie, Axis axis, Vector3 lp, Vector3 np, Vector3 llp,
Vector3 nnp, bool fine)
{
diff --git a/Doc/XCharts配置项手册.md b/Doc/XCharts配置项手册.md
index 19ef512c..e7142144 100644
--- a/Doc/XCharts配置项手册.md
+++ b/Doc/XCharts配置项手册.md
@@ -293,8 +293,15 @@
* `radarIndex`:雷达图所使用的 `radar` 组件的 `index`。
* `minShow`:系列显示数据的最小索引。
* `maxShow`:系列显示数据的最大索引。
-* `maxCache`:系列中可缓存的最大数据量。默认为0没有限制,大于0时超过指定值会移除旧数据再插入新数据。
-* `sampleDist`采样的最小水平像素距离,默认为0时不采样。当两个数据点间的水平像素距离小于该值时,开启采样,保证两点间的水平像素距离不小于该值。
+* `maxCache`:系列中可缓存的最大数据量。默认为`0`没有限制,大于0时超过指定值会移除旧数据再插入新数据。
+* `sampleDist`采样的最小水平像素距离,默认为`0`时不采样。当两个数据点间的水平像素距离小于该值时,开启采样,保证两点间的水平像素距离不小于该值。
+* `sampleType`:采样类型。当`sampleDist`大于`0`时有效。支持以下五种采样类型:
+ * `Peak`:取峰值。当过滤点的平均值大于等于`sampleAverage`时,取最大值;反之取最小值。
+ * `Average`:取过滤点的平均值。
+ * `Max`:取过滤点的最大值。
+ * `Min`:取过滤点的最小值。
+ * `Sum`:取过滤点之和。
+* `sampleAverage`:设定的采样平均值。当 `sampleType` 为 `Peak` 时,用于和过滤数据的平均值做对比是取最大值还是最小值。默认为`0`时会实时计算所有数据的平均值。
* `areaStyle`:区域填充样式 `AreaStyle`。`AreaStyle`参数如下:
* `show`:是否显示区域填充。
* `origin`:区域填充的起始位置 `AreaOrigin`。有以下三种填充方式:
diff --git a/README.md b/README.md
index d8e74745..09e27c65 100644
--- a/README.md
+++ b/README.md
@@ -28,6 +28,7 @@ QQ交流群:XCharts交流群(202030963)
## 更新日志
+* (2019.09.29)增加`Serie`采样类型`sampleType`的相关配置
* (2019.09.29)增加`SerieSymbol`关于显示间隔的相关配置
* (2019.09.29)重构代码:
1. `BaseChart`的`sampleDist`删除,`Serie`增加`lineSampleDist`