mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-14 20:00:09 +00:00
增加RingChart环形图
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
|
||||
# 更新日志
|
||||
|
||||
* (2020.03.08) 增加`RingChart`环形图
|
||||
* (2020.03.05) 调整`Serie`的`arcShaped`参数重命名为`roundCap`
|
||||
* (2020.03.05) 增加运行时和非运行时参数变更自动刷新图表
|
||||
* (2020.02.26) 重构`Legend`图例,改变样式,增加自定义图标等设置
|
||||
|
||||
@@ -107,6 +107,13 @@
|
||||
* 继承自 `BaseChart`。
|
||||
* 继承自 `CoordinateChart`。
|
||||
|
||||
## `RingChart`
|
||||
|
||||
* 继承自 `BaseChart`。
|
||||
* `RingChart.UpdateMax(int serieIndex, int dataIndex, float value)`:更新指定系列执行数据项的最大值。
|
||||
* `RingChart.UpdateMax(int serieIndex, float value)`:更新指定系列的所有数据项的最大值。
|
||||
* `RingChart.UpdateMax(float value)`:更新第一个系列第一个数据项的最大值。
|
||||
|
||||
[返回首页](https://github.com/monitor1394/unity-ugui-XCharts)
|
||||
[XCharts配置项手册](XCharts配置项手册.md)
|
||||
[XCharts问答](XCharts问答.md)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
* [Serie-Scatter 散点图](#Serie-Scatter)
|
||||
* [Serie-Heatmap 热力图](#Serie-Heatmap)
|
||||
* [Serie-Gauge 仪表盘](#Serie-Gauge)
|
||||
* [Serie-Ring 环形图](#Serie-Ring)
|
||||
* [Settings 设置](#Settings)
|
||||
* [Theme 主题](#Theme)
|
||||
* [Tooltip 提示框](#Tooltip)
|
||||
@@ -601,6 +602,26 @@
|
||||
* `animation`:起始动画 [SerieAnimation](#SerieAnimation)。
|
||||
* `data`:系列中的数据项 [SerieData](#SerieData) 数组,可以设置`1`到`n`维数据。仪表盘的数据一般只有一个,值通过`label`样式显示,`name`通过`titleStyle`样式显示。
|
||||
|
||||
## `Serie-Ring`
|
||||
|
||||
环形图系列。
|
||||
|
||||
* `show`:系列是否显示在图表上。
|
||||
* `type`:`Ring`。
|
||||
* `name`:系列名称。用于 `tooltip` 的显示,`legend` 的图例筛选。
|
||||
* `center`:中心点坐标。当值为0-1的浮点数时表示百分比。
|
||||
* `radius`:仪表盘半径。
|
||||
* `startAngle`:仪表盘起始角度。和时钟一样,12点钟位置是0度,顺时针到360度。
|
||||
* `ringGap`:环形图的环间隙。
|
||||
* `roundCap`:是否启用圆弧效果。
|
||||
* `clockwise`:是否顺时针,默认为`true`。
|
||||
* `titleStyle`:环形图中心标题 [TitleStyle](#TitleStyle)。
|
||||
* `itemStyle`:环形图的圆环样式,包括设置背景颜色和边框等 [ItemStyle](#ItemStyle)。
|
||||
* `label`:图形上的文本标签 [SerieLabel](#SerieLabel),可用于说明图形的一些数据信息,比如值,名称等。
|
||||
* `emphasis`:高亮样式 [Emphasis](#Emphasis)。
|
||||
* `animation`:起始动画 [SerieAnimation](#SerieAnimation)。
|
||||
* `data`:系列中的数据项 [SerieData](#SerieData) 数组,可以设置`1`到`n`维数据。环形图的数据只有二维,`data[0]`表示当前值,`data[1]`表示最大值。
|
||||
|
||||
## `Settings`
|
||||
|
||||
全局参数设置组件。一般情况下可使用默认值,当有需要时可进行调整。
|
||||
@@ -701,6 +722,8 @@
|
||||
|
||||
* `show`:是否启用。
|
||||
* `color`:颜色。
|
||||
* `backgroundColor`:背景颜色。
|
||||
* `backgroundWidth`:背景的宽。
|
||||
* `borderType`:边框的类型。
|
||||
* `borderColor`:边框的颜色。
|
||||
* `borderWidth`:边框宽。
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace XCharts
|
||||
drawRect.height = EditorGUIUtility.singleLineHeight;
|
||||
SerializedProperty show = prop.FindPropertyRelative("m_Show");
|
||||
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
|
||||
SerializedProperty m_BackgroundColor = prop.FindPropertyRelative("m_BackgroundColor");
|
||||
SerializedProperty m_BackgroundWidth = prop.FindPropertyRelative("m_BackgroundWidth");
|
||||
SerializedProperty m_CenterColor = prop.FindPropertyRelative("m_CenterColor");
|
||||
SerializedProperty m_CenterGap = prop.FindPropertyRelative("m_CenterGap");
|
||||
SerializedProperty m_BorderType = prop.FindPropertyRelative("m_BorderType");
|
||||
SerializedProperty m_BorderWidth = prop.FindPropertyRelative("m_BorderWidth");
|
||||
SerializedProperty m_BorderColor = prop.FindPropertyRelative("m_BorderColor");
|
||||
@@ -33,6 +37,14 @@ namespace XCharts
|
||||
++EditorGUI.indentLevel;
|
||||
EditorGUI.PropertyField(drawRect, m_Color);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_BackgroundColor);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_BackgroundWidth);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_CenterColor);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_CenterGap);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_BorderType);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_BorderWidth);
|
||||
@@ -50,7 +62,7 @@ namespace XCharts
|
||||
float height = 0;
|
||||
if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop))
|
||||
{
|
||||
height += 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
|
||||
height += 10 * EditorGUIUtility.singleLineHeight + 9 * EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -62,8 +62,9 @@ namespace XCharts
|
||||
SerializedProperty m_Max = prop.FindPropertyRelative("m_Max");
|
||||
SerializedProperty m_StartAngle = prop.FindPropertyRelative("m_StartAngle");
|
||||
SerializedProperty m_EndAngle = prop.FindPropertyRelative("m_EndAngle");
|
||||
SerializedProperty m_RingGap = prop.FindPropertyRelative("m_RingGap");
|
||||
SerializedProperty m_SplitNumber = prop.FindPropertyRelative("m_SplitNumber");
|
||||
//SerializedProperty m_Clockwise = prop.FindPropertyRelative("m_Clockwise");
|
||||
SerializedProperty m_Clockwise = prop.FindPropertyRelative("m_Clockwise");
|
||||
SerializedProperty m_RoundCap = prop.FindPropertyRelative("m_RoundCap");
|
||||
SerializedProperty m_GaugeType = prop.FindPropertyRelative("m_GaugeType");
|
||||
SerializedProperty m_GaugeAxis = prop.FindPropertyRelative("m_GaugeAxis");
|
||||
@@ -189,6 +190,26 @@ namespace XCharts
|
||||
EditorGUI.PropertyField(drawRect, m_Emphasis);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_Emphasis);
|
||||
break;
|
||||
case SerieType.Ring:
|
||||
ChartEditorHelper.MakeTwoField(ref drawRect, pos.width, m_Center, "Center");
|
||||
ChartEditorHelper.MakeTwoField(ref drawRect, pos.width, m_Radius, "Radius");
|
||||
EditorGUI.PropertyField(drawRect, m_StartAngle);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_RingGap);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_RoundCap);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_Clockwise);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
EditorGUI.PropertyField(drawRect, m_TitleStyle);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_TitleStyle);
|
||||
EditorGUI.PropertyField(drawRect, m_ItemStyle);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_ItemStyle);
|
||||
EditorGUI.PropertyField(drawRect, m_Label);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_Label);
|
||||
EditorGUI.PropertyField(drawRect, m_Emphasis);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_Emphasis);
|
||||
break;
|
||||
case SerieType.Radar:
|
||||
EditorGUI.PropertyField(drawRect, m_RadarIndex);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
@@ -452,6 +473,14 @@ namespace XCharts
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Emphasis"));
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Animation"));
|
||||
break;
|
||||
case SerieType.Ring:
|
||||
height += 10 * EditorGUIUtility.singleLineHeight + 9 * EditorGUIUtility.standardVerticalSpacing;
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_TitleStyle"));
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_ItemStyle"));
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Label"));
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Emphasis"));
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Animation"));
|
||||
break;
|
||||
case SerieType.Radar:
|
||||
height += 4 * EditorGUIUtility.singleLineHeight + 3 * EditorGUIUtility.standardVerticalSpacing;
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Symbol"));
|
||||
|
||||
@@ -21,14 +21,14 @@ namespace XCharts
|
||||
Rect drawRect = pos;
|
||||
drawRect.height = EditorGUIUtility.singleLineHeight;
|
||||
SerializedProperty show = prop.FindPropertyRelative("m_Show");
|
||||
SerializedProperty m_textStyle = prop.FindPropertyRelative("m_textStyle");
|
||||
SerializedProperty m_TextStyle = prop.FindPropertyRelative("m_TextStyle");
|
||||
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_TitleStyleToggle, prop, "Title Style", show, false);
|
||||
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
|
||||
if (ChartEditorHelper.IsToggle(m_TitleStyleToggle, prop))
|
||||
{
|
||||
++EditorGUI.indentLevel;
|
||||
EditorGUI.PropertyField(drawRect, m_textStyle);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_textStyle);
|
||||
EditorGUI.PropertyField(drawRect, m_TextStyle);
|
||||
drawRect.y += EditorGUI.GetPropertyHeight(m_TextStyle);
|
||||
--EditorGUI.indentLevel;
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ namespace XCharts
|
||||
if (ChartEditorHelper.IsToggle(m_TitleStyleToggle, prop))
|
||||
{
|
||||
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_textStyle"));
|
||||
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_TextStyle"));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -109,5 +109,11 @@ namespace XCharts
|
||||
{
|
||||
AddChart<GaugeChart>("GaugeChart");
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/XCharts/RingChart", priority = 51)]
|
||||
public static void AddRingChart()
|
||||
{
|
||||
AddChart<RingChart>("RingChart");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
A powerful, easy-to-use, configurable charting and data visualization library for Unity.
|
||||
|
||||
一款基于`UGUI`的功能强大、易用、参数可配置的数据可视化图表插件。支持折线图、柱状图、饼图、雷达图、散点图、热力图、仪表盘等常见图表。
|
||||
一款基于`UGUI`的功能强大、易用、参数可配置的数据可视化图表插件。支持折线图、柱状图、饼图、雷达图、散点图、热力图、仪表盘、环形图等常见图表。
|
||||
|
||||
## 特性
|
||||
|
||||
* 内置丰富示例和模板,参数可视化配置,效果实时预览,纯代码绘制。
|
||||
* 支持折线图、柱状图、饼图、雷达图、散点图、热力图、仪表盘等常见图表。
|
||||
* 支持折线图、柱状图、饼图、雷达图、散点图、热力图、仪表盘、环形图等常见图表。
|
||||
* 支持直线图、曲线图、面积图、阶梯线图等折线图。
|
||||
* 支持并列柱图、堆叠柱图、堆积百分比柱图、斑马柱图等柱状图。
|
||||
* 支持环形图、玫瑰图等饼图。
|
||||
|
||||
@@ -220,7 +220,7 @@ namespace XCharts
|
||||
/// <param name="yValue">y data</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public virtual SerieData AddData(string serieName, float xValue, float yValue, string dataName)
|
||||
public virtual SerieData AddData(string serieName, float xValue, float yValue, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddXYData(serieName, xValue, yValue, dataName);
|
||||
if (serieData != null)
|
||||
|
||||
95
Assets/XCharts/Runtime/API/RingChart_API.cs
Normal file
95
Assets/XCharts/Runtime/API/RingChart_API.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public partial class RingChart
|
||||
{
|
||||
/// <summary>
|
||||
/// 更新指定系列执行数据项的最大值
|
||||
/// </summary>
|
||||
/// <param name="serieIndex"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool UpdateMax(int serieIndex, int dataIndex, float value)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (serie != null)
|
||||
{
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
if (serieData != null)
|
||||
{
|
||||
return serieData.UpdateData(1, value);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指定系列的所有数据项的最大值
|
||||
/// </summary>
|
||||
/// <param name="serieIndex"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool UpdateMax(int serieIndex, float value)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (serie != null)
|
||||
{
|
||||
var flag = true;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (!serieData.UpdateData(1, value)) flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新第一个系列第一个数据项的最大值
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool UpdateMax(float value)
|
||||
{
|
||||
return UpdateMax(0, 0, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the data with the specified maximum value to the specified serie.
|
||||
/// 添加指定最大值的数据到指定系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="value">the data</param>
|
||||
/// <param name="max">the max data</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public override SerieData AddData(string serieName, float value, float max, string dataName = null)
|
||||
{
|
||||
return base.AddData(serieName, value, max, dataName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the data with the specified maximum value to the specified serie.
|
||||
/// 添加指定最大值的数据到指定系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie</param>
|
||||
/// <param name="value">the data</param>
|
||||
/// <param name="max">the max data</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public override SerieData AddData(int serieIndex, float value, float max, string dataName = null)
|
||||
{
|
||||
return base.AddData(serieIndex, value, max, dataName);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/API/RingChart_API.cs.meta
Normal file
11
Assets/XCharts/Runtime/API/RingChart_API.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a1cd7e0dade8470cb91d6a7971ff022
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -52,6 +52,10 @@ namespace XCharts
|
||||
/// 仪表盘。
|
||||
/// </summary>
|
||||
Gauge,
|
||||
/// <summary>
|
||||
/// 环形图。只支持一个数据的环形图。
|
||||
/// </summary>
|
||||
Ring,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -225,9 +229,11 @@ namespace XCharts
|
||||
[SerializeField] private float m_Max;
|
||||
[SerializeField] private float m_StartAngle;
|
||||
[SerializeField] private float m_EndAngle;
|
||||
[SerializeField] private bool m_Clockwise;
|
||||
[SerializeField] private bool m_Clockwise = true;
|
||||
[FormerlySerializedAs("m_ArcShaped")]
|
||||
[SerializeField] private bool m_RoundCap;
|
||||
[SerializeField] private float m_RingGap = 10f;
|
||||
|
||||
[SerializeField] private int m_SplitNumber;
|
||||
[SerializeField] private GaugeType m_GaugeType = GaugeType.Pointer;
|
||||
[SerializeField] private GaugeAxis m_GaugeAxis = new GaugeAxis();
|
||||
@@ -577,6 +583,15 @@ namespace XCharts
|
||||
get { return m_Clockwise; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_Clockwise, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 环形图的环间隙。
|
||||
/// </summary>
|
||||
public float ringGap
|
||||
{
|
||||
get { return m_RingGap; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_RingGap, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 刻度分割段数。最大可设置36。
|
||||
/// </summary>
|
||||
@@ -704,10 +719,11 @@ namespace XCharts
|
||||
label.vertsDirty ||
|
||||
emphasis.vertsDirty ||
|
||||
gaugeAxis.vertsDirty ||
|
||||
gaugePointer.vertsDirty ||
|
||||
titleStyle.vertsDirty;
|
||||
gaugePointer.vertsDirty;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool componentDirty { get { return m_ComponentDirty || titleStyle.componentDirty; } }
|
||||
internal override void ClearVerticesDirty()
|
||||
{
|
||||
base.ClearVerticesDirty();
|
||||
@@ -995,11 +1011,20 @@ namespace XCharts
|
||||
m_Data.Add(serieData);
|
||||
m_ShowDataDimension = 1;
|
||||
SetVerticesDirty();
|
||||
CheckDataName(dataName);
|
||||
return serieData;
|
||||
}
|
||||
|
||||
private void CheckDataName(string dataName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dataName))
|
||||
{
|
||||
SetNameDirty();
|
||||
}
|
||||
return serieData;
|
||||
else
|
||||
{
|
||||
m_ShowDataName = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1028,10 +1053,7 @@ namespace XCharts
|
||||
m_Data.Add(serieData);
|
||||
m_ShowDataDimension = 2;
|
||||
SetVerticesDirty();
|
||||
if (string.IsNullOrEmpty(dataName))
|
||||
{
|
||||
SetNameDirty();
|
||||
}
|
||||
CheckDataName(dataName);
|
||||
return serieData;
|
||||
}
|
||||
|
||||
@@ -1073,10 +1095,7 @@ namespace XCharts
|
||||
}
|
||||
m_Data.Add(serieData);
|
||||
SetVerticesDirty();
|
||||
if (string.IsNullOrEmpty(dataName))
|
||||
{
|
||||
SetNameDirty();
|
||||
}
|
||||
CheckDataName(dataName);
|
||||
return serieData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1033,6 +1033,7 @@ namespace XCharts
|
||||
{
|
||||
case SerieType.Pie:
|
||||
case SerieType.Radar:
|
||||
case SerieType.Ring:
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serie.data[i].name))
|
||||
|
||||
@@ -36,6 +36,10 @@ namespace XCharts
|
||||
}
|
||||
[SerializeField] private bool m_Show = false;
|
||||
[SerializeField] private Color m_Color;
|
||||
[SerializeField] private Color m_BackgroundColor;
|
||||
[SerializeField] private float m_BackgroundWidth;
|
||||
[SerializeField] private Color m_CenterColor;
|
||||
[SerializeField] private float m_CenterGap;
|
||||
[SerializeField] private Type m_BorderType = Type.Solid;
|
||||
[SerializeField] private float m_BorderWidth = 0;
|
||||
[SerializeField] private Color m_BorderColor;
|
||||
@@ -58,6 +62,38 @@ namespace XCharts
|
||||
set { if (PropertyUtility.SetColor(ref m_Color, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 数据项背景颜色。
|
||||
/// </summary>
|
||||
public Color backgroundColor
|
||||
{
|
||||
get { return m_BackgroundColor; }
|
||||
set { if (PropertyUtility.SetColor(ref m_BackgroundColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 中心区域颜色。
|
||||
/// </summary>
|
||||
public Color centerColor
|
||||
{
|
||||
get { return m_CenterColor; }
|
||||
set { if (PropertyUtility.SetColor(ref m_CenterColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 中心区域间隙。
|
||||
/// </summary>
|
||||
public float centerGap
|
||||
{
|
||||
get { return m_CenterGap; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_CenterGap, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 数据项背景颜色。
|
||||
/// </summary>
|
||||
public float backgroundWidth
|
||||
{
|
||||
get { return m_BackgroundWidth; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundWidth, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 边框的类型。
|
||||
/// </summary>
|
||||
public Type borderType
|
||||
|
||||
@@ -237,7 +237,7 @@ namespace XCharts
|
||||
return (delay > 0 && Time.time - startTime < delay / 1000);
|
||||
}
|
||||
|
||||
public bool CheckDetailBreak(int dataIndex, float detail)
|
||||
public bool CheckDetailBreak(float detail)
|
||||
{
|
||||
return !IsFinish() && detail > m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace XCharts
|
||||
public float runtimePieOffsetRadius { get; internal set; }
|
||||
public Vector3 runtiemPieOffsetCenter { get; internal set; }
|
||||
|
||||
private List<float> m_LastData = new List<float>();
|
||||
private List<float> m_PreviousData = new List<float>();
|
||||
private List<float> m_DataUpdateTime = new List<float>();
|
||||
private List<bool> m_DataUpdateFlag = new List<bool>();
|
||||
|
||||
@@ -166,15 +166,27 @@ namespace XCharts
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public float GetLastData(int index)
|
||||
public float GetPreviousData(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_LastData.Count)
|
||||
if (index >= 0 && index < m_PreviousData.Count)
|
||||
{
|
||||
return m_LastData[index];
|
||||
return m_PreviousData[index];
|
||||
}
|
||||
else return 0;
|
||||
}
|
||||
|
||||
public float GetFirstData(float animationDuration = 500f)
|
||||
{
|
||||
if (m_Data.Count > 0) return GetCurrData(0, animationDuration);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public float GetLastData()
|
||||
{
|
||||
if (m_Data.Count > 0) return m_Data[m_Data.Count - 1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
public float GetCurrData(int index, float animationDuration = 500f)
|
||||
{
|
||||
if (index < m_DataUpdateFlag.Count && m_DataUpdateFlag[index] && animationDuration > 0)
|
||||
@@ -184,7 +196,7 @@ namespace XCharts
|
||||
if (time <= total)
|
||||
{
|
||||
CheckLastData();
|
||||
var curr = Mathf.Lerp(GetLastData(index), GetData(index), time / total);
|
||||
var curr = Mathf.Lerp(GetPreviousData(index), GetData(index), time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
@@ -204,7 +216,7 @@ namespace XCharts
|
||||
if (dimension >= 0 && dimension < data.Count)
|
||||
{
|
||||
CheckLastData();
|
||||
m_LastData[dimension] = data[dimension];
|
||||
m_PreviousData[dimension] = data[dimension];
|
||||
m_DataUpdateTime[dimension] = Time.time;
|
||||
m_DataUpdateFlag[dimension] = true;
|
||||
data[dimension] = value;
|
||||
@@ -215,14 +227,14 @@ namespace XCharts
|
||||
|
||||
private void CheckLastData()
|
||||
{
|
||||
if (m_LastData.Count != m_Data.Count)
|
||||
if (m_PreviousData.Count != m_Data.Count)
|
||||
{
|
||||
m_LastData.Clear();
|
||||
m_PreviousData.Clear();
|
||||
m_DataUpdateTime.Clear();
|
||||
m_DataUpdateFlag.Clear();
|
||||
for (int i = 0; i < m_Data.Count; i++)
|
||||
{
|
||||
m_LastData.Add(m_Data[i]);
|
||||
m_PreviousData.Add(m_Data[i]);
|
||||
m_DataUpdateTime.Add(Time.time);
|
||||
m_DataUpdateFlag.Add(false);
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace XCharts
|
||||
public float backgroundHeight
|
||||
{
|
||||
get { return m_BackgroundHeight; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundWidth, value)) SetComponentDirty(); }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundHeight, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Rotate label.
|
||||
@@ -202,7 +202,7 @@ namespace XCharts
|
||||
public float rotate
|
||||
{
|
||||
get { return m_Rotate; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundWidth, value)) SetComponentDirty(); }
|
||||
set { if (PropertyUtility.SetStruct(ref m_Rotate, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the text padding of left and right. defaut:2.
|
||||
@@ -211,7 +211,7 @@ namespace XCharts
|
||||
public float paddingLeftRight
|
||||
{
|
||||
get { return m_PaddingLeftRight; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundWidth, value)) SetComponentDirty(); }
|
||||
set { if (PropertyUtility.SetStruct(ref m_PaddingLeftRight, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the text padding of top and bottom. defaut:2.
|
||||
@@ -220,7 +220,7 @@ namespace XCharts
|
||||
public float paddingTopBottom
|
||||
{
|
||||
get { return m_PaddingTopBottom; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundWidth, value)) SetComponentDirty(); }
|
||||
set { if (PropertyUtility.SetStruct(ref m_PaddingTopBottom, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// font size.
|
||||
@@ -229,7 +229,7 @@ namespace XCharts
|
||||
public int fontSize
|
||||
{
|
||||
get { return m_FontSize; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_BackgroundWidth, value)) SetAllDirty(); }
|
||||
set { if (PropertyUtility.SetStruct(ref m_FontSize, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// font style.
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace XCharts
|
||||
/// 文本的相关设置。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TextStyle : SubComponent, IEquatable<TextStyle>
|
||||
public class TextStyle : SubComponent
|
||||
{
|
||||
[SerializeField] private Font m_Font;
|
||||
[SerializeField] private float m_Rotate = 0;
|
||||
@@ -135,65 +135,5 @@ namespace XCharts
|
||||
this.color = color;
|
||||
this.rotate = rotate;
|
||||
}
|
||||
|
||||
public void Copy(TextStyle style)
|
||||
{
|
||||
this.fontSize = style.fontSize;
|
||||
this.fontStyle = style.fontStyle;
|
||||
this.color = style.color;
|
||||
this.backgroundColor = style.backgroundColor;
|
||||
this.rotate = style.rotate;
|
||||
this.offset = style.offset;
|
||||
this.lineSpacing = style.lineSpacing;
|
||||
}
|
||||
|
||||
public TextStyle Clone()
|
||||
{
|
||||
var textStyle = new TextStyle();
|
||||
textStyle.rotate = rotate;
|
||||
textStyle.color = color;
|
||||
textStyle.backgroundColor = backgroundColor;
|
||||
textStyle.fontSize = fontSize;
|
||||
textStyle.fontStyle = fontStyle;
|
||||
textStyle.offset = offset;
|
||||
textStyle.lineSpacing = lineSpacing;
|
||||
return textStyle;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (obj is TextStyle)
|
||||
{
|
||||
return Equals((TextStyle)obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Equals(TextStyle other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return rotate == other.rotate &&
|
||||
fontSize == other.fontSize &&
|
||||
fontStyle == other.fontStyle &&
|
||||
offset == other.offset &&
|
||||
lineSpacing == other.lineSpacing &&
|
||||
ChartHelper.IsValueEqualsColor(m_BackgroundColor, other.backgroundColor) &&
|
||||
ChartHelper.IsValueEqualsColor(m_Color, other.color);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
@@ -17,62 +18,42 @@ namespace XCharts
|
||||
/// 标题相关设置。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class TitleStyle : SubComponent, IEquatable<TitleStyle>
|
||||
public class TitleStyle : SubComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private TextStyle m_textStyle = new TextStyle(18);
|
||||
[FormerlySerializedAs("m_textStyle")]
|
||||
[SerializeField] private TextStyle m_TextStyle = new TextStyle(18);
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show title.
|
||||
/// 是否显示标题。
|
||||
/// </summary>
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtility.SetStruct(ref m_Show, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the color of text.
|
||||
/// 文本的颜色。
|
||||
/// </summary>
|
||||
public TextStyle textStyle { get { return m_textStyle; } set { m_textStyle = value; } }
|
||||
public TextStyle textStyle
|
||||
{
|
||||
get { return m_TextStyle; }
|
||||
set { if (PropertyUtility.SetClass(ref m_TextStyle, value, true)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
public override bool componentDirty { get { return m_ComponentDirty || textStyle.componentDirty; } }
|
||||
|
||||
internal override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
textStyle.ClearComponentDirty();
|
||||
}
|
||||
|
||||
public Text runtimeText { get; set; }
|
||||
|
||||
public TitleStyle Clone()
|
||||
{
|
||||
var title = new TitleStyle();
|
||||
title.show = show;
|
||||
title.textStyle = textStyle.Clone();
|
||||
return title;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (obj is TitleStyle)
|
||||
{
|
||||
return Equals((TitleStyle)obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Equals(TitleStyle other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return textStyle.Equals(other.textStyle);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
public bool IsInited()
|
||||
{
|
||||
return runtimeText != null;
|
||||
@@ -90,13 +71,13 @@ namespace XCharts
|
||||
{
|
||||
if (runtimeText)
|
||||
{
|
||||
runtimeText.transform.localPosition = pos + new Vector3(m_textStyle.offset.x, m_textStyle.offset.y);
|
||||
runtimeText.transform.localPosition = pos + new Vector3(m_TextStyle.offset.x, m_TextStyle.offset.y);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetText(string text)
|
||||
{
|
||||
if (runtimeText)
|
||||
if (runtimeText && !runtimeText.text.Equals(text))
|
||||
{
|
||||
if (textStyle.color != Color.clear) runtimeText.color = textStyle.color;
|
||||
runtimeText.text = text;
|
||||
|
||||
@@ -32,20 +32,25 @@ namespace XCharts
|
||||
base.Start();
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
UpdateTitle(serie);
|
||||
UpdateLabel(serie);
|
||||
TitleStyleHelper.CheckTitle(serie, ref m_ReinitTitle, ref m_UpdateTitleText);
|
||||
SerieLabelHelper.CheckLabel(serie, ref m_ReinitLabel, ref m_UpdateLabelText);
|
||||
}
|
||||
UpdateTitleAndLabelText();
|
||||
UpdateAxisLabel();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
if (m_UpdateLabelText || m_UpdateTitleText)
|
||||
if (m_UpdateTitleText)
|
||||
{
|
||||
m_UpdateTitleText = false;
|
||||
TitleStyleHelper.UpdateTitleText(m_Series);
|
||||
}
|
||||
if (m_UpdateLabelText)
|
||||
{
|
||||
m_UpdateLabelText = false;
|
||||
UpdateTitleAndLabelText();
|
||||
SerieLabelHelper.UpdateLabelText(m_Series,m_ThemeInfo);
|
||||
UpdateAxisLabel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,16 +139,14 @@ namespace XCharts
|
||||
serie.UpdateCenter(chartWidth, chartHeight);
|
||||
var destAngle = GetCurrAngle(serie, true);
|
||||
serie.animation.InitProgress(0, serie.startAngle, destAngle);
|
||||
//var currAngle = serie.animation.GetCurrDetail();
|
||||
var currAngle = serie.animation.IsFinish() ? GetCurrAngle(serie, false) : serie.animation.GetCurrDetail();
|
||||
DrawProgressBar(vh, serie, currAngle);
|
||||
DrawStageColor(vh, serie);
|
||||
DrawLineStyle(vh, serie);
|
||||
DrawAxisTick(vh, serie);
|
||||
DrawPointer(vh, serie, currAngle);
|
||||
UpdateTitle(serie);
|
||||
// UpdateAxisLabel(serie);
|
||||
UpdateLabel(serie);
|
||||
TitleStyleHelper.CheckTitle(serie, ref m_ReinitTitle, ref m_UpdateTitleText);
|
||||
SerieLabelHelper.CheckLabel(serie, ref m_ReinitLabel, ref m_UpdateLabelText);
|
||||
|
||||
CheckAnimation(serie);
|
||||
if (!serie.animation.IsFinish())
|
||||
@@ -168,15 +171,15 @@ namespace XCharts
|
||||
backgroundColor, m_ThemeInfo.backgroundColor, m_Settings.cicleSmoothness, serie.startAngle, serie.endAngle);
|
||||
if (serie.roundCap)
|
||||
{
|
||||
DrawArcShape(vh, serie, serie.startAngle, backgroundColor, true);
|
||||
DrawArcShape(vh, serie, serie.endAngle, backgroundColor);
|
||||
DrawRoundCap(vh, serie, serie.startAngle, backgroundColor, true);
|
||||
DrawRoundCap(vh, serie, serie.endAngle, backgroundColor);
|
||||
}
|
||||
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, serie.runtimeInsideRadius, outsideRadius,
|
||||
color, m_ThemeInfo.backgroundColor, m_Settings.cicleSmoothness, serie.startAngle, currAngle);
|
||||
if (serie.roundCap && currAngle != serie.startAngle)
|
||||
{
|
||||
DrawArcShape(vh, serie, currAngle, color);
|
||||
DrawArcShape(vh, serie, serie.startAngle, color, true);
|
||||
DrawRoundCap(vh, serie, currAngle, color);
|
||||
DrawRoundCap(vh, serie, serie.startAngle, color, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +278,7 @@ namespace XCharts
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DrawArcShape(VertexHelper vh, Serie serie, float angle, Color color, bool invert = false)
|
||||
private void DrawRoundCap(VertexHelper vh, Serie serie, float angle, Color color, bool invert = false)
|
||||
{
|
||||
var radius = serie.gaugeAxis.axisLine.width / 2;
|
||||
var len = serie.runtimeInsideRadius + radius;
|
||||
@@ -296,27 +299,6 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTitle(Serie serie)
|
||||
{
|
||||
if (serie.titleStyle.show)
|
||||
{
|
||||
if (serie.titleStyle.IsInited())
|
||||
{
|
||||
serie.titleStyle.SetActive(true);
|
||||
serie.titleStyle.UpdatePosition(serie.runtimeCenterPos);
|
||||
m_UpdateTitleText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ReinitTitle = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.titleStyle.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAxisLabel(Serie serie)
|
||||
{
|
||||
var show = serie.gaugeAxis.show && serie.gaugeAxis.axisLabel.show;
|
||||
@@ -347,56 +329,12 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLabel(Serie serie)
|
||||
{
|
||||
var serieData = serie.GetSerieData(0);
|
||||
if (serieData != null)
|
||||
{
|
||||
if (serie.label.show)
|
||||
{
|
||||
if (serieData.IsInitLabel())
|
||||
{
|
||||
serieData.SetLabelActive(true);
|
||||
serieData.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset);
|
||||
m_UpdateLabelText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ReinitLabel = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.SetLabelActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateTitleAndLabelText()
|
||||
private void UpdateAxisLabel()
|
||||
{
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
if (serie.type == SerieType.Gauge)
|
||||
{
|
||||
var serieData = serie.GetSerieData(0);
|
||||
if (serieData != null)
|
||||
{
|
||||
if (serie.label.show && serieData.IsInitLabel())
|
||||
{
|
||||
var value = serieData.GetData(1);
|
||||
var total = serie.max;
|
||||
var content = serie.label.GetFormatterContent(serie.name, serieData.name, value, total);
|
||||
serieData.SetLabelText(content);
|
||||
if (serie.label.color != Color.clear)
|
||||
{
|
||||
serieData.SetLabelColor(serie.label.color);
|
||||
}
|
||||
}
|
||||
if (serie.titleStyle.show && serie.titleStyle.IsInited())
|
||||
{
|
||||
serie.titleStyle.SetText(serieData.name);
|
||||
}
|
||||
}
|
||||
UpdateAxisLabel(serie);
|
||||
}
|
||||
}
|
||||
@@ -415,6 +353,7 @@ namespace XCharts
|
||||
if (serie.dataCount > 0)
|
||||
{
|
||||
var serieData = serie.data[0];
|
||||
serieData.labelPosition = serie.runtimeCenterPos + serie.label.offset;
|
||||
value = dest ? serieData.GetData(1) : serieData.GetCurrData(1, serie.animation.GetUpdateAnimationDuration());
|
||||
value = Mathf.Clamp(value, serie.min, serie.max);
|
||||
}
|
||||
|
||||
50
Assets/XCharts/Runtime/Helper/SerieHelper.cs
Normal file
50
Assets/XCharts/Runtime/Helper/SerieHelper.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
internal static class SerieHelper
|
||||
{
|
||||
internal static Color GetItemBackgroundColor(Serie serie, ThemeInfo theme, int index, bool highlight)
|
||||
{
|
||||
if (serie.itemStyle.backgroundColor != Color.clear)
|
||||
{
|
||||
var color = serie.itemStyle.backgroundColor;
|
||||
if (highlight) color *= color;
|
||||
color.a *= serie.itemStyle.opacity;
|
||||
return color;
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = (Color)theme.GetColor(index);
|
||||
if (highlight) color *= color;
|
||||
color.a = 0.2f;
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Color GetItemColor(Serie serie, ThemeInfo theme, int index, bool highlight)
|
||||
{
|
||||
if (serie.itemStyle.color != Color.clear)
|
||||
{
|
||||
var color = serie.itemStyle.color;
|
||||
if (highlight) color *= color;
|
||||
color.a *= serie.itemStyle.opacity;
|
||||
return color;
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = (Color)theme.GetColor(index);
|
||||
if (highlight) color *= color;
|
||||
color.a *= serie.itemStyle.opacity;
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Helper/SerieHelper.cs.meta
Normal file
11
Assets/XCharts/Runtime/Helper/SerieHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f69933c37061c417d9cadd9e486e6785
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
128
Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs
Normal file
128
Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
internal static class SerieLabelHelper
|
||||
{
|
||||
public static void CheckLabel(Serie serie, ref bool m_ReinitLabel, ref bool m_UpdateLabelText)
|
||||
{
|
||||
switch (serie.type)
|
||||
{
|
||||
case SerieType.Gauge:
|
||||
case SerieType.Ring:
|
||||
var serieData = serie.GetSerieData(0);
|
||||
if (serieData != null)
|
||||
{
|
||||
if (serie.label.show && serie.show)
|
||||
{
|
||||
if (serieData.IsInitLabel())
|
||||
{
|
||||
serieData.SetLabelActive(true);
|
||||
m_UpdateLabelText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ReinitLabel = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.SetLabelActive(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateLabelText(Series series, ThemeInfo themeInfo)
|
||||
{
|
||||
foreach (var serie in series.list)
|
||||
{
|
||||
if (!serie.label.show) continue;
|
||||
switch (serie.type)
|
||||
{
|
||||
case SerieType.Gauge:
|
||||
SetGaugeLabelText(serie);
|
||||
break;
|
||||
case SerieType.Ring:
|
||||
SetRingLabelText(serie, themeInfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Color GetLabelColor(Serie serie, ThemeInfo themeInfo, int index)
|
||||
{
|
||||
if (serie.label.color != Color.clear)
|
||||
{
|
||||
return serie.label.color;
|
||||
}
|
||||
else
|
||||
{
|
||||
return themeInfo.GetColor(index);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetGaugeLabelText(Serie serie)
|
||||
{
|
||||
var serieData = serie.GetSerieData(0);
|
||||
if (serieData != null)
|
||||
{
|
||||
if (serieData.IsInitLabel())
|
||||
{
|
||||
var value = serieData.GetData(1);
|
||||
var total = serie.max;
|
||||
var content = serie.label.GetFormatterContent(serie.name, serieData.name, value, total);
|
||||
serieData.SetLabelText(content);
|
||||
serieData.SetLabelPosition(serie.runtimeCenterPos + serie.label.offset);
|
||||
if (serie.label.color != Color.clear)
|
||||
{
|
||||
serieData.SetLabelColor(serie.label.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetRingLabelText(Serie serie, ThemeInfo themeInfo)
|
||||
{
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
if (serieData.IsInitLabel())
|
||||
{
|
||||
if (!serie.show || !serieData.show)
|
||||
{
|
||||
serieData.SetLabelActive(false);
|
||||
continue;
|
||||
}
|
||||
var value = serieData.GetData(0);
|
||||
var total = serieData.GetData(1);
|
||||
var content = serie.label.GetFormatterContent(serie.name, serieData.name, value, total);
|
||||
serieData.SetLabelActive(true);
|
||||
serieData.SetLabelText(content);
|
||||
serieData.SetLabelColor(GetLabelColor(serie, themeInfo, i));
|
||||
|
||||
if (serie.label.position == SerieLabel.Position.Bottom)
|
||||
{
|
||||
var labelWidth = serieData.GetLabelWidth();
|
||||
if (serie.clockwise)
|
||||
serieData.SetLabelPosition(serieData.labelPosition - new Vector3(labelWidth / 2, 0));
|
||||
else
|
||||
serieData.SetLabelPosition(serieData.labelPosition + new Vector3(labelWidth / 2, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.SetLabelPosition(serieData.labelPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs.meta
Normal file
11
Assets/XCharts/Runtime/Helper/SerieLabelHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d74ec0ba2845e409ca2e1c85a3814939
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
43
Assets/XCharts/Runtime/Helper/TitleStyleHelper.cs
Normal file
43
Assets/XCharts/Runtime/Helper/TitleStyleHelper.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
internal static class TitleStyleHelper
|
||||
{
|
||||
public static void CheckTitle(Serie serie, ref bool m_ReinitTitle, ref bool m_UpdateTitleText)
|
||||
{
|
||||
if (serie.titleStyle.show)
|
||||
{
|
||||
if (serie.titleStyle.IsInited())
|
||||
{
|
||||
serie.titleStyle.UpdatePosition(serie.runtimeCenterPos);
|
||||
m_UpdateTitleText = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ReinitTitle = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UpdateTitleText(Series series)
|
||||
{
|
||||
foreach (var serie in series.list) UpdateTitleText(serie);
|
||||
}
|
||||
|
||||
public static void UpdateTitleText(Serie serie)
|
||||
{
|
||||
if (serie.titleStyle.show)
|
||||
{
|
||||
serie.titleStyle.SetText(serie.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Helper/TitleStyleHelper.cs.meta
Normal file
11
Assets/XCharts/Runtime/Helper/TitleStyleHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76af3a33fe0b643e4ac6e875864233c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Assets/XCharts/Runtime/Internal/APIException.cs
Normal file
20
Assets/XCharts/Runtime/Internal/APIException.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class APIException : System.Exception
|
||||
{
|
||||
public APIException() { }
|
||||
public APIException(string message) : base(message) { }
|
||||
public APIException(string message, System.Exception inner) : base(message, inner) { }
|
||||
protected APIException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Internal/APIException.cs.meta
Normal file
11
Assets/XCharts/Runtime/Internal/APIException.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62abeafe2ed4141d69bdb9ad76c02e41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -163,6 +163,10 @@ namespace XCharts
|
||||
if (m_Series.vertsDirty) RefreshChart();
|
||||
if (m_Series.labelDirty) m_ReinitLabel = true;
|
||||
if (m_Series.labelUpdate && !m_RefreshChart) m_RefreshLabel = true;
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
if (serie.titleStyle.componentDirty) m_ReinitTitle = true;
|
||||
}
|
||||
m_Series.ClearDirty();
|
||||
}
|
||||
}
|
||||
@@ -203,6 +207,7 @@ namespace XCharts
|
||||
m_Legend.SetAllDirty();
|
||||
m_Tooltip.SetAllDirty();
|
||||
m_ReinitLabel = true;
|
||||
m_ReinitTitle = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -388,10 +393,10 @@ namespace XCharts
|
||||
var isAutoSize = serieLabel.backgroundWidth == 0 || serieLabel.backgroundHeight == 0;
|
||||
serieData.InitLabel(labelObj, isAutoSize, serieLabel.paddingLeftRight, serieLabel.paddingTopBottom);
|
||||
serieData.SetLabelActive(false);
|
||||
//serieData.SetLabelText(serieData.name);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
SerieLabelHelper.UpdateLabelText(m_Series,m_ThemeInfo);
|
||||
}
|
||||
|
||||
private void InitSerieTitle()
|
||||
@@ -415,8 +420,9 @@ namespace XCharts
|
||||
txt.text = "";
|
||||
txt.transform.localPosition = new Vector2(0, 0);
|
||||
txt.transform.localEulerAngles = Vector2.zero;
|
||||
ChartHelper.SetActive(txt, false);
|
||||
ChartHelper.SetActive(txt, serie.titleStyle.show);
|
||||
serie.titleStyle.runtimeText = txt;
|
||||
serie.titleStyle.UpdatePosition(serie.runtimeCenterPos);
|
||||
var serieData = serie.GetSerieData(0);
|
||||
if (serieData != null)
|
||||
{
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace XCharts
|
||||
serieData.runtimePieCurrAngle = serieData.runtimePieToAngle;
|
||||
serieData.runtiemPieOffsetCenter = center;
|
||||
serieData.runtimePieInsideRadius = serie.runtimeInsideRadius;
|
||||
if (serie.animation.CheckDetailBreak(n, serieData.runtimePieToAngle))
|
||||
if (serie.animation.CheckDetailBreak(serieData.runtimePieToAngle))
|
||||
{
|
||||
isFinish = false;
|
||||
serieData.runtimePieCurrAngle = serie.animation.GetCurrDetail();
|
||||
@@ -144,7 +144,7 @@ namespace XCharts
|
||||
center.y + serieData.runtimePieOffsetRadius * currCos);
|
||||
var drawStartDegree = startDegree + serie.pieSpace;
|
||||
var drawEndDegree = serieData.runtimePieCurrAngle - serie.pieSpace;
|
||||
DrawArcShape(vh, serie, serieData, serieData.runtiemPieOffsetCenter, color, ref drawStartDegree, ref drawEndDegree);
|
||||
DrawRoundCap(vh, serie, serieData, serieData.runtiemPieOffsetCenter, color, ref drawStartDegree, ref drawEndDegree);
|
||||
ChartDrawer.DrawDoughnut(vh, serieData.runtiemPieOffsetCenter, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
|
||||
color, m_ThemeInfo.backgroundColor, m_Settings.cicleSmoothness, drawStartDegree, drawEndDegree);
|
||||
}
|
||||
@@ -152,7 +152,7 @@ namespace XCharts
|
||||
{
|
||||
var drawStartDegree = startDegree + serie.pieSpace;
|
||||
var drawEndDegree = serieData.runtimePieCurrAngle - serie.pieSpace;
|
||||
DrawArcShape(vh, serie, serieData, center, color, ref drawStartDegree, ref drawEndDegree);
|
||||
DrawRoundCap(vh, serie, serieData, center, color, ref drawStartDegree, ref drawEndDegree);
|
||||
ChartDrawer.DrawDoughnut(vh, center, serieData.runtimePieInsideRadius, serieData.runtimePieOutsideRadius,
|
||||
color, m_ThemeInfo.backgroundColor, m_Settings.cicleSmoothness, drawStartDegree, drawEndDegree);
|
||||
}
|
||||
@@ -178,7 +178,7 @@ namespace XCharts
|
||||
raycastTarget = isClickOffset && isDataHighlight;
|
||||
}
|
||||
|
||||
private void DrawArcShape(VertexHelper vh, Serie serie, SerieData serieData, Vector3 centerPos,
|
||||
private void DrawRoundCap(VertexHelper vh, Serie serie, SerieData serieData, Vector3 centerPos,
|
||||
Color color, ref float drawStartDegree, ref float drawEndDegree)
|
||||
{
|
||||
if (serie.roundCap && serieData.runtimePieInsideRadius > 0)
|
||||
@@ -189,14 +189,8 @@ namespace XCharts
|
||||
drawStartDegree += diffDegree;
|
||||
drawEndDegree -= diffDegree;
|
||||
|
||||
var px = Mathf.Sin(drawStartDegree * Mathf.Deg2Rad) * radius;
|
||||
var py = Mathf.Cos(drawStartDegree * Mathf.Deg2Rad) * radius;
|
||||
var pos = new Vector3(px, py) + centerPos;
|
||||
ChartDrawer.DrawSector(vh, pos, width, color, drawStartDegree + 180, drawStartDegree + 360);
|
||||
px = Mathf.Sin(drawEndDegree * Mathf.Deg2Rad) * radius;
|
||||
py = Mathf.Cos(drawEndDegree * Mathf.Deg2Rad) * radius;
|
||||
pos = new Vector3(px, py) + centerPos;
|
||||
ChartDrawer.DrawSector(vh, pos, width, color, drawEndDegree, drawEndDegree + 180);
|
||||
ChartDrawer.DrawRoundCap(vh, centerPos, width, radius, drawStartDegree, serie.clockwise, color, false);
|
||||
ChartDrawer.DrawRoundCap(vh, centerPos, width, radius, drawEndDegree, serie.clockwise, color, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
364
Assets/XCharts/Runtime/RingChart.cs
Normal file
364
Assets/XCharts/Runtime/RingChart.cs
Normal file
@@ -0,0 +1,364 @@
|
||||
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/RingChart", 20)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public partial class RingChart : BaseChart
|
||||
{
|
||||
private bool m_UpdateTitleText = false;
|
||||
private bool m_UpdateLabelText = false;
|
||||
private bool m_IsEnterLegendButtom;
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
if (m_UpdateTitleText)
|
||||
{
|
||||
m_UpdateTitleText = false;
|
||||
TitleStyleHelper.UpdateTitleText(m_Series);
|
||||
}
|
||||
if (m_UpdateLabelText)
|
||||
{
|
||||
m_UpdateLabelText = false;
|
||||
SerieLabelHelper.UpdateLabelText(m_Series, m_ThemeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
m_Title.text = "RingChart";
|
||||
m_Tooltip.type = Tooltip.Type.Line;
|
||||
RemoveData();
|
||||
var serie = AddSerie(SerieType.Ring, "serie1");
|
||||
serie.roundCap = true;
|
||||
serie.radius = new float[] { 0.3f, 0.35f };
|
||||
serie.titleStyle.show = false;
|
||||
serie.titleStyle.textStyle.offset = new Vector2(0, 30);
|
||||
serie.label.show = true;
|
||||
serie.label.position = SerieLabel.Position.Center;
|
||||
serie.label.formatter = "{d:f0}%";
|
||||
serie.label.fontSize = 28;
|
||||
var value = Random.Range(30, 90);
|
||||
var max = 100;
|
||||
AddData(0, value, max, "data1");
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void DrawChart(VertexHelper vh)
|
||||
{
|
||||
base.DrawChart(vh);
|
||||
for (int i = 0; i < m_Series.list.Count; i++)
|
||||
{
|
||||
var serie = m_Series.list[i];
|
||||
var data = serie.data;
|
||||
serie.index = i;
|
||||
if (!serie.show || serie.type != SerieType.Ring || serie.animation.HasFadeOut())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
serie.animation.InitProgress(data.Count, serie.startAngle, serie.startAngle + 360);
|
||||
serie.UpdateCenter(chartWidth, chartHeight);
|
||||
TitleStyleHelper.CheckTitle(serie, ref m_ReinitTitle, ref m_UpdateTitleText);
|
||||
SerieLabelHelper.CheckLabel(serie, ref m_ReinitLabel, ref m_UpdateLabelText);
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var ringWidth = serie.runtimeOutsideRadius - serie.runtimeInsideRadius;
|
||||
var dataChanging = false;
|
||||
for (int j = 0; j < data.Count; j++)
|
||||
{
|
||||
var serieData = data[j];
|
||||
if (!serieData.show) continue;
|
||||
if (serieData.IsDataChanged()) dataChanging = true;
|
||||
var value = serieData.GetFirstData(dataChangeDuration);
|
||||
var max = serieData.GetLastData();
|
||||
var degree = 360 * value / max;
|
||||
var startDegree = GetStartAngle(serie);
|
||||
var toDegree = GetToAngle(serie, degree);
|
||||
var itemColor = SerieHelper.GetItemColor(serie, m_ThemeInfo, j, serieData.highlighted);
|
||||
var outsideRadius = serie.runtimeOutsideRadius - j * (ringWidth + serie.ringGap);
|
||||
var insideRadius = outsideRadius - ringWidth;
|
||||
var centerRadius = (outsideRadius + insideRadius) / 2;
|
||||
|
||||
serieData.runtimePieStartAngle = serie.clockwise ? startDegree : toDegree;
|
||||
serieData.runtimePieToAngle = serie.clockwise ? toDegree : startDegree;
|
||||
serieData.runtimePieInsideRadius = insideRadius;
|
||||
serieData.runtimePieOutsideRadius = outsideRadius;
|
||||
|
||||
DrawBackground(vh, serie, j, insideRadius, outsideRadius);
|
||||
DrawRoundCap(vh, serie, serie.runtimeCenterPos, itemColor, insideRadius, outsideRadius,
|
||||
ref startDegree, ref toDegree);
|
||||
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, insideRadius,
|
||||
outsideRadius, itemColor, Color.clear, m_Settings.cicleSmoothness,
|
||||
startDegree, toDegree);
|
||||
DrawBorder(vh, serie, insideRadius, outsideRadius);
|
||||
DrawCenter(vh, serie, insideRadius, j == data.Count - 1);
|
||||
UpateLabelPosition(serie, serieData, j, startDegree, toDegree, centerRadius);
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(360);
|
||||
serie.animation.CheckSymbol(serie.symbol.size);
|
||||
RefreshChart();
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private float GetStartAngle(Serie serie)
|
||||
{
|
||||
return serie.clockwise ? serie.startAngle : 360 - serie.startAngle;
|
||||
}
|
||||
|
||||
private float GetToAngle(Serie serie, float angle)
|
||||
{
|
||||
var toAngle = angle + serie.startAngle;
|
||||
if (!serie.clockwise)
|
||||
{
|
||||
toAngle = 360 - toAngle - serie.startAngle;
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
var currAngle = serie.animation.GetCurrDetail();
|
||||
if (serie.clockwise)
|
||||
{
|
||||
toAngle = toAngle > currAngle ? currAngle : toAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
toAngle = toAngle < 360 - currAngle ? 360 - currAngle : toAngle;
|
||||
}
|
||||
}
|
||||
return toAngle;
|
||||
}
|
||||
|
||||
private void DrawCenter(VertexHelper vh, Serie serie, float insideRadius, bool last)
|
||||
{
|
||||
if (serie.itemStyle.centerColor != Color.clear && last)
|
||||
{
|
||||
var radius = insideRadius - serie.itemStyle.centerGap;
|
||||
ChartDrawer.DrawCricle(vh, serie.runtimeCenterPos, radius, serie.itemStyle.centerColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpateLabelPosition(Serie serie, SerieData serieData, int index, float startAngle,
|
||||
float toAngle, float centerRadius)
|
||||
{
|
||||
if (!serie.label.show) return;
|
||||
switch (serie.label.position)
|
||||
{
|
||||
case SerieLabel.Position.Center:
|
||||
serieData.labelPosition = serie.runtimeCenterPos + serie.label.offset;
|
||||
break;
|
||||
case SerieLabel.Position.Bottom:
|
||||
var px1 = Mathf.Sin(startAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
var py1 = Mathf.Cos(startAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
var xDiff = serie.clockwise ? -serie.label.margin : serie.label.margin;
|
||||
serieData.labelPosition = serie.runtimeCenterPos + new Vector3(px1 + xDiff, py1);
|
||||
break;
|
||||
case SerieLabel.Position.Top:
|
||||
startAngle += serie.clockwise ? -serie.label.margin : serie.label.margin;
|
||||
toAngle += serie.clockwise ? serie.label.margin : -serie.label.margin;
|
||||
var px2 = Mathf.Sin(toAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
var py2 = Mathf.Cos(toAngle * Mathf.Deg2Rad) * centerRadius;
|
||||
serieData.labelPosition = serie.runtimeCenterPos + new Vector3(px2, py2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBackground(VertexHelper vh, Serie serie, int index, float insideRadius, float outsideRadius)
|
||||
{
|
||||
var backgroundColor = SerieHelper.GetItemBackgroundColor(serie, m_ThemeInfo, index, false);
|
||||
if (serie.itemStyle.backgroundWidth != 0)
|
||||
{
|
||||
var centerRadius = (outsideRadius + insideRadius) / 2;
|
||||
var inradius = centerRadius - serie.itemStyle.backgroundWidth / 2;
|
||||
var outradius = centerRadius + serie.itemStyle.backgroundWidth / 2;
|
||||
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, inradius,
|
||||
outradius, backgroundColor, Color.clear, m_Settings.cicleSmoothness);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, insideRadius,
|
||||
outsideRadius, backgroundColor, Color.clear, m_Settings.cicleSmoothness);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBorder(VertexHelper vh, Serie serie, float insideRadius, float outsideRadius)
|
||||
{
|
||||
if (serie.itemStyle.show && serie.itemStyle.borderWidth > 0 && serie.itemStyle.borderColor != Color.clear)
|
||||
{
|
||||
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, outsideRadius,
|
||||
outsideRadius + serie.itemStyle.borderWidth, serie.itemStyle.borderColor,
|
||||
Color.clear, m_Settings.cicleSmoothness);
|
||||
ChartDrawer.DrawDoughnut(vh, serie.runtimeCenterPos, insideRadius,
|
||||
insideRadius + serie.itemStyle.borderWidth, serie.itemStyle.borderColor,
|
||||
Color.clear, m_Settings.cicleSmoothness);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void DrawRoundCap(VertexHelper vh, Serie serie, Vector3 centerPos, Color color,
|
||||
float insideRadius, float outsideRadius, ref float drawStartDegree, ref float drawEndDegree)
|
||||
{
|
||||
if (serie.roundCap && insideRadius > 0 && drawStartDegree != drawEndDegree)
|
||||
{
|
||||
var width = (outsideRadius - insideRadius) / 2;
|
||||
var radius = insideRadius + width;
|
||||
|
||||
var diffDegree = Mathf.Asin(width / radius) * Mathf.Rad2Deg;
|
||||
drawStartDegree += serie.clockwise ? diffDegree : -diffDegree;
|
||||
drawEndDegree -= serie.clockwise ? diffDegree : -diffDegree;
|
||||
ChartDrawer.DrawRoundCap(vh, centerPos, width, radius, drawStartDegree, serie.clockwise, color, false);
|
||||
ChartDrawer.DrawRoundCap(vh, centerPos, width, radius, drawEndDegree, serie.clockwise, color, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnLegendButtonClick(int index, string legendName, bool show)
|
||||
{
|
||||
CheckDataShow(legendName, show);
|
||||
UpdateLegendColor(legendName, show);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
protected override void OnLegendButtonEnter(int index, string legendName)
|
||||
{
|
||||
m_IsEnterLegendButtom = true;
|
||||
CheckDataHighlighted(legendName, true);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
protected override void OnLegendButtonExit(int index, string legendName)
|
||||
{
|
||||
m_IsEnterLegendButtom = false;
|
||||
CheckDataHighlighted(legendName, false);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
protected override void CheckTootipArea(Vector2 local)
|
||||
{
|
||||
if (m_IsEnterLegendButtom) return;
|
||||
m_Tooltip.runtimeDataIndex.Clear();
|
||||
bool selected = false;
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
int index = GetRingIndex(serie, local);
|
||||
m_Tooltip.runtimeDataIndex.Add(index);
|
||||
if (serie.type != SerieType.Ring) continue;
|
||||
bool refresh = false;
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
var serieData = serie.data[j];
|
||||
if (serieData.highlighted != (j == index)) refresh = true;
|
||||
serieData.highlighted = j == index;
|
||||
}
|
||||
if (index >= 0) selected = true;
|
||||
if (refresh) RefreshChart();
|
||||
}
|
||||
if (selected)
|
||||
{
|
||||
m_Tooltip.UpdateContentPos(new Vector2(local.x + 18, local.y - 25));
|
||||
UpdateTooltip();
|
||||
}
|
||||
else if (m_Tooltip.IsActive())
|
||||
{
|
||||
m_Tooltip.SetActive(false);
|
||||
RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetRingIndex(Serie serie, Vector2 local)
|
||||
{
|
||||
if (serie.type != SerieType.Ring) return -1;
|
||||
var dist = Vector2.Distance(local, serie.runtimeCenterPos);
|
||||
if (dist > serie.runtimeOutsideRadius) return -1;
|
||||
Vector2 dir = local - new Vector2(serie.runtimeCenterPos.x, serie.runtimeCenterPos.y);
|
||||
float angle = VectorAngle(Vector2.up, dir);
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
if (dist >= serieData.runtimePieInsideRadius &&
|
||||
dist <= serieData.runtimePieOutsideRadius &&
|
||||
angle >= serieData.runtimePieStartAngle &&
|
||||
angle <= serieData.runtimePieToAngle)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
float VectorAngle(Vector2 from, Vector2 to)
|
||||
{
|
||||
float angle;
|
||||
|
||||
Vector3 cross = Vector3.Cross(from, to);
|
||||
angle = Vector2.Angle(from, to);
|
||||
angle = cross.z > 0 ? -angle : angle;
|
||||
angle = (angle + 360) % 360;
|
||||
return angle;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
protected override void UpdateTooltip()
|
||||
{
|
||||
base.UpdateTooltip();
|
||||
bool showTooltip = false;
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
int index = m_Tooltip.runtimeDataIndex[serie.index];
|
||||
if (index < 0) continue;
|
||||
showTooltip = true;
|
||||
if (tooltip.IsNoFormatter())
|
||||
{
|
||||
var serieData = serie.GetSerieData(index);
|
||||
float value = serieData.GetFirstData();
|
||||
sb.Length = 0;
|
||||
if (!string.IsNullOrEmpty(serieData.name))
|
||||
{
|
||||
sb.Append("<color=#").Append(m_ThemeInfo.GetColorStr(index)).Append(">● </color>")
|
||||
.Append(serieData.name).Append(": ").Append(ChartCached.FloatToStr(value, 0, m_Tooltip.forceENotation));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(ChartCached.FloatToStr(value, 0, m_Tooltip.forceENotation));
|
||||
}
|
||||
m_Tooltip.UpdateContentText(sb.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Tooltip.UpdateContentText(m_Tooltip.GetFormatterContent(index, m_Series, null, m_ThemeInfo));
|
||||
}
|
||||
|
||||
var pos = m_Tooltip.GetContentPos();
|
||||
if (pos.x + m_Tooltip.runtimeWidth > chartWidth)
|
||||
{
|
||||
pos.x = chartWidth - m_Tooltip.runtimeWidth;
|
||||
}
|
||||
if (pos.y - m_Tooltip.runtimeHeight < 0)
|
||||
{
|
||||
pos.y = m_Tooltip.runtimeHeight;
|
||||
}
|
||||
m_Tooltip.UpdateContentPos(pos);
|
||||
}
|
||||
m_Tooltip.SetActive(showTooltip);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/RingChart.cs.meta
Normal file
11
Assets/XCharts/Runtime/RingChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ad8949f652ee4376a4a4fe5cb32029f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -335,6 +335,28 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawRoundCap(VertexHelper vh, Vector3 center, float width, float radius, float angle,
|
||||
bool clockwise, Color color, bool end)
|
||||
{
|
||||
var px = Mathf.Sin(angle * Mathf.Deg2Rad) * radius;
|
||||
var py = Mathf.Cos(angle * Mathf.Deg2Rad) * radius;
|
||||
var pos = new Vector3(px, py) + center;
|
||||
if (end)
|
||||
{
|
||||
if (clockwise)
|
||||
ChartDrawer.DrawSector(vh, pos, width, color, angle, angle + 180);
|
||||
else
|
||||
ChartDrawer.DrawSector(vh, pos, width, color, angle, angle - 180);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (clockwise)
|
||||
ChartDrawer.DrawSector(vh, pos, width, color, angle + 180, angle + 360);
|
||||
else
|
||||
ChartDrawer.DrawSector(vh, pos, width, color, angle - 180, angle - 360);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawDoughnut(VertexHelper vh, Vector3 p, float insideRadius, float outsideRadius,
|
||||
Color32 color, Color emptyColor, float smoothness = 2f, float startDegree = 0, float toDegree = 360)
|
||||
{
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace XCharts
|
||||
public class XChartsMgr : MonoBehaviour
|
||||
{
|
||||
public const string version = "1.2.0";
|
||||
public const int date = 20200226;
|
||||
public const int date = 20200308;
|
||||
|
||||
[SerializeField] private string m_NowVersion;
|
||||
[SerializeField] private string m_NewVersion;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
BIN
Doc/newfeature/(2020.03.08) 环形图.png
Normal file
BIN
Doc/newfeature/(2020.03.08) 环形图.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 KiB |
@@ -7,7 +7,7 @@
|
||||
|
||||
A powerful, easy-to-use, configurable charting and data visualization library for Unity.
|
||||
|
||||
一款基于`UGUI`的功能强大、易用、参数可配置的数据可视化图表插件。支持折线图、柱状图、饼图、雷达图、散点图、热力图等常见图表。
|
||||
一款基于`UGUI`的功能强大、易用、参数可配置的数据可视化图表插件。支持折线图、柱状图、饼图、雷达图、散点图、热力图、仪表盘、环形图等常见图表。
|
||||
|
||||
[XCharts问答](https://github.com/monitor1394/unity-ugui-XCharts/blob/master/Assets/XCharts/Documentation/XCharts问答.md)
|
||||
[XChartsAPI手册](https://github.com/monitor1394/unity-ugui-XCharts/blob/master/Assets/XCharts/Documentation/XChartsAPI.md)
|
||||
@@ -66,6 +66,8 @@ XCharts的图表由组件和数据组成。不同的组件和数据可以组合
|
||||
* `RadarChart` 雷达图:雷达图主要用于表现多变量的数据,例如球员的各个属性分析。依赖 radar 组件。
|
||||
* `ScatterChart` 散点图:直角坐标系上的散点图可以用来展现数据的 x,y 之间的关系,如果数据项有多个维度,其它维度的值可以通过不同大小的 symbol 展现成气泡图,也可以用颜色来表现。
|
||||
* `HeatmapChart` 热力图:热力图主要通过颜色去表现数值的大小,必须要配合 visualMap 组件使用。
|
||||
* `GuageChart` 仪表盘。
|
||||
* `RingChart` 环形图。区别于`PieChart`中的环形图,`RingChart`只支持一个数据,一般用于表示百分比。
|
||||
|
||||
以下是LineChart折线图和主组件、子组件的关系结构:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user