From 4266b07a5f69c84ca608a16d414ddd0a61bdabd5 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Mon, 30 Sep 2019 12:43:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Serie=E9=87=87=E6=A0=B7?= =?UTF-8?q?=E7=B1=BB=E5=9E=8BsampleType=E7=9A=84=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Editor/PropertyDrawers/SerieDrawer.cs | 10 ++- Assets/XCharts/Scripts/UI/Component/Serie.cs | 41 ++++++++++- .../UI/Internal/CoordinateChart_DrawLine.cs | 69 ++++++++++++++++++- Doc/XCharts配置项手册.md | 11 ++- README.md | 1 + 5 files changed, 126 insertions(+), 6 deletions(-) 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`