mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-14 20:00:09 +00:00
增加GanttChart甘特图
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
|
||||
## Latest
|
||||
|
||||
* (2021.03.25) Added `Ganttchart`
|
||||
* (2021.03.22) Added `Theme` `Unbind` button to unbind theme when copying chart #118
|
||||
* (2021.03.18) Fixed an issue where the check box after `Foldout` in `Inspector` could not be checked
|
||||
* (2021.03.18) Fixed an issue with `BarChart` displaying an exception in the `0` value
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
## Latest
|
||||
|
||||
* (2021.03.25) 增加`GanttChart`甘特图
|
||||
* (2021.03.22) 增加`Theme`的`Unbind`按钮用于解绑复制图表时的主题 #118
|
||||
* (2021.03.18) 修复`Inspector`下`Foldout`后的勾选框无法选中的问题
|
||||
* (2021.03.18) 修复`BarChart`在`0`数值时显示异常的问题
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* [Serie-Ring 环形图](#Serie-Ring)
|
||||
* [Serie-Liquid 水位图](#Serie-Liquid)
|
||||
* [Serie-Candlestick K线图](#Serie-Candlestick)
|
||||
* [Serie-Gantt 甘特图](#Serie-Gantt)
|
||||
* [Settings 设置](#Settings)
|
||||
* [Theme 主题](#Theme)
|
||||
* [Tooltip 提示框](#Tooltip)
|
||||
@@ -774,6 +775,24 @@ K线图系列。
|
||||
* `animation`:起始动画 [SerieAnimation](#SerieAnimation)。
|
||||
* `data`:系列中的数据项 [SerieData](#SerieData) 数组,K线图至少需要4个维度的数组`[open, close, lowest, highest]`。
|
||||
|
||||
## `Serie-Gantt`
|
||||
|
||||
甘特图系列。支持类目轴和时间轴的甘特图,当 `X` 轴为类目轴时,数据为类目的索引,`X` 轴为时间轴时,数据为时间戳(秒为单位)。`Y` 轴默认为类目轴,显示的数据来源于`Serie`的`Data`的`Name`。
|
||||
甘特图默认支持开始和结束时间,也可以额外支持实际开始和结束时间。
|
||||
|
||||
* `show`:系列是否显示在图表上。
|
||||
* `type`:`Gantt`。
|
||||
* `name`:系列名称。用于 `tooltip` 的显示,`legend` 的图例筛选。
|
||||
* `xAxisIndex`:使用的坐标轴X轴的 `index`,在单个图表实例中存在多个坐标轴的时候有用。
|
||||
* `yAxisIndex`:使用的坐标轴Y轴的 `index`,在单个图表实例中存在多个坐标轴的时候有用。
|
||||
* `clip`:是否裁剪超出坐标系部分的图形。
|
||||
* `large`:是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。缺点:优化后不能自定义设置单个数据项的样式,不能显示Label,折线图不绘制Symbol。
|
||||
* `largeThreshold`:开启大数量优化的阈值。只有当开启了large并且数据量大于该阀值时才进入性能模式。
|
||||
* `itemStyle`:甘特图的柱条样式,包括设置背景颜色和边框等 [ItemStyle](#ItemStyle)。
|
||||
* `emphasis`:高亮样式 [Emphasis](#Emphasis)。
|
||||
* `animation`:起始动画 [SerieAnimation](#SerieAnimation)。
|
||||
* `data`:系列中的数据项 [SerieData](#SerieData) 数组,甘特图至少需要2个维度的数组`[start, end]`,也支持4个维度的数组`[start, end, actualStart, actualEnd]`。当 X 轴为类目轴时,数据为类目的索引,X 轴为时间轴时,数据为时间戳(秒为单位)。
|
||||
|
||||
## `Settings`
|
||||
|
||||
全局参数设置组件。一般情况下可使用默认值,当有需要时可进行调整。
|
||||
|
||||
@@ -26,6 +26,7 @@ __Main component:__
|
||||
* [Serie-Ring](#Serie-Ring)
|
||||
* [Serie-Liquid](#Serie-Liquid)
|
||||
* [Serie-Candlestick](#Serie-Candlestick)
|
||||
* [Serie-Gantt](#Serie-Gantt)
|
||||
* [Settings](#Settings)
|
||||
* [Theme](#Theme)
|
||||
* [Title](#Title)
|
||||
@@ -667,6 +668,24 @@ K线图系列。
|
||||
* `animation`:起始动画 [SerieAnimation](#SerieAnimation)。
|
||||
* `data`:系列中的数据项 [SerieData](#SerieData) 数组,K线图至少需要4个维度的数组`[open, close, lowest, highest]`。
|
||||
|
||||
## `Serie-Gantt`
|
||||
|
||||
甘特图系列。支持类目轴和时间轴的甘特图,当 `X` 轴为类目轴时,数据为类目的索引,`X` 轴为时间轴时,数据为时间戳(秒为单位)。`Y` 轴默认为类目轴,显示的数据来源于`Serie`的`Data`的`Name`。
|
||||
甘特图默认支持开始和结束时间,也可以额外支持实际开始和结束时间。
|
||||
|
||||
* `show`:系列是否显示在图表上。
|
||||
* `type`:`Gantt`。
|
||||
* `name`:系列名称。用于 `tooltip` 的显示,`legend` 的图例筛选。
|
||||
* `xAxisIndex`:使用的坐标轴X轴的 `index`,在单个图表实例中存在多个坐标轴的时候有用。
|
||||
* `yAxisIndex`:使用的坐标轴Y轴的 `index`,在单个图表实例中存在多个坐标轴的时候有用。
|
||||
* `clip`:是否裁剪超出坐标系部分的图形。
|
||||
* `large`:是否开启大数据量优化,在数据图形特别多而出现卡顿时候可以开启。开启后配合 largeThreshold 在数据量大于指定阈值的时候对绘制进行优化。缺点:优化后不能自定义设置单个数据项的样式,不能显示Label,折线图不绘制Symbol。
|
||||
* `largeThreshold`:开启大数量优化的阈值。只有当开启了large并且数据量大于该阀值时才进入性能模式。
|
||||
* `itemStyle`:甘特图的柱条样式,包括设置背景颜色和边框等 [ItemStyle](#ItemStyle)。
|
||||
* `emphasis`:高亮样式 [Emphasis](#Emphasis)。
|
||||
* `animation`:起始动画 [SerieAnimation](#SerieAnimation)。
|
||||
* `data`:系列中的数据项 [SerieData](#SerieData) 数组,甘特图至少需要2个维度的数组`[start, end]`,也支持4个维度的数组`[start, end, actualStart, actualEnd]`。当 X 轴为类目轴时,数据为类目的索引,X 轴为时间轴时,数据为时间戳(秒为单位)。
|
||||
|
||||
## `Settings`
|
||||
|
||||
全局参数设置组件。一般情况下可使用默认值,当有需要时可进行调整。
|
||||
|
||||
@@ -19,6 +19,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (BarChart)target;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace XCharts
|
||||
BlockEnd();
|
||||
|
||||
BlockStart();
|
||||
m_BaseFoldout = EditorGUILayout.Foldout(m_BaseFoldout, "Base");
|
||||
m_BaseFoldout = EditorGUILayout.Foldout(m_BaseFoldout, "Base", true);
|
||||
if (m_BaseFoldout)
|
||||
{
|
||||
EditorGUILayout.PropertyField(m_Script);
|
||||
@@ -196,7 +196,7 @@ namespace XCharts
|
||||
if (all)
|
||||
{
|
||||
var flag = m_Flodouts.ContainsKey(prop.displayName) && m_Flodouts[prop.displayName];
|
||||
m_Flodouts[prop.displayName] = EditorGUILayout.Foldout(flag, prop.displayName);
|
||||
m_Flodouts[prop.displayName] = EditorGUILayout.Foldout(flag, prop.displayName, true);
|
||||
if (m_Flodouts[prop.displayName])
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (CandlestickChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (CoordinateChart)target;
|
||||
m_Grids = serializedObject.FindProperty("m_Grids");
|
||||
m_XAxes = serializedObject.FindProperty("m_XAxes");
|
||||
|
||||
25
Assets/XCharts/Editor/GanttChartEditor.cs
Normal file
25
Assets/XCharts/Editor/GanttChartEditor.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEditor;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Editor class used to edit UI GanttChart.
|
||||
/// </summary>
|
||||
[CustomEditor(typeof(GanttChart), false)]
|
||||
public class GanttChartEditor : CoordinateChartEditor
|
||||
{
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (GanttChart)target;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Editor/GanttChartEditor.cs.meta
Normal file
11
Assets/XCharts/Editor/GanttChartEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1b5a1dfca8e5476b98c807c66783d85
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (GaugeChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (HeatmapChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (LineChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (PieChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (PolarChart)target;
|
||||
m_Polars = serializedObject.FindProperty("m_Polars");
|
||||
m_RadiusAxes = serializedObject.FindProperty("m_RadiusAxes");
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace XCharts
|
||||
}
|
||||
EditorGUI.EndChangeCheck();
|
||||
}
|
||||
if (type == Axis.AxisType.Value)
|
||||
if (type == Axis.AxisType.Value || type == Axis.AxisType.Time)
|
||||
{
|
||||
PropertyField(prop, "m_MinMaxType");
|
||||
Axis.AxisMinMaxType minMaxType = (Axis.AxisMinMaxType)m_MinMaxType.enumValueIndex;
|
||||
@@ -60,7 +60,10 @@ namespace XCharts
|
||||
break;
|
||||
}
|
||||
PropertyField(prop, "m_CeilRate");
|
||||
PropertyField(prop, "m_Inverse");
|
||||
if (type == Axis.AxisType.Value)
|
||||
{
|
||||
PropertyField(prop, "m_Inverse");
|
||||
}
|
||||
}
|
||||
PropertyField(prop, "m_SplitNumber");
|
||||
if (type == Axis.AxisType.Category)
|
||||
|
||||
@@ -197,6 +197,17 @@ namespace XCharts
|
||||
PropertyField(prop, "m_Label");
|
||||
PropertyField(prop, "m_Emphasis");
|
||||
break;
|
||||
case SerieType.Gantt:
|
||||
PropertyField(prop, "m_XAxisIndex");
|
||||
PropertyField(prop, "m_YAxisIndex");
|
||||
PropertyField(prop, "m_BarWidth");
|
||||
PropertyField(prop, "m_Clip");
|
||||
PropertyField(prop, "m_Large");
|
||||
PropertyField(prop, "m_LargeThreshold");
|
||||
PropertyField(prop, "m_ItemStyle");
|
||||
PropertyField(prop, "m_Label");
|
||||
PropertyField(prop, "m_Emphasis");
|
||||
break;
|
||||
}
|
||||
PropertyField(prop, "m_Animation");
|
||||
DrawData(pos, prop, serieType, ref m_DrawRect);
|
||||
@@ -340,7 +351,7 @@ namespace XCharts
|
||||
var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15 + gap;
|
||||
var dataWidTotal = (currentWidth - (startX + 20.5f + 1));
|
||||
var dataWid = dataWidTotal / fieldCount;
|
||||
var xWid = dataWid - 4;
|
||||
var xWid = dataWid - 2;
|
||||
for (int i = 0; i < dimension; i++)
|
||||
{
|
||||
var dataCount = i < 1 ? 2 : i + 1;
|
||||
@@ -407,7 +418,7 @@ namespace XCharts
|
||||
var str = prop.propertyPath.Substring(sindex + 1, eindex - sindex - 1);
|
||||
int.TryParse(str, out index);
|
||||
}
|
||||
if (index >= m_DataFoldout.Count)
|
||||
while (index >= m_DataFoldout.Count)
|
||||
{
|
||||
m_DataFoldout.Add(false);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (RingChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace XCharts
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
if(target == null) return;
|
||||
m_Chart = (ScatterChart)target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,11 +146,11 @@ namespace XCharts
|
||||
AddChart<LiquidChart>("LiquidChart");
|
||||
}
|
||||
|
||||
[MenuItem("XCharts/CandlestickChart", priority = 54)]
|
||||
[MenuItem("GameObject/XCharts/CandlestickChart", priority = 54)]
|
||||
public static void AddCandlestickChart()
|
||||
[MenuItem("XCharts/GanttChart", priority = 54)]
|
||||
[MenuItem("GameObject/XCharts/GanttChart", priority = 54)]
|
||||
public static void AddGanttChart()
|
||||
{
|
||||
AddChart<CandlestickChart>("CandlestickChart");
|
||||
AddChart<GanttChart>("GanttChart");
|
||||
}
|
||||
|
||||
[MenuItem("XCharts/Themes Reload")]
|
||||
|
||||
80
Assets/XCharts/Examples/Runtime/Example100_Gantt_Category.cs
Normal file
80
Assets/XCharts/Examples/Runtime/Example100_Gantt_Category.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Examples
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[ExecuteInEditMode]
|
||||
public class Example100_Gantt_Category : MonoBehaviour
|
||||
{
|
||||
private GanttChart chart;
|
||||
private float updateTime;
|
||||
public int dayCount = 10;
|
||||
public int taskCount = 5;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
chart = gameObject.GetComponent<GanttChart>();
|
||||
if (chart == null)
|
||||
{
|
||||
chart = gameObject.AddComponent<GanttChart>();
|
||||
}
|
||||
GenerateCategoryData();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
AddData();
|
||||
}
|
||||
}
|
||||
|
||||
void AddData()
|
||||
{
|
||||
for (int i = 0; i < taskCount; i++)
|
||||
{
|
||||
var taskName = "task-" + (i + 1);
|
||||
var startIndex = Random.Range(0, (int)(dayCount * 2.0f / 3));
|
||||
var endIndex = Random.Range(startIndex, dayCount);
|
||||
chart.UpdateData(0, i, 0, startIndex);
|
||||
chart.UpdateData(0, i, 1, endIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateCategoryData()
|
||||
{
|
||||
chart.RemoveData();
|
||||
|
||||
chart.grid.left = 100;
|
||||
chart.xAxis0.type = Axis.AxisType.Category;
|
||||
chart.xAxis0.boundaryGap = false;
|
||||
chart.xAxis0.splitNumber = dayCount;
|
||||
|
||||
chart.yAxis0.type = Axis.AxisType.Category;
|
||||
chart.yAxis0.boundaryGap = true;
|
||||
chart.yAxis0.splitNumber = 0;
|
||||
|
||||
for (int i = 0; i < dayCount; i++)
|
||||
{
|
||||
chart.AddXAxisData("day" + (i + 1));
|
||||
}
|
||||
|
||||
var serie = chart.AddSerie(SerieType.Gantt, "任务进度表");
|
||||
for (int i = 0; i < taskCount; i++)
|
||||
{
|
||||
var taskName = "task-" + (i + 1);
|
||||
var startIndex = Random.Range(0, (int)(dayCount * 2.0f / 3));
|
||||
var endIndex = Random.Range(startIndex, dayCount);
|
||||
chart.AddData(0, startIndex, endIndex, taskName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c383c3eae67ed461693e18a807b2e599
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
99
Assets/XCharts/Examples/Runtime/Example101_Gantt_Time.cs
Normal file
99
Assets/XCharts/Examples/Runtime/Example101_Gantt_Time.cs
Normal file
@@ -0,0 +1,99 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Examples
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[ExecuteInEditMode]
|
||||
public class Example101_Gantt_Time : MonoBehaviour
|
||||
{
|
||||
private GanttChart chart;
|
||||
private float updateTime;
|
||||
public int taskCount = 5;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
chart = gameObject.GetComponent<GanttChart>();
|
||||
if (chart == null)
|
||||
{
|
||||
chart = gameObject.AddComponent<GanttChart>();
|
||||
}
|
||||
GenerateTimeData();
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(KeyCode.Space))
|
||||
{
|
||||
AddData();
|
||||
}
|
||||
}
|
||||
|
||||
void AddData()
|
||||
{
|
||||
chart.ClearData();
|
||||
for (int i = 0; i < taskCount; i++)
|
||||
{
|
||||
var taskName = "张三-任务-" + (i + 1);
|
||||
var nowTimestamp = DateTimeUtil.GetTimestamp();
|
||||
var startTimestamp = nowTimestamp + Random.Range(1, 6) * 3600 * 24;
|
||||
var endTimestamp = startTimestamp + Random.Range(1, 10) * 3600 * 24;
|
||||
chart.AddData(0, startTimestamp, endTimestamp, taskName);
|
||||
}
|
||||
var serie2 = chart.AddSerie(SerieType.Gantt, "李四");
|
||||
for (int i = 0; i < taskCount; i++)
|
||||
{
|
||||
var taskName = "李四-任务-" + (i + 1);
|
||||
var nowTimestamp = DateTimeUtil.GetTimestamp();
|
||||
var startTimestamp = nowTimestamp + Random.Range(1, 6) * 3600 * 24;
|
||||
var endTimestamp = startTimestamp + Random.Range(1, 10) * 3600 * 24;
|
||||
chart.AddData(1, startTimestamp, endTimestamp, taskName);
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateTimeData()
|
||||
{
|
||||
chart.RemoveData();
|
||||
|
||||
chart.grid.left = 100;
|
||||
chart.xAxis0.type = Axis.AxisType.Time;
|
||||
chart.xAxis0.boundaryGap = false;
|
||||
chart.xAxis0.splitNumber = 5;
|
||||
|
||||
chart.xAxis0.axisLabel.numericFormatter = "HH:mm:ss";
|
||||
chart.xAxis0.axisLabel.formatter = "time:{value}";
|
||||
|
||||
chart.yAxis0.type = Axis.AxisType.Category;
|
||||
chart.yAxis0.boundaryGap = true;
|
||||
chart.yAxis0.splitNumber = 0;
|
||||
|
||||
|
||||
var serie1 = chart.AddSerie(SerieType.Gantt, "张三");
|
||||
serie1.label.show = true;
|
||||
for (int i = 0; i < taskCount; i++)
|
||||
{
|
||||
var taskName = "张三-任务-" + (i + 1);
|
||||
var nowTimestamp = DateTimeUtil.GetTimestamp();
|
||||
var startTimestamp = nowTimestamp + Random.Range(1, 6) * 3600 * 24;
|
||||
var endTimestamp = startTimestamp + Random.Range(1, 10) * 3600 * 24;
|
||||
chart.AddData(0, startTimestamp, endTimestamp, taskName);
|
||||
}
|
||||
var serie2 = chart.AddSerie(SerieType.Gantt, "李四");
|
||||
for (int i = 0; i < taskCount; i++)
|
||||
{
|
||||
var taskName = "李四-任务-" + (i + 1);
|
||||
var nowTimestamp = DateTimeUtil.GetTimestamp();
|
||||
var startTimestamp = nowTimestamp + Random.Range(1, 6) * 3600 * 24;
|
||||
var endTimestamp = startTimestamp + Random.Range(1, 10) * 3600 * 24;
|
||||
chart.AddData(1, startTimestamp, endTimestamp, taskName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d546ff7dfa6104a739c1accdb415ef54
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -45,7 +45,6 @@ namespace XCharts.Examples
|
||||
chart.ClearData();
|
||||
|
||||
var xValue = System.DateTime.Now;
|
||||
var minute = 60 * 1000;
|
||||
var baseValue = Random.Range(0f, 1f) * 12000;
|
||||
var boxVals = new float[4];
|
||||
var dayRange = 12;
|
||||
|
||||
@@ -134,6 +134,7 @@ namespace XCharts
|
||||
public void RefreshAllComponent()
|
||||
{
|
||||
SetAllComponentDirty();
|
||||
RefreshGraph();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -89,8 +89,16 @@ namespace XCharts
|
||||
/// </summary>
|
||||
public void ClearAxisData()
|
||||
{
|
||||
foreach (var item in m_XAxes) item.data.Clear();
|
||||
foreach (var item in m_YAxes) item.data.Clear();
|
||||
foreach (var axis in m_XAxes)
|
||||
{
|
||||
axis.data.Clear();
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
foreach (var axis in m_YAxes)
|
||||
{
|
||||
axis.data.Clear();
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -39,7 +39,12 @@ namespace XCharts
|
||||
/// Log axis, suitable for log data.
|
||||
/// 对数轴。适用于对数数据。
|
||||
/// </summary>
|
||||
Log
|
||||
Log,
|
||||
/// <summary>
|
||||
/// Time axis, suitable for continuous time series data.
|
||||
/// 时间轴。适用于连续的时序数据。
|
||||
/// </summary>
|
||||
Time
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -408,6 +413,7 @@ namespace XCharts
|
||||
public int runtimeMaxLogIndex { get { return logBaseE ? (int)Mathf.Log(runtimeMaxValue) : (int)Mathf.Log(runtimeMaxValue, logBase); } }
|
||||
internal bool runtimeLastCheckInverse { get; set; }
|
||||
internal float runtimeMinMaxRange { get { return m_MinMaxValueRange; } set { m_MinMaxValueRange = value; } }
|
||||
internal List<string> runtimeData { get { return m_RuntimeData; } }
|
||||
private int filterStart;
|
||||
private int filterEnd;
|
||||
private int filterMinShow;
|
||||
@@ -426,6 +432,7 @@ namespace XCharts
|
||||
private float m_RuntimeMaxValueUpdateTime;
|
||||
private bool m_RuntimeMinValueFirstChanged = true;
|
||||
private bool m_RuntimeMaxValueFirstChanged = true;
|
||||
protected List<string> m_RuntimeData = new List<string>();
|
||||
|
||||
public Axis Clone()
|
||||
{
|
||||
@@ -484,6 +491,7 @@ namespace XCharts
|
||||
public void ClearData()
|
||||
{
|
||||
m_Data.Clear();
|
||||
m_RuntimeData.Clear();
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
@@ -574,10 +582,14 @@ namespace XCharts
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Data;
|
||||
return m_Data.Count > 0 ? m_Data : m_RuntimeData;
|
||||
}
|
||||
}
|
||||
|
||||
internal List<string> GetDataList(){
|
||||
return m_Data.Count > 0 ? m_Data : m_RuntimeData;
|
||||
}
|
||||
|
||||
private List<string> emptyFliter = new List<string>();
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
@@ -596,24 +608,25 @@ namespace XCharts
|
||||
filterEnd = endIndex;
|
||||
filterMinShow = dataZoom.minShowNum;
|
||||
m_NeedUpdateFilterData = false;
|
||||
if (m_Data.Count > 0)
|
||||
var data = GetDataList();
|
||||
if (data.Count > 0)
|
||||
{
|
||||
var count = endIndex == startIndex ? 1 : endIndex - startIndex + 1;
|
||||
if (count < dataZoom.minShowNum)
|
||||
{
|
||||
if (dataZoom.minShowNum > m_Data.Count) count = m_Data.Count;
|
||||
if (dataZoom.minShowNum > data.Count) count = data.Count;
|
||||
else count = dataZoom.minShowNum;
|
||||
}
|
||||
if (startIndex + count > m_Data.Count)
|
||||
if (startIndex + count > data.Count)
|
||||
{
|
||||
int start = endIndex - count;
|
||||
filterData = m_Data.GetRange(start < 0 ? 0 : start, count);
|
||||
filterData = data.GetRange(start < 0 ? 0 : start, count);
|
||||
}
|
||||
else filterData = m_Data.GetRange(startIndex, count);
|
||||
else filterData = data.GetRange(startIndex, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
filterData = m_Data;
|
||||
filterData = data;
|
||||
}
|
||||
}
|
||||
else if (endIndex == 0)
|
||||
|
||||
@@ -64,6 +64,10 @@ namespace XCharts
|
||||
/// K线图。K线图的data至少包含四个数据:[open, close, lowest, highest]
|
||||
/// </summary>
|
||||
Candlestick,
|
||||
/// <summary>
|
||||
/// 甘特图。甘特图的data至少包含两个数据:[start, end]
|
||||
/// </summary>
|
||||
Gantt,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -781,7 +785,7 @@ namespace XCharts
|
||||
/// <summary>
|
||||
/// 数据项里的数据维数。
|
||||
/// </summary>
|
||||
public int showDataDimension { get { return m_ShowDataDimension; } }
|
||||
public int showDataDimension { get { return m_ShowDataDimension; } internal set { m_ShowDataDimension = value; } }
|
||||
/// <summary>
|
||||
/// 在Editor的inpsector上是否显示name参数
|
||||
/// </summary>
|
||||
@@ -1234,6 +1238,7 @@ namespace XCharts
|
||||
{
|
||||
CheckMaxCache();
|
||||
var serieData = SerieDataPool.Get();
|
||||
serieData.data.Clear();
|
||||
serieData.data.Add(xValue);
|
||||
serieData.data.Add(yValue);
|
||||
serieData.name = dataName;
|
||||
@@ -1245,10 +1250,20 @@ namespace XCharts
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加 (open, close, lowest, heighest) 数据
|
||||
/// </summary>
|
||||
/// <param name="open"></param>
|
||||
/// <param name="close"></param>
|
||||
/// <param name="lowest"></param>
|
||||
/// <param name="heighest"></param>
|
||||
/// <param name="dataName"></param>
|
||||
/// <returns></returns>
|
||||
public SerieData AddData(float open, float close, float lowest, float heighest, string dataName = null)
|
||||
{
|
||||
CheckMaxCache();
|
||||
var serieData = SerieDataPool.Get();
|
||||
serieData.data.Clear();
|
||||
serieData.data.Add(open);
|
||||
serieData.data.Add(close);
|
||||
serieData.data.Add(lowest);
|
||||
@@ -1678,7 +1693,9 @@ namespace XCharts
|
||||
return type == SerieType.Line
|
||||
|| type == SerieType.Bar
|
||||
|| type == SerieType.Scatter
|
||||
|| type == SerieType.Heatmap;
|
||||
|| type == SerieType.Heatmap
|
||||
|| type == SerieType.Gantt
|
||||
|| type == SerieType.Candlestick;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -188,9 +188,8 @@ namespace XCharts
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = m_Formatter.Replace("{value}", category);
|
||||
content = content.Replace("\\n", "\n");
|
||||
content = content.Replace("<br/>", "\n");
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, category);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
}
|
||||
@@ -224,5 +223,21 @@ namespace XCharts
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFormatterDateTime(DateTime dateTime)
|
||||
{
|
||||
var format = string.IsNullOrEmpty(numericFormatter) ? "yyyy/M/d" : numericFormatter;
|
||||
if (!string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, dateTime.ToString(format));
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = dateTime.ToString(format);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,11 +5,8 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
@@ -191,6 +188,10 @@ namespace XCharts
|
||||
/// </summary>
|
||||
public float runtimePieOffsetRadius { get; internal set; }
|
||||
public Vector3 runtimePosition { get; internal set; }
|
||||
/// <summary>
|
||||
/// 绘制区域。
|
||||
/// </summary>
|
||||
public Rect runtimeRect { get; internal set; }
|
||||
public float runtimeAngle { get; internal set; }
|
||||
public Vector3 runtiemPieOffsetCenter { get; internal set; }
|
||||
public float runtimeStackHig { get; internal set; }
|
||||
|
||||
@@ -85,5 +85,13 @@ namespace XCharts
|
||||
runtimeText.SetText(text);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetColor(Color color)
|
||||
{
|
||||
if (runtimeText != null)
|
||||
{
|
||||
runtimeText.SetColor(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Assets/XCharts/Runtime/GanttChart.cs
Normal file
137
Assets/XCharts/Runtime/GanttChart.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/GanttChart", 22)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public partial class GanttChart : CoordinateChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "GanttChart";
|
||||
var xCount = 5;
|
||||
var yCount = 5;
|
||||
|
||||
m_Grids[0].left = 60;
|
||||
m_Grids[0].right = 50;
|
||||
m_XAxes[0].type = Axis.AxisType.Time;
|
||||
m_XAxes[0].boundaryGap = false;
|
||||
m_XAxes[0].splitNumber = xCount;
|
||||
m_YAxes[0].type = Axis.AxisType.Category;
|
||||
m_YAxes[0].boundaryGap = true;
|
||||
m_YAxes[0].splitNumber = 0;
|
||||
|
||||
RemoveData();
|
||||
SerieTemplate.AddDefaultTimeGanttSerie(this, "task", yCount);
|
||||
}
|
||||
#endif
|
||||
protected override void GetSeriesMinMaxValue(Axis axis, int axisIndex, out float tempMinValue, out float tempMaxValue)
|
||||
{
|
||||
tempMinValue = int.MaxValue;
|
||||
tempMaxValue = int.MinValue;
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
if (serie.type != SerieType.Gantt) continue;
|
||||
if (serie.xAxisIndex != axis.index) continue;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.data.Count >= 2)
|
||||
{
|
||||
var xData = serieData.data[0];
|
||||
var yData = serieData.data[1];
|
||||
if (xData < tempMinValue) tempMinValue = xData;
|
||||
if (yData > tempMaxValue) tempMaxValue = yData;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tempMinValue == int.MaxValue) tempMinValue = 0;
|
||||
if (tempMaxValue == int.MinValue) tempMaxValue = 0;
|
||||
//AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true, 60);
|
||||
}
|
||||
|
||||
protected override void OnRefreshLabel()
|
||||
{
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
var serie = m_Series.GetSerie(i);
|
||||
if (serie.IsPerformanceMode()) continue;
|
||||
if (serie.type != SerieType.Gantt) continue;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.labelObject == null) continue;
|
||||
var serieLabel = SerieHelper.GetSerieLabel(serie, serieData);
|
||||
var labelShow = serie.show && serieLabel.show;
|
||||
serieData.SetLabelActive(labelShow);
|
||||
if (labelShow)
|
||||
{
|
||||
var labelColor = serieLabel.textStyle.GetColor(m_Theme.axis.textColor);
|
||||
var labelPos = serieData.runtimePosition;
|
||||
SerieLabelHelper.ResetLabel(serieData.labelObject.label, serieLabel, m_Theme, i);
|
||||
serieData.labelObject.SetPosition(labelPos);
|
||||
serieData.labelObject.SetLabelColor(labelColor);
|
||||
serieData.labelObject.SetText(serieData.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateTooltipValue(Vector2 local)
|
||||
{
|
||||
var grid = GetGrid(tooltip.runtimeGridIndex);
|
||||
if (grid == null) return;
|
||||
tooltip.runtimeDataIndex.Clear();
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
var serieGrid = GetSerieGridOrDefault(serie);
|
||||
if (grid.index != serieGrid.index) continue;
|
||||
for (int i = 0; i < serie.data.Count; i++)
|
||||
{
|
||||
var serieData = serie.GetSerieData(i);
|
||||
var highlight = serieData.runtimeRect.Contains(local);
|
||||
serieData.highlighted = highlight;
|
||||
if (highlight)
|
||||
{
|
||||
|
||||
tooltip.runtimeDataIndex.Add(serie.index);
|
||||
tooltip.runtimeDataIndex.Add(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdateTooltip()
|
||||
{
|
||||
if (tooltip.runtimeDataIndex.Count == 0)
|
||||
{
|
||||
if (tooltip.IsActive())
|
||||
{
|
||||
tooltip.SetActive(false);
|
||||
RefreshChart();
|
||||
}
|
||||
return;
|
||||
}
|
||||
var serieIndex = tooltip.runtimeDataIndex[0];
|
||||
var dataIndex = tooltip.runtimeDataIndex[1];
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (serie == null) return;
|
||||
var serieData = serie.GetSerieData(dataIndex);
|
||||
var category = serieData == null ? serie.name : serieData.name;
|
||||
TooltipHelper.SetContentAndPosition(tooltip, category, chartRect);
|
||||
tooltip.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/GanttChart.cs.meta
Normal file
11
Assets/XCharts/Runtime/GanttChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d20186b31c74d4711870603e97fd65bc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -198,6 +198,20 @@ namespace XCharts
|
||||
content = TrimAndReplaceLine(content);
|
||||
}
|
||||
|
||||
public static void ReplaceAxisLabelContent(ref string content, string value)
|
||||
{
|
||||
var mc = s_RegexForAxisLabel.Matches(content);
|
||||
foreach (var m in mc)
|
||||
{
|
||||
var old = m.ToString();
|
||||
var args = s_RegexSubForAxisLabel.Matches(m.ToString());
|
||||
var argsCount = args.Count;
|
||||
if (argsCount <= 0) continue;
|
||||
content = content.Replace(old, value);
|
||||
}
|
||||
content = TrimAndReplaceLine(content);
|
||||
}
|
||||
|
||||
public static void ReplaceSerieLabelContent(ref string content, string numericFormatter, float value, float total,
|
||||
string serieName, string dataName)
|
||||
{
|
||||
|
||||
@@ -284,6 +284,7 @@ namespace XCharts
|
||||
foreach (var component in m_Radars) component.SetAllDirty();
|
||||
m_ReinitLabel = true;
|
||||
m_ReinitTitle = true;
|
||||
m_RefreshChart = true;
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
|
||||
@@ -178,6 +178,9 @@ namespace XCharts
|
||||
case SerieType.Candlestick:
|
||||
DrawCandlestickSerie(vh, colorIndex, serie);
|
||||
break;
|
||||
case SerieType.Gantt:
|
||||
DrawGanttSerie(vh, colorIndex, serie);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,7 +243,7 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
protected void UpdateTooltipValue(Vector2 local)
|
||||
protected virtual void UpdateTooltipValue(Vector2 local)
|
||||
{
|
||||
var isCartesian = IsValue();
|
||||
var dataCount = m_Series.list.Count > 0 ? m_Series.list[0].GetDataList(dataZoom).Count : 0;
|
||||
@@ -495,6 +498,7 @@ namespace XCharts
|
||||
yAxis.painter = m_Painter;
|
||||
yAxis.refreshComponent = delegate ()
|
||||
{
|
||||
InitAxisRuntimeData(yAxis);
|
||||
string objName = ChartCached.GetYAxisName(yAxisIndex);
|
||||
var axisObj = ChartHelper.AddObject(objName, transform, graphAnchorMin,
|
||||
graphAnchorMax, chartPivot, new Vector2(chartWidth, chartHeight));
|
||||
@@ -593,6 +597,26 @@ namespace XCharts
|
||||
yAxis.refreshComponent();
|
||||
}
|
||||
|
||||
private void InitAxisRuntimeData(Axis axis)
|
||||
{
|
||||
if (axis.type != Axis.AxisType.Category) return;
|
||||
if (axis.data.Count > 0) return;
|
||||
var isYAxis = axis is YAxis;
|
||||
if (this is GanttChart)
|
||||
{
|
||||
axis.runtimeData.Clear();
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
var serie = m_Series.GetSerie(i);
|
||||
if(serie.yAxisIndex != axis.index) continue;
|
||||
for (int j = serie.data.Count - 1; j >= 0; j--)
|
||||
{
|
||||
axis.runtimeData.Add(serie.data[j].name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitAxisX()
|
||||
{
|
||||
for (int i = 0; i < m_XAxes.Count; i++)
|
||||
@@ -782,7 +806,7 @@ namespace XCharts
|
||||
return new Vector3(grid.runtimeX + scaleWid, posY);
|
||||
}
|
||||
|
||||
private void CheckMinMaxValue()
|
||||
protected virtual void CheckMinMaxValue()
|
||||
{
|
||||
if (m_XAxes == null || m_YAxes == null) return;
|
||||
for (int i = 0; i < m_XAxes.Count; i++)
|
||||
@@ -806,23 +830,7 @@ namespace XCharts
|
||||
}
|
||||
float tempMinValue = 0;
|
||||
float tempMaxValue = 0;
|
||||
|
||||
if (IsValue())
|
||||
{
|
||||
if (axis is XAxis)
|
||||
{
|
||||
SeriesHelper.GetXMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, false, axis.inverse, out tempMinValue, out tempMaxValue);
|
||||
}
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
GetSeriesMinMaxValue(axis, axisIndex, out tempMinValue, out tempMaxValue);
|
||||
if (tempMinValue != axis.runtimeMinValue || tempMaxValue != axis.runtimeMaxValue)
|
||||
{
|
||||
m_IsPlayingAnimation = true;
|
||||
@@ -866,6 +874,26 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out float tempMinValue, out float tempMaxValue)
|
||||
{
|
||||
if (IsValue())
|
||||
{
|
||||
if (axis is XAxis)
|
||||
{
|
||||
SeriesHelper.GetXMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, true, axis.inverse, out tempMinValue, out tempMaxValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SeriesHelper.GetYMinMaxValue(m_Series, null, axisIndex, false, axis.inverse, out tempMinValue, out tempMaxValue);
|
||||
}
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
}
|
||||
|
||||
protected void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
var grid = GetAxisGridOrDefault(axis);
|
||||
@@ -1571,6 +1599,7 @@ namespace XCharts
|
||||
{
|
||||
base.OnRefreshLabel();
|
||||
var anyPercentStack = SeriesHelper.IsPercentStack(m_Series, SerieType.Bar);
|
||||
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
var serie = m_Series.GetSerie(i);
|
||||
@@ -1578,6 +1607,7 @@ namespace XCharts
|
||||
if (!serie.IsCoordinateSerie()) continue;
|
||||
var total = serie.yTotal;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack(m_Series, serie.stack, SerieType.Bar);
|
||||
|
||||
for (int j = 0; j < serie.data.Count; j++)
|
||||
{
|
||||
var serieData = serie.data[j];
|
||||
@@ -1602,7 +1632,7 @@ namespace XCharts
|
||||
dimension = VisualMapHelper.GetDimension(visualMap, serieData.data.Count);
|
||||
}
|
||||
|
||||
SerieLabelHelper.ResetLabel(serieData, serieLabel, theme, i);
|
||||
SerieLabelHelper.ResetLabel(serieData.labelObject.label, serieLabel, theme, i);
|
||||
|
||||
value = serieData.data[dimension];
|
||||
var content = "";
|
||||
|
||||
178
Assets/XCharts/Runtime/Internal/CoordinateChart_DrawGantt.cs
Normal file
178
Assets/XCharts/Runtime/Internal/CoordinateChart_DrawGantt.cs
Normal file
@@ -0,0 +1,178 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public partial class CoordinateChart
|
||||
{
|
||||
protected void DrawGanttSerie(VertexHelper vh, int colorIndex, Serie serie)
|
||||
{
|
||||
if (!IsActive(serie.index)) return;
|
||||
if (serie.animation.HasFadeOut()) return;
|
||||
var showData = serie.GetDataList(null);
|
||||
var yAxis = m_YAxes[serie.yAxisIndex];
|
||||
var xAxis = m_XAxes[serie.xAxisIndex];
|
||||
var grid = GetSerieGridOrDefault(serie);
|
||||
var xCategoryWidth = AxisHelper.GetDataWidth(xAxis, grid.runtimeWidth, showData.Count, dataZoom);
|
||||
var yCategoryWidth = AxisHelper.GetDataWidth(yAxis, grid.runtimeHeight, showData.Count, dataZoom);
|
||||
var barGap = GetBarGap();
|
||||
var barWidth = serie.GetBarWidth(yCategoryWidth);
|
||||
var space = (yCategoryWidth - barWidth) / 2;
|
||||
var dataChanging = false;
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var minValue = xAxis.GetCurrMinValue(dataChangeDuration);
|
||||
var maxValue = xAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
var pX = grid.runtimeX + (xAxis.boundaryGap ? xCategoryWidth / 2 : 0);
|
||||
var pY = 0f;
|
||||
var startY = grid.runtimeY - (yAxis.boundaryGap ? 0 : yCategoryWidth / 2);
|
||||
var isTime = xAxis.type == Axis.AxisType.Time;
|
||||
|
||||
var categoryIndex = GetGanttSerieCategoryIndex(serie, grid.index);
|
||||
var dataCount = serie.data.Count;
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
var serieData = serie.data[i];
|
||||
pY = startY + (categoryIndex - 1 - i) * yCategoryWidth;
|
||||
DrawSerieData(vh, grid, serie, serieData, colorIndex, pX, pY, space, barWidth, isTime, minValue,
|
||||
maxValue, xCategoryWidth);
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSerieData(VertexHelper vh, Grid grid, Serie serie, SerieData serieData, int colorIndex,
|
||||
float pX, float pY, float space, float barWidth, bool isTime, float minValue, float maxValue,
|
||||
float xCategoryWidth)
|
||||
{
|
||||
var xStart = 0f;
|
||||
var xEnd = 0f;
|
||||
var xActualStart = 0f;
|
||||
var xActualEnd = 0f;
|
||||
var start = (int)serieData.GetData(0);
|
||||
var end = (int)serieData.GetData(1);
|
||||
var actualStart = (int)serieData.GetData(2);
|
||||
var actualEnd = (int)serieData.GetData(3);
|
||||
var enableActual = actualStart > 0 && actualEnd > 0;
|
||||
if (isTime)
|
||||
{
|
||||
var valueTotal = maxValue - minValue;
|
||||
xStart = pX + (start - minValue) / valueTotal * grid.runtimeWidth;
|
||||
xEnd = pX + (end - minValue) / valueTotal * grid.runtimeWidth;
|
||||
if (enableActual)
|
||||
{
|
||||
xActualStart = pX + (actualStart - minValue) / valueTotal * grid.runtimeWidth;
|
||||
xActualEnd = pX + (actualEnd - minValue) / valueTotal * grid.runtimeWidth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xStart = pX + start * xCategoryWidth;
|
||||
xEnd = pX + end * xCategoryWidth;
|
||||
if (enableActual)
|
||||
{
|
||||
xActualStart = pX + actualStart * xCategoryWidth;
|
||||
xActualEnd = pX + actualEnd * xCategoryWidth;
|
||||
}
|
||||
}
|
||||
var highlight = (serieData != null && serieData.highlighted)
|
||||
|| serie.highlighted;
|
||||
var itemStyle = SerieHelper.GetItemStyle(serie, serieData, highlight);
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, m_Theme, colorIndex, highlight);
|
||||
var borderWidth = itemStyle.borderWidth;
|
||||
|
||||
var rect = DrawGanttBar(vh, grid, serie, serieData, itemStyle, color, pY, pY, space, barWidth, xStart,
|
||||
xEnd);
|
||||
if (enableActual)
|
||||
{
|
||||
var defaultActualColor = SerieHelper.GetItemColor(serie, serieData, m_Theme, colorIndex, true);
|
||||
var actualColor = SerieHelper.GetItemColor0(serie, serieData, m_Theme, highlight, defaultActualColor);
|
||||
var rect2 = DrawGanttBar(vh, grid, serie, serieData, itemStyle, actualColor, pY, pY, space, barWidth,
|
||||
xActualStart, xActualEnd);
|
||||
var rect3X = Mathf.Min(rect.x, rect2.x);
|
||||
var rect3Width = Mathf.Max(rect.x + rect.width, rect2.x + rect2.width) - rect3X;
|
||||
var rect3 = new Rect(rect3X, rect.y, rect3Width, rect.height);
|
||||
serie.dataPoints.Add(rect3.center);
|
||||
serieData.runtimePosition = rect3.center;
|
||||
serieData.labelPosition = rect3.center;
|
||||
serieData.runtimeRect = rect3;
|
||||
}
|
||||
else
|
||||
{
|
||||
serie.dataPoints.Add(rect.center);
|
||||
serieData.runtimePosition = rect.center;
|
||||
serieData.labelPosition = rect.center;
|
||||
serieData.runtimeRect = rect;
|
||||
}
|
||||
}
|
||||
|
||||
private Rect DrawGanttBar(VertexHelper vh, Grid grid, Serie serie, SerieData serieData, ItemStyle itemStyle,
|
||||
Color32 color, float pX, float pY, float space, float barWidth, float xStart, float xEnd)
|
||||
{
|
||||
|
||||
var borderWidth = itemStyle.borderWidth;
|
||||
var plb = new Vector3(xStart + borderWidth, pY + space + borderWidth);
|
||||
var plt = new Vector3(xStart + borderWidth, pY + space + barWidth - borderWidth);
|
||||
var prt = new Vector3(xEnd - borderWidth, pY + space + barWidth - borderWidth);
|
||||
var prb = new Vector3(xEnd - borderWidth, pY + space + borderWidth);
|
||||
var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2);
|
||||
var itemWidth = Mathf.Abs(prt.x - plb.x);
|
||||
var itemHeight = Mathf.Abs(plt.y - prb.y);
|
||||
if (serie.clip)
|
||||
{
|
||||
plb = ClampInGrid(grid, plb);
|
||||
plt = ClampInGrid(grid, plt);
|
||||
prt = ClampInGrid(grid, prt);
|
||||
prb = ClampInGrid(grid, prb);
|
||||
center = ClampInGrid(grid, center);
|
||||
}
|
||||
if (ItemStyleHelper.IsNeedCorner(itemStyle))
|
||||
{
|
||||
UGL.DrawRoundRectangle(vh, center, itemWidth, itemHeight, color, color, 0,
|
||||
itemStyle.cornerRadius, true, 0.5f);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, color, color,
|
||||
serie.clip, grid);
|
||||
}
|
||||
if (borderWidth != 0)
|
||||
{
|
||||
UGL.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, itemStyle.borderColor, 0,
|
||||
itemStyle.cornerRadius, true, 0.5f);
|
||||
}
|
||||
return new Rect(plb.x, plb.y, xEnd - xStart, barWidth);
|
||||
}
|
||||
|
||||
private int GetGanttSerieCategoryIndex(Serie currSerie, int gridIndex)
|
||||
{
|
||||
var count = m_Series.Count;
|
||||
var index = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var serie = m_Series.GetSerie(i);
|
||||
if (serie.type != SerieType.Gantt) continue;
|
||||
var grid = GetSerieGridOrDefault(serie);
|
||||
if (grid.index != gridIndex) continue;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
index++;
|
||||
}
|
||||
if (serie.index == currSerie.index)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 81895b3c97e684e8090572c7e64b396e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -99,7 +99,7 @@ namespace XCharts
|
||||
{
|
||||
var value = serieData.GetCurrData(1);
|
||||
var max = radar.GetIndicatorMax(n);
|
||||
SerieLabelHelper.ResetLabel(serieData, serieLabel, chart.theme, i);
|
||||
SerieLabelHelper.ResetLabel(serieData.labelObject.label, serieLabel, chart.theme, i);
|
||||
serieData.SetLabelActive(serieData.labelPosition != Vector3.zero);
|
||||
serieData.labelObject.SetLabelPosition(serieLabel.offset);
|
||||
var content = SerieLabelHelper.GetFormatterContent(serie, serieData, value, max, serieLabel);
|
||||
|
||||
@@ -53,6 +53,25 @@ namespace XCharts
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
}
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
if (axis.interval > 0)
|
||||
{
|
||||
if (coordinateWid <= 0) return 0;
|
||||
int num = Mathf.CeilToInt(axis.runtimeMinMaxRange / axis.interval);
|
||||
int maxNum = Mathf.CeilToInt(coordinateWid / 15);
|
||||
if (num > maxNum)
|
||||
{
|
||||
axis.interval *= 2;
|
||||
num = Mathf.CeilToInt(axis.runtimeMinMaxRange / axis.interval);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
else
|
||||
{
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
}
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
@@ -146,6 +165,23 @@ namespace XCharts
|
||||
}
|
||||
return axis.axisLabel.GetFormatterContent(value, minValue, maxValue, true);
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
if (minValue == 0 && maxValue == 0) return string.Empty;
|
||||
var value = 0f;
|
||||
if (axis.interval > 0)
|
||||
{
|
||||
if (index == split) value = maxValue;
|
||||
else value = minValue + index * axis.interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = minValue + (maxValue - minValue) * index / split;
|
||||
}
|
||||
var timestamp = (int)value;
|
||||
var dateTime = DateTimeUtil.GetDateTime(timestamp);
|
||||
return axis.axisLabel.GetFormatterDateTime(dateTime);
|
||||
}
|
||||
var showData = axis.GetDataList(dataZoom);
|
||||
int dataCount = showData.Count;
|
||||
if (dataCount <= 0) return "";
|
||||
@@ -177,11 +213,12 @@ namespace XCharts
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
int tick = Mathf.RoundToInt(axis.data.Count * 1f / splitNum);
|
||||
var data = axis.GetDataList();
|
||||
int tick = Mathf.RoundToInt(data.Count * 1f / splitNum);
|
||||
if (axis.boundaryGap)
|
||||
return Mathf.CeilToInt(axis.data.Count * 1.0f / tick) + 1;
|
||||
return Mathf.CeilToInt(data.Count * 1.0f / tick) + 1;
|
||||
else
|
||||
return Mathf.CeilToInt(axis.data.Count * 1.0f / tick);
|
||||
return Mathf.CeilToInt(data.Count * 1.0f / tick);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -209,10 +246,11 @@ namespace XCharts
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsCategory() && axis.data.Count > 0)
|
||||
var data = axis.GetDataList();
|
||||
if (axis.IsCategory() && data.Count > 0)
|
||||
{
|
||||
int tick = Mathf.RoundToInt(axis.data.Count * 1f / splitNum);
|
||||
var count = axis.boundaryGap ? axis.data.Count : axis.data.Count - 1;
|
||||
int tick = Mathf.RoundToInt(data.Count * 1f / splitNum);
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
if (count <= 0) return 0;
|
||||
var each = coordinateWidth / count;
|
||||
if (index >= num - 1)
|
||||
@@ -232,9 +270,10 @@ namespace XCharts
|
||||
|
||||
internal static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
|
||||
{
|
||||
if (axis.data.Count > 0)
|
||||
var data = axis.GetDataList();
|
||||
if (data.Count > 0)
|
||||
{
|
||||
var count = axis.boundaryGap ? axis.data.Count : axis.data.Count - 1;
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
return count > 0 ? coordinateWidth / count : coordinateWidth;
|
||||
}
|
||||
else
|
||||
@@ -249,7 +288,7 @@ namespace XCharts
|
||||
/// </summary>
|
||||
/// <param name="minValue"></param>
|
||||
/// <param name="maxValue"></param>
|
||||
internal static void AdjustMinMaxValue(Axis axis, ref float minValue, ref float maxValue, bool needFormat)
|
||||
internal static void AdjustMinMaxValue(Axis axis, ref float minValue, ref float maxValue, bool needFormat, int ceilRate = 0)
|
||||
{
|
||||
if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
@@ -278,6 +317,7 @@ namespace XCharts
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ceilRate == 0) ceilRate = axis.ceilRate;
|
||||
switch (axis.minMaxType)
|
||||
{
|
||||
case Axis.AxisMinMaxType.Default:
|
||||
@@ -287,22 +327,22 @@ namespace XCharts
|
||||
else if (minValue > 0 && maxValue > 0)
|
||||
{
|
||||
minValue = 0;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, axis.ceilRate) : maxValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
else if (minValue < 0 && maxValue < 0)
|
||||
{
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, axis.ceilRate) : minValue;
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, axis.ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, axis.ceilRate) : maxValue;
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
break;
|
||||
case Axis.AxisMinMaxType.MinMax:
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, axis.ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, axis.ceilRate) : maxValue;
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -320,7 +360,7 @@ namespace XCharts
|
||||
internal static bool NeedShowSplit(Axis axis)
|
||||
{
|
||||
if (!axis.show) return false;
|
||||
if (axis.IsCategory() && axis.data.Count <= 0) return false;
|
||||
if (axis.IsCategory() && axis.GetDataList().Count <= 0) return false;
|
||||
else if (axis.IsValue() && axis.runtimeMinValue == 0 && axis.runtimeMaxValue == 0) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,32 @@ namespace XCharts
|
||||
return color;
|
||||
}
|
||||
}
|
||||
internal static Color32 GetItemColor0(Serie serie, SerieData serieData, ChartTheme theme, bool highlight, Color32 defaultColor)
|
||||
{
|
||||
if (serie == null) return ChartConst.clearColor32;
|
||||
if (highlight)
|
||||
{
|
||||
var itemStyleEmphasis = GetItemStyleEmphasis(serie, serieData);
|
||||
if (itemStyleEmphasis != null && !ChartHelper.IsClearColor(itemStyleEmphasis.color))
|
||||
{
|
||||
var color = itemStyleEmphasis.color0;
|
||||
ChartHelper.SetColorOpacity(ref color, itemStyleEmphasis.opacity);
|
||||
return color;
|
||||
}
|
||||
}
|
||||
var itemStyle = GetItemStyle(serie, serieData);
|
||||
if (!ChartHelper.IsClearColor(itemStyle.color0))
|
||||
{
|
||||
return itemStyle.GetColor0();
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = defaultColor;
|
||||
if (highlight) color = ChartHelper.GetHighlightColor(color);
|
||||
ChartHelper.SetColorOpacity(ref color, itemStyle.opacity);
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
internal static Color32 GetItemToColor(Serie serie, SerieData serieData, ChartTheme theme, int index, bool highlight)
|
||||
{
|
||||
|
||||
@@ -75,14 +75,13 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
public static void ResetLabel(SerieData serieData, SerieLabel label, ChartTheme theme, int colorIndex)
|
||||
public static void ResetLabel(ChartText labelObject, SerieLabel label, ChartTheme theme, int colorIndex)
|
||||
{
|
||||
if (serieData.labelObject == null) return;
|
||||
if (serieData.labelObject.label == null) return;
|
||||
serieData.labelObject.label.SetColor(!ChartHelper.IsClearColor(label.textStyle.color) ? label.textStyle.color :
|
||||
if (labelObject == null) return;
|
||||
labelObject.SetColor(!ChartHelper.IsClearColor(label.textStyle.color) ? label.textStyle.color :
|
||||
(Color)theme.GetColor(colorIndex));
|
||||
serieData.labelObject.label.SetFontSize(label.textStyle.GetFontSize(theme.common));
|
||||
serieData.labelObject.label.SetFontStyle(label.textStyle.fontStyle);
|
||||
labelObject.SetFontSize(label.textStyle.GetFontSize(theme.common));
|
||||
labelObject.SetFontStyle(label.textStyle.fontStyle);
|
||||
}
|
||||
|
||||
public static bool CanShowLabel(Serie serie, SerieData serieData, SerieLabel label, int dimesion)
|
||||
|
||||
@@ -232,6 +232,14 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitGanttTooltip(ref StringBuilder sb, Tooltip tooltip, Serie serie, int index,
|
||||
ChartTheme theme, string category)
|
||||
{
|
||||
//if (tooltip.runtimeGridIndex >= 0) return;
|
||||
//if (serie.index != index || serie.type != SerieType.Gantt) return;
|
||||
sb.Append(serie.name);
|
||||
}
|
||||
|
||||
private static void InitDefaultContent(ref StringBuilder sb, Tooltip tooltip, Serie serie, int index,
|
||||
string category, ChartTheme theme = null, DataZoom dataZoom = null, bool isCartesian = false,
|
||||
Radar radar = null)
|
||||
@@ -261,6 +269,9 @@ namespace XCharts
|
||||
case SerieType.Gauge:
|
||||
InitGaugeTooltip(ref sb, tooltip, serie, index, theme);
|
||||
break;
|
||||
case SerieType.Gantt:
|
||||
InitGanttTooltip(ref sb, tooltip, serie, index, theme, category);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace XCharts
|
||||
case SerieType.Gauge: AddDefaultGaugeSerie(chart, serieName); break;
|
||||
case SerieType.Ring: AddDefaultRingSerie(chart, serieName); break;
|
||||
case SerieType.Candlestick: AddDefaultCandlestickSerie(chart, serieName); break;
|
||||
case SerieType.Gantt: AddDefaultCategoryGanttSerie(chart, serieName); break;
|
||||
default: Debug.LogError("AddDefaultSerie: not support serieType yet:" + serieType); break;
|
||||
}
|
||||
}
|
||||
@@ -183,5 +184,35 @@ namespace XCharts
|
||||
}
|
||||
return defaultDataCount;
|
||||
}
|
||||
|
||||
public static Serie AddDefaultCategoryGanttSerie(BaseChart chart, string serieName, int dataCount = 0, int min = 0, int max = 0)
|
||||
{
|
||||
var serie = chart.AddSerie(SerieType.Gantt, serieName);
|
||||
serie.showDataName = true;
|
||||
serie.showDataDimension = 2;
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
var start = Random.Range(min, max);
|
||||
var end = Random.Range(start + 1, max);
|
||||
serie.AddXYData(start, end, "task-" + (i + 1));
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
|
||||
public static Serie AddDefaultTimeGanttSerie(BaseChart chart, string serieName, int dataCount = 0)
|
||||
{
|
||||
var serie = chart.AddSerie(SerieType.Gantt, serieName);
|
||||
serie.showDataName = true;
|
||||
serie.showDataDimension = 2;
|
||||
var timestamp = DateTimeUtil.GetTimestamp();
|
||||
var now = DateTimeUtil.GetDateTime(timestamp);
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
var start = timestamp + Random.Range(1, 6) * 3600 * 24;
|
||||
var end = start + Random.Range(1, 10) * 3600 * 24;
|
||||
serie.AddXYData(start, end, "task-" + (i + 1));
|
||||
}
|
||||
return serie;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
Assets/XCharts/Runtime/Utils/DateTimeUtil.cs
Normal file
33
Assets/XCharts/Runtime/Utils/DateTimeUtil.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public static class DateTimeUtil
|
||||
{
|
||||
private static readonly DateTime k_DateTime1970 = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
|
||||
|
||||
public static int GetTimestamp()
|
||||
{
|
||||
return (int)(DateTime.Now - k_DateTime1970).TotalSeconds;
|
||||
}
|
||||
|
||||
public static int GetTimestamp(DateTime time)
|
||||
{
|
||||
return (int)(time - k_DateTime1970).TotalSeconds;
|
||||
}
|
||||
|
||||
public static DateTime GetDateTime(int timestamp)
|
||||
{
|
||||
long span = ((long)timestamp) * 10000000;
|
||||
return k_DateTime1970.Add(new TimeSpan(span));
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Utils/DateTimeUtil.cs.meta
Normal file
11
Assets/XCharts/Runtime/Utils/DateTimeUtil.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f0ac80f189a04b5c826f40c8bc8af64
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -5,14 +5,24 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XChartsDemo
|
||||
{
|
||||
[CustomPropertyDrawer(typeof(ChartModule), true)]
|
||||
public class ChartModuleDrawer : PropertyDrawer
|
||||
internal class ChartModuleDrawer : PropertyDrawer
|
||||
{
|
||||
public class Styles
|
||||
{
|
||||
public static readonly GUIContent iconAdd = new GUIContent("+", "Add");
|
||||
public static readonly GUIContent iconRemove = new GUIContent("-", "Remove");
|
||||
public static readonly GUIContent iconUp = new GUIContent("↑", "Up");
|
||||
public static readonly GUIContent iconDown = new GUIContent("↓", "Down");
|
||||
public static readonly GUIStyle invisibleButton = "InvisibleButton";
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
|
||||
{
|
||||
Rect drawRect = pos;
|
||||
@@ -25,9 +35,29 @@ namespace XChartsDemo
|
||||
SerializedProperty m_Title = prop.FindPropertyRelative("m_Title");
|
||||
SerializedProperty m_Selected = prop.FindPropertyRelative("m_Selected");
|
||||
SerializedProperty m_Panel = prop.FindPropertyRelative("m_Panel");
|
||||
var fieldWid = EditorGUIUtility.currentViewWidth - 30 - 5 - 40 - 80 - 50 - 100 - 6 * 2;
|
||||
var fieldWid = EditorGUIUtility.currentViewWidth - 30 - 5 - 40 - 80 - 50 - 100 - 6 * 2 - 70;
|
||||
drawRect.width = 15;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
var oldFlag = m_Selected.boolValue;
|
||||
EditorGUI.PropertyField(drawRect, m_Selected, GUIContent.none);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
var demo = prop.serializedObject.targetObject as Demo;
|
||||
var index = GetIndex(prop);
|
||||
var selectedIndex = demo.GetSelectedModule();
|
||||
if (selectedIndex != index)
|
||||
{
|
||||
for (int i = 0; i < demo.chartModules.Count; i++)
|
||||
{
|
||||
demo.chartModules[i].select = i == index && m_Selected.boolValue;
|
||||
}
|
||||
demo.InitModuleButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Selected.boolValue = oldFlag;
|
||||
}
|
||||
}
|
||||
drawRect.x += 17;
|
||||
drawRect.width = 80;
|
||||
EditorGUI.PropertyField(drawRect, m_Name, GUIContent.none);
|
||||
@@ -43,11 +73,83 @@ namespace XChartsDemo
|
||||
drawRect.x += 102;
|
||||
drawRect.width = 40;
|
||||
EditorGUI.PropertyField(drawRect, m_Column, GUIContent.none);
|
||||
|
||||
var btnWidth = 12;
|
||||
drawRect.x += 42;
|
||||
drawRect.width = btnWidth;
|
||||
if (GUI.Button(drawRect, Styles.iconUp, Styles.invisibleButton))
|
||||
{
|
||||
var demo = prop.serializedObject.targetObject as Demo;
|
||||
var index = GetIndex(prop);
|
||||
if (index >= 0)
|
||||
{
|
||||
Swap(demo.chartModules, index, index - 1);
|
||||
demo.InitModuleButton();
|
||||
}
|
||||
}
|
||||
drawRect.x += btnWidth + 1;
|
||||
if (GUI.Button(drawRect, Styles.iconDown, Styles.invisibleButton))
|
||||
{
|
||||
var demo = prop.serializedObject.targetObject as Demo;
|
||||
var index = GetIndex(prop);
|
||||
if (index >= 0)
|
||||
{
|
||||
Swap(demo.chartModules, index, index + 1);
|
||||
demo.InitModuleButton();
|
||||
}
|
||||
}
|
||||
drawRect.x += btnWidth + 1;
|
||||
if (GUI.Button(drawRect, Styles.iconAdd, Styles.invisibleButton))
|
||||
{
|
||||
var demo = prop.serializedObject.targetObject as Demo;
|
||||
var index = GetIndex(prop);
|
||||
if (index >= 0)
|
||||
{
|
||||
demo.chartModules.Insert(index + 1, new ChartModule());
|
||||
demo.InitModuleButton();
|
||||
}
|
||||
}
|
||||
drawRect.x += 16;
|
||||
if (GUI.Button(drawRect, Styles.iconRemove, Styles.invisibleButton))
|
||||
{
|
||||
var demo = prop.serializedObject.targetObject as Demo;
|
||||
var index = GetIndex(prop);
|
||||
if (index >= 0)
|
||||
{
|
||||
demo.chartModules.RemoveAt(index);
|
||||
demo.InitModuleButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
|
||||
{
|
||||
return 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
|
||||
}
|
||||
|
||||
private int GetIndex(SerializedProperty prop)
|
||||
{
|
||||
int index = -1;
|
||||
var sindex = prop.propertyPath.LastIndexOf('[');
|
||||
var eindex = prop.propertyPath.LastIndexOf(']');
|
||||
if (sindex >= 0 && eindex >= 0)
|
||||
{
|
||||
var str = prop.propertyPath.Substring(sindex + 1, eindex - sindex - 1);
|
||||
int.TryParse(str, out index);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
private static bool Swap<T>(List<T> list, int index1, int index2)
|
||||
{
|
||||
if (index1 < 0 || index1 >= list.Count) return false;
|
||||
if (index2 < 0 || index2 >= list.Count) return false;
|
||||
var temp = list[index1];
|
||||
list[index1] = list[index2];
|
||||
list[index2] = temp;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace XChartsDemo
|
||||
/// </summary>
|
||||
|
||||
[CustomEditor(typeof(Demo), false)]
|
||||
public class DemoEditor : Editor
|
||||
internal class DemoEditor : Editor
|
||||
{
|
||||
protected Demo m_Target;
|
||||
protected SerializedProperty m_Script;
|
||||
|
||||
@@ -16,11 +16,11 @@ namespace XChartsDemo
|
||||
[System.Serializable]
|
||||
public class ChartModule
|
||||
{
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private string m_SubName;
|
||||
[SerializeField] private string m_Name = "Name";
|
||||
[SerializeField] private string m_SubName = "SubName";
|
||||
[SerializeField] private int m_Column = 3;
|
||||
|
||||
[SerializeField] private string m_Title;
|
||||
[SerializeField] private string m_Title = "Title";
|
||||
[SerializeField] private bool m_Selected;
|
||||
[SerializeField] private GameObject m_Panel;
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace XChartsDemo
|
||||
public bool select { get { return m_Selected; } set { m_Selected = value; } }
|
||||
public GameObject panel { get { return m_Panel; } set { m_Panel = value; } }
|
||||
public Button button { get; set; }
|
||||
public int index { get; internal set; }
|
||||
}
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
@@ -44,6 +45,7 @@ namespace XChartsDemo
|
||||
[SerializeField] private Color m_ButtonNormalColor;
|
||||
[SerializeField] private Color m_ButtonSelectedColor;
|
||||
[SerializeField] private Color m_ButtonHighlightColor;
|
||||
[SerializeField] public int lastSelectedModuleIndex = -1;
|
||||
[SerializeField] private List<ChartModule> m_ChartModule = new List<ChartModule>();
|
||||
|
||||
private GameObject m_BtnClone;
|
||||
@@ -60,6 +62,8 @@ namespace XChartsDemo
|
||||
private ScrollRect m_ScrollRect;
|
||||
private Mask m_Mark;
|
||||
|
||||
public List<ChartModule> chartModules { get { return m_ChartModule; } }
|
||||
|
||||
void Awake()
|
||||
{
|
||||
m_SelectedTheme = Theme.Default;
|
||||
@@ -118,6 +122,7 @@ namespace XChartsDemo
|
||||
private void SetChartRootInfo(ChartModule module)
|
||||
{
|
||||
var chartRoot = module.panel;
|
||||
if (chartRoot == null) return;
|
||||
var grid = chartRoot.GetComponent<GridLayoutGroup>();
|
||||
var hig = Mathf.CeilToInt(chartRoot.transform.childCount * 1f / module.column) * (grid.cellSize.y + grid.spacing.y);
|
||||
SetChartGridLayoutGroup(grid, module.column);
|
||||
@@ -137,23 +142,6 @@ namespace XChartsDemo
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (m_ChartModule.Count <= 0) return;
|
||||
int selectedModuleIndex = -1;
|
||||
for (int i = 0; i < m_ChartModule.Count; i++)
|
||||
{
|
||||
if (selectedModuleIndex >= 0 && i > selectedModuleIndex)
|
||||
{
|
||||
m_ChartModule[i].select = false;
|
||||
}
|
||||
else if (m_ChartModule[i].select)
|
||||
{
|
||||
selectedModuleIndex = i;
|
||||
}
|
||||
}
|
||||
if (selectedModuleIndex < 0) selectedModuleIndex = 0;
|
||||
if (selectedModuleIndex != m_LastSelectedModuleIndex)
|
||||
{
|
||||
InitModuleButton();
|
||||
}
|
||||
if (!Application.isPlaying) m_Mark.enabled = false;
|
||||
|
||||
if (m_LastCheckLeftWidth != m_LeftWidth)
|
||||
@@ -164,14 +152,25 @@ namespace XChartsDemo
|
||||
#endif
|
||||
}
|
||||
|
||||
void InitModuleButton()
|
||||
public int GetSelectedModule()
|
||||
{
|
||||
for (int i = 0; i < m_ChartModule.Count; i++)
|
||||
{
|
||||
if (m_ChartModule[i].select) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void InitModuleButton()
|
||||
{
|
||||
var btnPanel = transform.Find("chart_list");
|
||||
m_BtnClone = transform.Find("btn_clone").gameObject;
|
||||
m_BtnClone.SetActive(false);
|
||||
ChartHelper.HideAllObject(btnPanel);
|
||||
foreach (var module in m_ChartModule)
|
||||
ChartHelper.DestroyAllChildren(btnPanel.transform);
|
||||
for (int i = 0; i < m_ChartModule.Count; i++)
|
||||
{
|
||||
var module = m_ChartModule[i];
|
||||
module.index = i;
|
||||
var btnName = "btn_" + module.name;
|
||||
GameObject btn;
|
||||
if (btnPanel.Find(btnName))
|
||||
@@ -193,19 +192,19 @@ namespace XChartsDemo
|
||||
module.button.transform.Find("Text").GetComponent<Text>().text = module.name.Replace("\\n", "\n");
|
||||
module.button.transform.Find("SubText").GetComponent<Text>().text = module.subName.Replace("\\n", "\n");
|
||||
|
||||
ChartHelper.ClearEventListener(btn.gameObject);
|
||||
ChartHelper.AddEventListener(btn.gameObject, EventTriggerType.PointerDown, (data) =>
|
||||
{
|
||||
ClickModule(module);
|
||||
});
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_ChartModule.Count; i++)
|
||||
{
|
||||
var module = m_ChartModule[i];
|
||||
module.index = i;
|
||||
if (module.select)
|
||||
{
|
||||
ClickModule(module);
|
||||
m_LastSelectedModuleIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -213,28 +212,38 @@ namespace XChartsDemo
|
||||
|
||||
void ClickModule(ChartModule selectedModule)
|
||||
{
|
||||
if (lastSelectedModuleIndex >= 0)
|
||||
{
|
||||
m_ChartModule[lastSelectedModuleIndex].select = false;
|
||||
}
|
||||
lastSelectedModuleIndex = selectedModule.index;
|
||||
foreach (var module in m_ChartModule)
|
||||
{
|
||||
if (selectedModule != module)
|
||||
if (module.index != lastSelectedModuleIndex)
|
||||
{
|
||||
var block = module.button.colors;
|
||||
block.highlightedColor = m_ButtonHighlightColor;
|
||||
block.selectedColor = m_ButtonNormalColor;
|
||||
block.normalColor = m_ButtonNormalColor;
|
||||
module.button.colors = block;
|
||||
module.panel.SetActive(false);
|
||||
module.select = false;
|
||||
if (module.panel != null)
|
||||
module.panel.SetActive(false);
|
||||
//module.select = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
var block = module.button.colors;
|
||||
block.highlightedColor = m_ButtonSelectedColor;
|
||||
block.selectedColor = m_ButtonSelectedColor;
|
||||
block.normalColor = m_ButtonSelectedColor;
|
||||
module.button.colors = block;
|
||||
module.panel.SetActive(true);
|
||||
module.select = true;
|
||||
if (module.panel != null)
|
||||
module.panel.SetActive(true);
|
||||
// module.select = true;
|
||||
}
|
||||
}
|
||||
m_ScrollRect.content = selectedModule.panel.GetComponent<RectTransform>();
|
||||
if (selectedModule.panel != null)
|
||||
m_ScrollRect.content = selectedModule.panel.GetComponent<RectTransform>();
|
||||
SetChartRootInfo(selectedModule);
|
||||
m_Title.text = string.IsNullOrEmpty(selectedModule.title) ?
|
||||
selectedModule.name : selectedModule.title;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace XChartsDemo
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[ExecuteInEditMode]
|
||||
public class Demo_Animation : MonoBehaviour
|
||||
internal class Demo_Animation : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private int m_FadeInDuration = 1000;
|
||||
[SerializeField] private int m_FadeOutDuration = 1000;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace XChartsDemo
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
[ExecuteInEditMode]
|
||||
public class Demo_Performance : MonoBehaviour
|
||||
internal class Demo_Performance : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float fps = 0;
|
||||
[SerializeField] private int m_MaxCacheDataNumber = 3000;
|
||||
|
||||
@@ -10,7 +10,7 @@ using UnityEngine.UI;
|
||||
|
||||
namespace XChartsDemo
|
||||
{
|
||||
public static class UIUtil
|
||||
internal static class UIUtil
|
||||
{
|
||||
|
||||
public static RectTransform GetRectTransform(Transform transform, string path)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user