mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-28 03:58:49 +00:00
3.0 commit
This commit is contained in:
@@ -1,833 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using System.Text;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class of all charts.
|
||||
/// 所有Chart的基类。
|
||||
/// </summary>
|
||||
public partial class BaseChart
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of chart.
|
||||
/// </summary>
|
||||
public string chartName
|
||||
{
|
||||
get { return m_ChartName; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && XChartsMgr.Instance.ContainsChart(value))
|
||||
{
|
||||
Debug.LogError("chartName repeated:" + value);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ChartName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The theme.
|
||||
/// </summary>
|
||||
public ChartTheme theme { get { return m_Theme; } set { m_Theme = value; } }
|
||||
/// <summary>
|
||||
/// The title setting of chart.
|
||||
/// 标题组件
|
||||
/// </summary>
|
||||
public Title title { get { return m_Titles.Count > 0 ? m_Titles[0] : null; } }
|
||||
public List<Title> titles { get { return m_Titles; } }
|
||||
/// <summary>
|
||||
/// The legend setting of chart.
|
||||
/// 图例组件
|
||||
/// </summary>
|
||||
public Legend legend { get { return m_Legends.Count > 0 ? m_Legends[0] : null; } }
|
||||
public List<Legend> legends { get { return m_Legends; } }
|
||||
/// <summary>
|
||||
/// The tooltip setting of chart.
|
||||
/// 提示框组件
|
||||
/// </summary>
|
||||
public Tooltip tooltip { get { return m_Tooltips.Count > 0 ? m_Tooltips[0] : null; } }
|
||||
/// <summary>
|
||||
/// The series setting of chart.
|
||||
/// 系列列表
|
||||
/// </summary>
|
||||
public Series series { get { return m_Series; } }
|
||||
/// <summary>
|
||||
/// Global parameter setting component.
|
||||
/// 全局设置组件。
|
||||
/// </summary>
|
||||
public Settings settings { get { return m_Settings; } }
|
||||
/// <summary>
|
||||
/// dataZoom component.
|
||||
/// 区域缩放组件。
|
||||
/// </summary>
|
||||
public DataZoom dataZoom { get { return m_DataZooms.Count > 0 ? m_DataZooms[0] : null; } }
|
||||
public List<DataZoom> dataZooms { get { return m_DataZooms; } }
|
||||
/// <summary>
|
||||
/// visualMap component.
|
||||
/// 视觉映射组件。
|
||||
/// </summary>
|
||||
public VisualMap visualMap { get { return m_VisualMaps.Count > 0 ? m_VisualMaps[0] : null; } }
|
||||
public List<VisualMap> visualMaps { get { return m_VisualMaps; } }
|
||||
/// <summary>
|
||||
/// The x of chart.
|
||||
/// 图表的X
|
||||
/// </summary>
|
||||
public float chartX { get { return m_ChartX; } }
|
||||
/// <summary>
|
||||
/// The y of chart.
|
||||
/// 图表的Y
|
||||
/// </summary>
|
||||
public float chartY { get { return m_ChartY; } }
|
||||
/// <summary>
|
||||
/// The width of chart.
|
||||
/// 图表的宽
|
||||
/// </summary>
|
||||
public float chartWidth { get { return m_ChartWidth; } }
|
||||
/// <summary>
|
||||
/// The height of chart.
|
||||
/// 图表的高
|
||||
/// </summary>
|
||||
public float chartHeight { get { return m_ChartHeight; } }
|
||||
public Vector2 chartMinAnchor { get { return m_ChartMinAnchor; } }
|
||||
public Vector2 chartMaxAnchor { get { return m_ChartMaxAnchor; } }
|
||||
public Vector2 chartPivot { get { return m_ChartPivot; } }
|
||||
public Vector2 chartSizeDelta { get { return m_ChartSizeDelta; } }
|
||||
/// <summary>
|
||||
/// The position of chart.
|
||||
/// 图表的左下角起始坐标。
|
||||
/// </summary>
|
||||
public Vector3 chartPosition { get { return m_ChartPosition; } }
|
||||
public Rect chartRect { get { return m_ChartRect; } }
|
||||
/// <summary>
|
||||
/// 自定义绘制回调。在绘制Serie前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper> onCustomDraw { set { m_OnCustomDrawBaseCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Serie绘制回调。在每个Serie绘制完前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper, Serie> onCustomDrawBeforeSerie { set { m_OnCustomDrawSerieBeforeCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Serie绘制回调。在每个Serie绘制完后调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper, Serie> onCustomDrawAfterSerie { set { m_OnCustomDrawSerieAfterCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Top绘制回调。在绘制Tooltip前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper> onCustomDrawTop { set { m_OnCustomDrawTopCallback = value; } }
|
||||
/// <summary>
|
||||
/// the callback function of click pie area.
|
||||
/// 点击饼图区域回调。参数:PointerEventData,SerieIndex,SerieDataIndex
|
||||
/// </summary>
|
||||
public Action<PointerEventData, int, int> onPointerClickPie { set { m_OnPointerClickPie = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerClickPie; } }
|
||||
|
||||
/// <summary>
|
||||
/// Redraw chart in next frame.
|
||||
/// 在下一帧刷新图表。
|
||||
/// </summary>
|
||||
public void RefreshChart()
|
||||
{
|
||||
m_RefreshChart = true;
|
||||
if (m_Painter) m_Painter.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all series and legend data.
|
||||
/// It just emptying all of serie's data without emptying the list of series.
|
||||
/// 清除所有数据,系列中只是移除数据,列表会保留。
|
||||
/// </summary>
|
||||
public virtual void ClearData()
|
||||
{
|
||||
m_Series.ClearData();
|
||||
foreach (var legend in m_Legends) legend.ClearData();
|
||||
tooltip.ClearValue();
|
||||
m_CheckAnimation = false;
|
||||
m_ReinitLabel = true;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all data from series and legend.
|
||||
/// The series list is also cleared.
|
||||
/// 清除所有系列和图例数据,系列的列表也会被清除。
|
||||
/// </summary>
|
||||
public virtual void RemoveData()
|
||||
{
|
||||
foreach (var legend in m_Legends) legend.ClearData();
|
||||
foreach (var radar in m_Radars) radar.indicatorList.Clear();
|
||||
m_Series.RemoveAll();
|
||||
tooltip.ClearValue();
|
||||
m_CheckAnimation = false;
|
||||
m_ReinitLabel = true;
|
||||
m_SerieLabelRoot = null;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove legend and serie by name.
|
||||
/// 清除指定系列名称的数据。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
public virtual void RemoveData(string serieName)
|
||||
{
|
||||
m_Series.RemoveSerie(serieName);
|
||||
foreach (var legend in m_Legends) legend.RemoveData(serieName);
|
||||
m_SerieLabelRoot = null;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a serie to serie list.
|
||||
/// 添加一个系列到系列列表中。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="type">the type of serie</param>
|
||||
/// <param name="show">whether to show this serie</param>
|
||||
/// <returns>the added serie</returns>
|
||||
public virtual Serie AddSerie(SerieType type, string serieName = null, bool show = true, bool addToHead = false)
|
||||
{
|
||||
return m_Series.AddSerie(type, serieName, show, addToHead);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a serie to serie list.
|
||||
/// 通过字符串类型的serieType添加一个系列到系列列表中。如果serieType不是已定义的SerieType类型,则设置为Custom类型。
|
||||
/// </summary>
|
||||
/// <param name="serieType"></param>
|
||||
/// <param name="serieName"></param>
|
||||
/// <param name="show"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Serie AddSerie(string serieType, string serieName = null, bool show = true, bool addToHead = false)
|
||||
{
|
||||
var type = SerieType.Custom;
|
||||
var list = Enum.GetNames(typeof(SerieType));
|
||||
foreach (var t in list)
|
||||
{
|
||||
if (t.Equals(serieType)) type = (SerieType)Enum.Parse(typeof(SerieType), t);
|
||||
}
|
||||
return AddSerie(type, serieName, show, addToHead);
|
||||
}
|
||||
|
||||
public virtual Serie InsertSerie(int index, SerieType serieType, string serieName = null, bool show = true)
|
||||
{
|
||||
return m_Series.InsertSerie(index, serieType, serieName, show);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a data to serie.
|
||||
/// If serieName doesn't exist in legend,will be add to legend.
|
||||
/// 添加一个数据到指定的系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="data">the data to add</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public virtual SerieData AddData(string serieName, double data, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddData(serieName, data, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieName);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a data to serie.
|
||||
/// 添加一个数据到指定的系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie</param>
|
||||
/// <param name="data">the data to add</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public virtual SerieData AddData(int serieIndex, double data, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddData(serieIndex, data, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an arbitray dimension data to serie,such as (x,y,z,...).
|
||||
/// 添加多维数据(x,y,z...)到指定的系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="multidimensionalData">the (x,y,z,...) data</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public virtual SerieData AddData(string serieName, List<double> multidimensionalData, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddData(serieName, multidimensionalData, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieName);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an arbitray dimension data to serie,such as (x,y,z,...).
|
||||
/// 添加多维数据(x,y,z...)到指定的系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie,index starts at 0</param>
|
||||
/// <param name="multidimensionalData">the (x,y,z,...) data</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public virtual SerieData AddData(int serieIndex, List<double> multidimensionalData, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddData(serieIndex, multidimensionalData, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a (x,y) data to serie.
|
||||
/// 添加(x,y)数据到指定系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="xValue">x data</param>
|
||||
/// <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, double xValue, double yValue, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddXYData(serieName, xValue, yValue, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieName);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a (x,y) data to serie.
|
||||
/// 添加(x,y)数据到指定系列中。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie</param>
|
||||
/// <param name="xValue">x data</param>
|
||||
/// <param name="yValue">y data</param>
|
||||
/// <param name="dataName">the name of data</param>
|
||||
/// <returns>Returns True on success</returns>
|
||||
public virtual SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddXYData(serieIndex, xValue, yValue, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
public virtual SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null)
|
||||
{
|
||||
var serieData = m_Series.AddData(serieIndex, open, close, lowest, heighest, dataName);
|
||||
if (serieData != null)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (SerieHelper.GetSerieLabel(serie, serieData).show)
|
||||
{
|
||||
RefreshLabel();
|
||||
}
|
||||
RefreshPainter(serie);
|
||||
}
|
||||
return serieData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update serie data by serie name.
|
||||
/// 更新指定系列中的指定索引数据。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="dataIndex">the index of data</param>
|
||||
/// <param name="value">the data will be update</param>
|
||||
public virtual bool UpdateData(string serieName, int dataIndex, double value)
|
||||
{
|
||||
if (m_Series.UpdateData(serieName, dataIndex, value))
|
||||
{
|
||||
RefreshPainter(m_Series.GetSerie(serieName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update serie data by serie index.
|
||||
/// 更新指定系列中的指定索引数据。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie</param>
|
||||
/// <param name="dataIndex">the index of data</param>
|
||||
/// <param name="value">the data will be update</param>
|
||||
public virtual bool UpdateData(int serieIndex, int dataIndex, double value)
|
||||
{
|
||||
if (m_Series.UpdateData(serieIndex, dataIndex, value))
|
||||
{
|
||||
RefreshPainter(m_Series.GetSerie(serieIndex));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指定系列指定索引的数据项的多维数据。
|
||||
/// </summary>
|
||||
/// <param name="serieName"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
/// <param name="multidimensionalData">一个数据项的多维数据列表,而不是多个数据项的数据</param>
|
||||
public virtual bool UpdateData(string serieName, int dataIndex, List<double> multidimensionalData)
|
||||
{
|
||||
if (m_Series.UpdateData(serieName, dataIndex, multidimensionalData))
|
||||
{
|
||||
RefreshPainter(m_Series.GetSerie(serieName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指定系列指定索引的数据项的多维数据。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
/// <param name="multidimensionalData">一个数据项的多维数据列表,而不是多个数据项的数据</param>
|
||||
public virtual bool UpdateData(int serieIndex, int dataIndex, List<double> multidimensionalData)
|
||||
{
|
||||
if (m_Series.UpdateData(serieIndex, dataIndex, multidimensionalData))
|
||||
{
|
||||
RefreshPainter(m_Series.GetSerie(serieIndex));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指定系列指定索引指定维数的数据。维数从0开始。
|
||||
/// </summary>
|
||||
/// <param name="serieName"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
/// <param name="dimension">指定维数,从0开始</param>
|
||||
/// <param name="value"></param>
|
||||
public virtual bool UpdateData(string serieName, int dataIndex, int dimension, double value)
|
||||
{
|
||||
if (m_Series.UpdateData(serieName, dataIndex, dimension, value))
|
||||
{
|
||||
RefreshPainter(m_Series.GetSerie(serieName));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指定系列指定索引指定维数的数据。维数从0开始。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
/// <param name="dimension">指定维数,从0开始</param>
|
||||
/// <param name="value"></param>
|
||||
public virtual bool UpdateData(int serieIndex, int dataIndex, int dimension, double value)
|
||||
{
|
||||
if (m_Series.UpdateData(serieIndex, dataIndex, dimension, value))
|
||||
{
|
||||
RefreshPainter(m_Series.GetSerie(serieIndex));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update serie data name.
|
||||
/// 更新指定系列中的指定索引数据名称。
|
||||
/// </summary>
|
||||
/// <param name="serieName"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
/// <param name="dataName"></param>
|
||||
public virtual bool UpdateDataName(string serieName, int dataIndex, string dataName)
|
||||
{
|
||||
return m_Series.UpdateDataName(serieName, dataIndex, dataName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update serie data name.
|
||||
/// 更新指定系列中的指定索引数据名称。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex"></param>
|
||||
/// <param name="dataName"></param>
|
||||
/// <param name="dataIndex"></param>
|
||||
public virtual bool UpdateDataName(int serieIndex, int dataIndex, string dataName)
|
||||
{
|
||||
return m_Series.UpdateDataName(serieIndex, dataIndex, dataName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show serie.
|
||||
/// 设置指定系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <param name="active">Active or not</param>
|
||||
public virtual void SetActive(string serieName, bool active)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieName);
|
||||
if (serie != null)
|
||||
{
|
||||
SetActive(serie.index, active);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show serie.
|
||||
/// 设置指定系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie</param>
|
||||
/// <param name="active">Active or not</param>
|
||||
public virtual void SetActive(int serieIndex, bool active)
|
||||
{
|
||||
m_Series.SetActive(serieIndex, active);
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (serie != null && !string.IsNullOrEmpty(serie.name))
|
||||
{
|
||||
UpdateLegendColor(serie.name, active);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void UpdateLegendColor(string legendName, bool active)
|
||||
{
|
||||
var legendIndex = m_LegendRealShowName.IndexOf(legendName);
|
||||
if (legendIndex >= 0)
|
||||
{
|
||||
foreach (var legend in m_Legends)
|
||||
{
|
||||
var iconColor = LegendHelper.GetIconColor(this, legendIndex, legendName, active);
|
||||
var contentColor = LegendHelper.GetContentColor(legendIndex, legend, m_Theme, active);
|
||||
legend.UpdateButtonColor(legendName, iconColor);
|
||||
legend.UpdateContentColor(legendName, contentColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether serie is activated.
|
||||
/// 获取指定系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
/// <returns>True when activated</returns>
|
||||
public virtual bool IsActive(string serieName)
|
||||
{
|
||||
return m_Series.IsActive(serieName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether serie is activated.
|
||||
/// 获取指定系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="serieIndex">the index of serie</param>
|
||||
/// <returns>True when activated</returns>
|
||||
public virtual bool IsActive(int serieIndex)
|
||||
{
|
||||
return m_Series.IsActive(serieIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether serie is activated.
|
||||
/// 获得指定图例名字的系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="legendName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsActiveByLegend(string legendName)
|
||||
{
|
||||
foreach (var serie in m_Series.list)
|
||||
{
|
||||
if (serie.show && legendName.Equals(serie.name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.show && legendName.Equals(serieData.name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新文本标签Label,重新初始化,当有改动Label参数时手动调用改接口
|
||||
/// </summary>
|
||||
public void RefreshLabel()
|
||||
{
|
||||
m_ReinitLabel = true;
|
||||
m_SerieLabelRoot = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新Tooltip组件。
|
||||
/// </summary>
|
||||
public void RefreshTooltip()
|
||||
{
|
||||
InitTooltip();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update chart theme.
|
||||
/// 切换内置主题。
|
||||
/// </summary>
|
||||
/// <param name="theme">theme</param>
|
||||
public bool UpdateTheme(Theme theme)
|
||||
{
|
||||
if (theme == Theme.Custom)
|
||||
{
|
||||
Debug.LogError("UpdateTheme: not support switch to Custom theme.");
|
||||
return false;
|
||||
}
|
||||
m_Theme.theme = theme;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update chart theme info.
|
||||
/// 切换图表主题。
|
||||
/// </summary>
|
||||
/// <param name="theme">theme</param>
|
||||
public void UpdateTheme(ChartTheme theme)
|
||||
{
|
||||
m_Theme.CopyTheme(theme);
|
||||
SetAllComponentDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether series animation enabel.
|
||||
/// 启用或关闭起始动画。
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
public void AnimationEnable(bool flag)
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.AnimationEnable(flag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fadeIn animation.
|
||||
/// 开始渐入动画。
|
||||
/// </summary>
|
||||
public void AnimationFadeIn()
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.AnimationFadeIn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fadeIn animation.
|
||||
/// 开始渐出动画。
|
||||
/// </summary>
|
||||
public void AnimationFadeOut()
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.AnimationFadeOut();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause animation.
|
||||
/// 暂停动画。
|
||||
/// </summary>
|
||||
public void AnimationPause()
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.AnimationPause();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop play animation.
|
||||
/// 继续动画。
|
||||
/// </summary>
|
||||
public void AnimationResume()
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.AnimationResume();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset animation.
|
||||
/// 重置动画。
|
||||
/// </summary>
|
||||
public void AnimationReset()
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.AnimationReset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击图例按钮
|
||||
/// </summary>
|
||||
/// <param name="legendIndex">图例按钮索引</param>
|
||||
/// <param name="legendName">图例按钮名称</param>
|
||||
/// <param name="show">显示还是隐藏</param>
|
||||
public void ClickLegendButton(int legendIndex, string legendName, bool show)
|
||||
{
|
||||
OnLegendButtonClick(legendIndex, legendName, show);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 坐标是否在图表范围内
|
||||
/// </summary>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsInChart(Vector2 local)
|
||||
{
|
||||
return IsInChart(local.x, local.y);
|
||||
}
|
||||
|
||||
public bool IsInChart(float x, float y)
|
||||
{
|
||||
if (x < m_ChartX || x > m_ChartX + m_ChartWidth ||
|
||||
y < m_ChartY || y > m_ChartY + m_ChartHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ClampInChart(ref Vector3 pos)
|
||||
{
|
||||
if (!IsInChart(pos.x, pos.y))
|
||||
{
|
||||
if (pos.x < m_ChartX) pos.x = m_ChartX;
|
||||
if (pos.x > m_ChartX + m_ChartWidth) pos.x = m_ChartX + m_ChartWidth;
|
||||
if (pos.y < m_ChartY) pos.y = m_ChartY;
|
||||
if (pos.y > m_ChartY + m_ChartHeight) pos.y = m_ChartY + m_ChartHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetTitlePosition(Title title)
|
||||
{
|
||||
return chartPosition + title.location.GetPosition(chartWidth, chartHeight);
|
||||
}
|
||||
|
||||
public bool ContainsSerie(SerieType serieType)
|
||||
{
|
||||
return SeriesHelper.ContainsSerie(m_Series, serieType);
|
||||
}
|
||||
|
||||
public virtual bool AddDefaultCustomSerie(string serieName, int dataCount = 5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual string[] GetCustomSerieInspectorShowFileds()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public virtual string[][] GetCustomSerieInspectorCustomFileds()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
public virtual string[] GetCustomChartInspectorShowFileds()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual string GetCustomSerieTypeName()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual bool GetCustomSerieDataNameForColor()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetLegendRealShowNameIndex(string name)
|
||||
{
|
||||
return m_LegendRealShowName.IndexOf(name);
|
||||
}
|
||||
|
||||
public virtual void InitCustomSerieTooltip(ref StringBuilder stringBuilder, Serie serie, int index)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Base Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetBasePainterMaterial(Material material)
|
||||
{
|
||||
settings.basePainterMaterial = material;
|
||||
if (m_Painter != null)
|
||||
{
|
||||
m_Painter.material = material;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Serie Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetSeriePainterMaterial(Material material)
|
||||
{
|
||||
settings.basePainterMaterial = material;
|
||||
if (m_PainterList != null)
|
||||
{
|
||||
foreach (var painter in m_PainterList)
|
||||
painter.material = material;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Top Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetTopPainterMaterial(Material material)
|
||||
{
|
||||
settings.topPainterMaterial = material;
|
||||
if (m_PainterTop != null)
|
||||
{
|
||||
m_PainterTop.material = material;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,399 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The basic class of rectangular coordinate chart,such as LineChart,BarChart and ScatterChart.
|
||||
/// 直角坐标系类型图表的基类,如折线图LineChart,柱状图BarChart,散点图ScatterChart都属于这类型的图表。
|
||||
/// 不可用直接将CoordinateChart绑定到GameObject上。
|
||||
/// </summary>
|
||||
public partial class CoordinateChart
|
||||
{
|
||||
/// <summary>
|
||||
/// grid component.
|
||||
/// 网格组件。
|
||||
/// </summary>
|
||||
public Grid grid { get { return m_Grids.Count > 0 ? m_Grids[0] : null; } }
|
||||
public List<Grid> grids { get { return m_Grids; } }
|
||||
/// <summary>
|
||||
/// the x Axes,xAxes[0] is the first x axis, xAxes[1] is the second x axis.
|
||||
/// 两个x轴。
|
||||
/// </summary>
|
||||
public List<XAxis> xAxes { get { return m_XAxes; } }
|
||||
/// <summary>
|
||||
/// the y Axes, yAxes[0] is the first y axis, yAxes[1] is the second y axis.
|
||||
/// 两个y轴。
|
||||
/// </summary>
|
||||
public List<YAxis> yAxes { get { return m_YAxes; } }
|
||||
|
||||
/// <summary>
|
||||
/// X轴(下)
|
||||
/// </summary>
|
||||
public XAxis xAxis0 { get { return m_XAxes.Count > 0 ? m_XAxes[0] : null; } }
|
||||
/// <summary>
|
||||
/// X轴(上)
|
||||
/// </summary>
|
||||
public XAxis xAxis1 { get { return m_XAxes.Count > 1 ? m_XAxes[1] : null; } }
|
||||
/// <summary>
|
||||
/// Y轴(左)
|
||||
/// </summary>
|
||||
public YAxis yAxis0 { get { return m_YAxes.Count > 0 ? m_YAxes[0] : null; } }
|
||||
/// <summary>
|
||||
/// Y轴(右)
|
||||
/// </summary>
|
||||
public YAxis yAxis1 { get { return m_YAxes.Count > 1 ? m_YAxes[1] : null; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Remove all data from series,legend and axis.
|
||||
/// It just emptying all of serie's data without emptying the list of series.
|
||||
/// 清空所有图例,系列和坐标轴类目数据。系列中指示清空系列中的数据,会保留系列列表。
|
||||
/// </summary>
|
||||
public override void ClearData()
|
||||
{
|
||||
base.ClearData();
|
||||
ClearAxisData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all data from series,legend and axis.
|
||||
/// The series list is also cleared.
|
||||
/// 清空所有图例,系列和坐标轴类目数据。系列的列表也会被清空。
|
||||
/// </summary>
|
||||
public override void RemoveData()
|
||||
{
|
||||
base.RemoveData();
|
||||
ClearAxisData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all data of Axes.
|
||||
/// 清除所有x轴和y轴的类目数据。
|
||||
/// </summary>
|
||||
public void ClearAxisData()
|
||||
{
|
||||
foreach (var axis in m_XAxes)
|
||||
{
|
||||
axis.data.Clear();
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
foreach (var axis in m_YAxes)
|
||||
{
|
||||
axis.data.Clear();
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a category data to xAxis.
|
||||
/// 添加一个类目数据到指定的x轴。
|
||||
/// </summary>
|
||||
/// <param name="category">the category data</param>
|
||||
/// <param name="xAxisIndex">which xAxis should category add to</param>
|
||||
public void AddXAxisData(string category, int xAxisIndex = 0)
|
||||
{
|
||||
var xAxis = GetXAxis(xAxisIndex);
|
||||
if (xAxis != null)
|
||||
{
|
||||
xAxis.AddData(category);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update category data.
|
||||
/// 更新X轴类目数据。
|
||||
/// </summary>
|
||||
/// <param name="index">the index of category data</param>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="xAxisIndex">which xAxis index to update to</param>
|
||||
public void UpdateXAxisData(int index, string category, int xAxisIndex = 0)
|
||||
{
|
||||
var xAxis = GetXAxis(xAxisIndex);
|
||||
if (xAxis != null)
|
||||
{
|
||||
xAxis.UpdateData(index, category);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an icon to xAxis.
|
||||
/// 添加一个图标到指定的x轴。
|
||||
/// </summary>
|
||||
/// <param name="icon"></param>
|
||||
/// <param name="xAxisIndex"></param>
|
||||
public void AddXAxisIcon(Sprite icon, int xAxisIndex = 0)
|
||||
{
|
||||
var xAxis = GetXAxis(xAxisIndex);
|
||||
if (xAxis != null)
|
||||
{
|
||||
xAxis.AddIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update xAxis icon.
|
||||
/// 更新X轴图标。
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="icon"></param>
|
||||
/// <param name="xAxisIndex"></param>
|
||||
public void UdpateXAxisIcon(int index, Sprite icon, int xAxisIndex = 0)
|
||||
{
|
||||
var xAxis = GetXAxis(xAxisIndex);
|
||||
if (xAxis != null)
|
||||
{
|
||||
xAxis.UpdateIcon(index, icon);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a category data to yAxis.
|
||||
/// 添加一个类目数据到指定的y轴。
|
||||
/// </summary>
|
||||
/// <param name="category">the category data</param>
|
||||
/// <param name="yAxisIndex">which yAxis should category add to</param>
|
||||
public void AddYAxisData(string category, int yAxisIndex = 0)
|
||||
{
|
||||
var yAxis = GetYAxis(yAxisIndex);
|
||||
if (yAxis != null)
|
||||
{
|
||||
yAxis.AddData(category);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update category data.
|
||||
/// 更新Y轴类目数据。
|
||||
/// </summary>
|
||||
/// <param name="index">the index of category data</param>
|
||||
/// <param name="category"></param>
|
||||
/// <param name="yAxisIndex">which yAxis index to update to</param>
|
||||
public void UpdateYAxisData(int index, string category, int yAxisIndex = 0)
|
||||
{
|
||||
var yAxis = GetYAxis(yAxisIndex);
|
||||
if (yAxis != null)
|
||||
{
|
||||
yAxis.UpdateData(index, category);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add an icon to yAxis.
|
||||
/// 添加一个图标到指定的y轴。
|
||||
/// </summary>
|
||||
/// <param name="icon"></param>
|
||||
/// <param name="yAxisIndex"></param>
|
||||
public void AddYAxisIcon(Sprite icon, int yAxisIndex = 0)
|
||||
{
|
||||
var yAxis = GetYAxis(yAxisIndex);
|
||||
if (yAxis != null)
|
||||
{
|
||||
yAxis.AddIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新Y轴图标。
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="icon"></param>
|
||||
/// <param name="yAxisIndex"></param>
|
||||
public void UpdateYAxisIcon(int index, Sprite icon, int yAxisIndex = 0)
|
||||
{
|
||||
var yAxis = GetYAxis(yAxisIndex);
|
||||
if (yAxis != null)
|
||||
{
|
||||
yAxis.UpdateIcon(index, icon);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// reutrn true when all the show axis is `Value` type.
|
||||
/// 纯数值坐标轴(数值轴或对数轴)。
|
||||
/// </summary>
|
||||
public bool IsValue()
|
||||
{
|
||||
foreach (var axis in m_XAxes)
|
||||
{
|
||||
if (axis.show && !axis.IsValue() && !axis.IsLog()) return false;
|
||||
}
|
||||
foreach (var axis in m_YAxes)
|
||||
{
|
||||
if (axis.show && !axis.IsValue() && !axis.IsLog()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 纯类目轴。
|
||||
/// </summary>
|
||||
public bool IsCategory()
|
||||
{
|
||||
foreach (var axis in m_XAxes)
|
||||
{
|
||||
if (axis.show && !axis.IsCategory()) return false;
|
||||
}
|
||||
foreach (var axis in m_YAxes)
|
||||
{
|
||||
if (axis.show && !axis.IsCategory()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 坐标是否在坐标轴内。
|
||||
/// </summary>
|
||||
public bool IsInGrid(Grid grid, Vector2 local)
|
||||
{
|
||||
return IsInGrid(grid, local.x, local.y);
|
||||
}
|
||||
|
||||
public bool IsInGrid(Grid grid, Vector3 local)
|
||||
{
|
||||
return IsInGrid(grid, local.x, local.y);
|
||||
}
|
||||
|
||||
public bool IsInGrid(Grid grid, float x, float y)
|
||||
{
|
||||
if (x < grid.runtimeX - 1 || x > grid.runtimeX + grid.runtimeWidth + 1 ||
|
||||
y < grid.runtimeY - 1 || y > grid.runtimeY + grid.runtimeHeight + 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInAnyGrid(Vector2 local)
|
||||
{
|
||||
foreach (var grid in m_Grids)
|
||||
{
|
||||
if (IsInGrid(grid, local)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public Grid GetGrid(Vector2 local)
|
||||
{
|
||||
for (int i = 0; i < m_Grids.Count; i++)
|
||||
{
|
||||
var grid = m_Grids[i];
|
||||
grid.index = i;
|
||||
if (IsInGrid(grid, local)) return grid;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在下一帧刷新DataZoom
|
||||
/// </summary>
|
||||
public void RefreshDataZoom()
|
||||
{
|
||||
foreach (var handler in m_ComponentHandlers)
|
||||
{
|
||||
if (handler is DataZoomHandler)
|
||||
{
|
||||
(handler as DataZoomHandler).RefreshDataZoomLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 立即刷新数值坐标轴的最大最小值
|
||||
/// </summary>
|
||||
public void RefreshAxisMinMaxValue()
|
||||
{
|
||||
CheckMinMaxValue();
|
||||
}
|
||||
|
||||
public Vector3 ClampInGrid(Grid grid, Vector3 pos)
|
||||
{
|
||||
if (IsInGrid(grid, pos)) return pos;
|
||||
else
|
||||
{
|
||||
// var pos = new Vector3(pos.x, pos.y);
|
||||
if (pos.x < grid.runtimeX) pos.x = grid.runtimeX;
|
||||
if (pos.x > grid.runtimeX + grid.runtimeWidth) pos.x = grid.runtimeX + grid.runtimeWidth;
|
||||
if (pos.y < grid.runtimeY) pos.y = grid.runtimeY;
|
||||
if (pos.y > grid.runtimeY + grid.runtimeHeight) pos.y = grid.runtimeY + grid.runtimeHeight;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换X轴和Y轴的配置
|
||||
/// </summary>
|
||||
/// <param name="index">坐标轴索引,0或1</param>
|
||||
public void CovertXYAxis(int index)
|
||||
{
|
||||
if (index >= 0 && index <= 1)
|
||||
{
|
||||
var xAxis = m_XAxes[index];
|
||||
var yAxis = m_YAxes[index];
|
||||
var tempX = m_XAxes[index].Clone();
|
||||
xAxis.Copy(m_YAxes[index]);
|
||||
yAxis.Copy(tempX);
|
||||
xAxis.runtimeZeroXOffset = 0;
|
||||
xAxis.runtimeZeroYOffset = 0;
|
||||
yAxis.runtimeZeroXOffset = 0;
|
||||
yAxis.runtimeZeroYOffset = 0;
|
||||
xAxis.runtimeMinValue = 0;
|
||||
xAxis.runtimeMaxValue = 0;
|
||||
yAxis.runtimeMinValue = 0;
|
||||
yAxis.runtimeMaxValue = 0;
|
||||
RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新坐标系原点和宽高
|
||||
/// </summary>
|
||||
public void UpdateCoordinate()
|
||||
{
|
||||
foreach (var grid in m_Grids)
|
||||
{
|
||||
grid.UpdateRuntimeData(m_ChartX, m_ChartY, m_ChartWidth, m_ChartHeight);
|
||||
}
|
||||
foreach (var dataZoom in m_DataZooms)
|
||||
{
|
||||
dataZoom.UpdateRuntimeData(m_ChartX, m_ChartY, m_ChartWidth, m_ChartHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。
|
||||
/// </summary>
|
||||
public void SetMaxCache(int maxCache)
|
||||
{
|
||||
foreach (var serie in m_Series.list) serie.maxCache = maxCache;
|
||||
foreach (var axis in m_XAxes) axis.maxCache = maxCache;
|
||||
foreach (var axis in m_YAxes) axis.maxCache = maxCache;
|
||||
}
|
||||
|
||||
public Grid GetGrid(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_Grids.Count) return m_Grids[index];
|
||||
else return null;
|
||||
}
|
||||
|
||||
public XAxis GetXAxis(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_XAxes.Count) return m_XAxes[index];
|
||||
else return null;
|
||||
}
|
||||
|
||||
public YAxis GetYAxis(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_YAxes.Count) return m_YAxes[index];
|
||||
else return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public partial class BaseChart
|
||||
{
|
||||
public Vessel vessel { get { return m_Vessels.Count > 0 ? m_Vessels[0] : null; } }
|
||||
/// <summary>
|
||||
/// 容器组件列表。
|
||||
/// </summary>
|
||||
public List<Vessel> vessels { get { return m_Vessels; } }
|
||||
|
||||
/// <summary>
|
||||
/// 移除所有容器组件。
|
||||
/// </summary>
|
||||
public void RemoveVessel()
|
||||
{
|
||||
m_Vessels.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加容器组件。
|
||||
/// </summary>
|
||||
public void AddVessel(Vessel vessel)
|
||||
{
|
||||
m_Vessels.Add(vessel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加容器组件。
|
||||
/// </summary>
|
||||
public Vessel AddVessel(Vessel.Shape shape, Vector2 center, float radius)
|
||||
{
|
||||
var vessel = new Vessel();
|
||||
vessel.shape = shape;
|
||||
vessel.radius = radius;
|
||||
vessel.center[0] = center.x;
|
||||
vessel.center[1] = center.y;
|
||||
AddVessel(vessel);
|
||||
return vessel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定索引的容器组件。
|
||||
/// </summary>
|
||||
/// <param name="radarIndex"></param>
|
||||
/// <returns></returns>
|
||||
public Vessel GetVessel(int vesselIndex)
|
||||
{
|
||||
if (vesselIndex < 0 || vesselIndex > m_Vessels.Count - 1) return null;
|
||||
return m_Vessels[vesselIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public partial class BaseChart
|
||||
{
|
||||
/// <summary>
|
||||
/// 极坐标。
|
||||
/// </summary>
|
||||
public Polar polar { get { return m_Polars.Count > 0 ? m_Polars[0] : null; } }
|
||||
/// <summary>
|
||||
/// Angle axis of Polar Coordinate.
|
||||
/// 极坐标系的角度轴。
|
||||
/// </summary>
|
||||
public AngleAxis angleAxis { get { return m_AngleAxes.Count > 0 ? m_AngleAxes[0] : null; } }
|
||||
/// <summary>
|
||||
/// Radial axis of polar coordinate.
|
||||
/// 极坐标系的径向轴。
|
||||
/// </summary>
|
||||
public RadiusAxis radiusAxis { get { return m_RadiusAxes.Count > 0 ? m_RadiusAxes[0] : null; } }
|
||||
}
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public partial class BaseChart
|
||||
{
|
||||
public Radar radar { get { return m_Radars.Count > 0 ? m_Radars[0] : null; } }
|
||||
/// <summary>
|
||||
/// 雷达坐标系组件列表。
|
||||
/// </summary>
|
||||
public List<Radar> radars { get { return m_Radars; } }
|
||||
|
||||
/// <summary>
|
||||
/// 移除所有雷达坐标系组件。
|
||||
/// </summary>
|
||||
public void RemoveRadar()
|
||||
{
|
||||
m_Radars.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除指定Radar的所有Indicator。
|
||||
/// </summary>
|
||||
/// <param name="radarIndex"></param>
|
||||
public void RemoveIndicator(int radarIndex)
|
||||
{
|
||||
var radar = GetRadar(radarIndex);
|
||||
if (radar == null) return;
|
||||
radar.indicatorList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加雷达坐标系组件。
|
||||
/// </summary>
|
||||
public void AddRadar(Radar radar)
|
||||
{
|
||||
m_Radars.Add(radar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加雷达坐标系组件。
|
||||
/// </summary>
|
||||
/// <param name="shape">形状,圆形还是多边形</param>
|
||||
/// <param name="center">中心点,0-1浮点数时表示百分比</param>
|
||||
/// <param name="radius">半径,0-1浮点数时表示百分比</param>
|
||||
/// <param name="splitNumber">指示器轴的分割段数</param>
|
||||
/// <param name="lineWidth">线条宽</param>
|
||||
/// <param name="showIndicator">是否显示指示器名称</param>
|
||||
/// <param name="showSplitArea">是否显示分割区域</param>
|
||||
/// <returns></returns>
|
||||
public Radar AddRadar(Radar.Shape shape, Vector2 center, float radius, int splitNumber = 5,
|
||||
float lineWidth = 0f, bool showIndicator = true, bool showSplitArea = true)
|
||||
{
|
||||
var radar = new Radar();
|
||||
radar.shape = shape;
|
||||
radar.splitNumber = splitNumber;
|
||||
radar.radius = radius;
|
||||
radar.indicator = showIndicator;
|
||||
radar.center[0] = center.x;
|
||||
radar.center[1] = center.y;
|
||||
radar.splitArea.show = showSplitArea;
|
||||
radar.splitLine.lineStyle.width = lineWidth;
|
||||
m_Radars.Add(radar);
|
||||
return radar;
|
||||
}
|
||||
|
||||
public bool AddIndicator(int radarIndex, Radar.Indicator indicator)
|
||||
{
|
||||
var radar = GetRadar(radarIndex);
|
||||
if (radar == null) return false;
|
||||
radar.AddIndicator(indicator);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加指示器。
|
||||
/// </summary>
|
||||
/// <param name="radarIndex">雷达坐标系组件索引,从0开始</param>
|
||||
/// <param name="name">指示器名称</param>
|
||||
/// <param name="min">指示器最小值</param>
|
||||
/// <param name="max">指示器最大值</param>
|
||||
/// <returns></returns>
|
||||
public Radar.Indicator AddIndicator(int radarIndex, string name, float min, float max)
|
||||
{
|
||||
var radar = GetRadar(radarIndex);
|
||||
if (radar == null) return null;
|
||||
return radar.AddIndicator(name, min, max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指示器。
|
||||
/// </summary>
|
||||
/// <param name="radarIndex">雷达坐标系组件的索引,从0开始</param>
|
||||
/// <param name="indicatorIndex">指示器索引,从0开始</param>
|
||||
/// <param name="name">指示器名称</param>
|
||||
/// <param name="min">指示器最小值</param>
|
||||
/// <param name="max">指示器最大值</param>
|
||||
/// <returns></returns>
|
||||
public bool UpdateIndicator(int radarIndex, int indicatorIndex, string name, float min, float max)
|
||||
{
|
||||
var radar = GetRadar(radarIndex);
|
||||
if (radar == null) return false;
|
||||
return radar.UpdateIndicator(indicatorIndex, name, min, max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定索引的雷达坐标系组件。
|
||||
/// </summary>
|
||||
/// <param name="radarIndex"></param>
|
||||
/// <returns></returns>
|
||||
public Radar GetRadar(int radarIndex)
|
||||
{
|
||||
if (radarIndex < 0 || radarIndex > m_Radars.Count - 1) return null;
|
||||
return m_Radars[radarIndex];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定雷达坐标系组件指定索引的指示器。
|
||||
/// </summary>
|
||||
/// <param name="radarIndex"></param>
|
||||
/// <param name="indicatorIndex"></param>
|
||||
/// <returns></returns>
|
||||
public Radar.Indicator GetIndicator(int radarIndex, int indicatorIndex)
|
||||
{
|
||||
var radar = GetRadar(radarIndex);
|
||||
if (radar != null) return radar.GetIndicator(indicatorIndex);
|
||||
else return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f17a7aa35fdd3417dab9414f10fe2886
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,88 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
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, double value)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (serie != null)
|
||||
{
|
||||
return serie.UpdateData(dataIndex, 1, value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新指定系列的所有数据项的最大值
|
||||
/// </summary>
|
||||
/// <param name="serieIndex"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool UpdateMax(int serieIndex, double value)
|
||||
{
|
||||
var serie = m_Series.GetSerie(serieIndex);
|
||||
if (serie != null)
|
||||
{
|
||||
var flag = true;
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
if (serie.UpdateData(i, 1, value)) flag = false;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新第一个系列第一个数据项的最大值
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool UpdateMax(double 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, double value, double 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, double value, double max, string dataName = null)
|
||||
{
|
||||
return base.AddData(serieIndex, value, max, dataName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a1cd7e0dade8470cb91d6a7971ff022
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94d1c19509a514ffab61efb88d3281fd
|
||||
guid: 900b05585ba864df1aa05dcdb36b324b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -5,9 +5,7 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
@@ -15,39 +13,27 @@ namespace XCharts
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public partial class BarChart : CoordinateChart
|
||||
public partial class BarChart : BaseChart
|
||||
{
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
raycastTarget = false;
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "BarChart";
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SerieTemplate.AddDefaultBarSerie(this, "serie1");
|
||||
Bar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
base.OnPointerDown(eventData);
|
||||
if (m_OnPointerClickBar == null) return;
|
||||
if (pointerPos == Vector2.zero) return;
|
||||
UpdateTooltipValue(pointerPos);
|
||||
var dataIndex = tooltip.runtimeDataIndex[0];
|
||||
if (dataIndex >= 0)
|
||||
{
|
||||
m_OnPointerClickBar(eventData, dataIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
495
Assets/XCharts/Runtime/Chart/BaseChart_API.cs
Normal file
495
Assets/XCharts/Runtime/Chart/BaseChart_API.cs
Normal file
@@ -0,0 +1,495 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class of all charts.
|
||||
/// 所有Chart的基类。
|
||||
/// </summary>
|
||||
public partial class BaseChart
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of chart.
|
||||
/// </summary>
|
||||
public string chartName
|
||||
{
|
||||
get { return m_ChartName; }
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value) && XChartsMgr.ContainsChart(value))
|
||||
{
|
||||
Debug.LogError("chartName repeated:" + value);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ChartName = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// The theme.
|
||||
/// </summary>
|
||||
public ThemeStyle theme { get { return m_Theme; } set { m_Theme = value; } }
|
||||
/// <summary>
|
||||
/// The title setting of chart.
|
||||
/// 标题组件
|
||||
/// </summary>
|
||||
//public Title title { get { return GetChartComponent<Title>(); } }
|
||||
/// <summary>
|
||||
/// The legend setting of chart.
|
||||
/// 图例组件
|
||||
/// </summary>
|
||||
//public Legend legend { get { return m_Legends.Count > 0 ? m_Legends[0] : null; } }
|
||||
//public List<Legend> legends { get { return m_Legends; } }
|
||||
/// <summary>
|
||||
/// The tooltip setting of chart.
|
||||
/// 提示框组件
|
||||
/// </summary>
|
||||
//public Tooltip tooltip { get { return m_Tooltips.Count > 0 ? m_Tooltips[0] : null; } }
|
||||
/// <summary>
|
||||
/// The series setting of chart.
|
||||
/// 系列列表
|
||||
/// </summary>
|
||||
//public List<Serie> series { get { return m_Series; } }
|
||||
/// <summary>
|
||||
/// Global parameter setting component.
|
||||
/// 全局设置组件。
|
||||
/// </summary>
|
||||
public Settings settings { get { return m_Settings; } }
|
||||
/// <summary>
|
||||
/// dataZoom component.
|
||||
/// 区域缩放组件。
|
||||
/// </summary>
|
||||
//public DataZoom dataZoom { get { return m_DataZooms.Count > 0 ? m_DataZooms[0] : null; } }
|
||||
//public List<DataZoom> dataZooms { get { return m_DataZooms; } }
|
||||
/// <summary>
|
||||
/// visualMap component.
|
||||
/// 视觉映射组件。
|
||||
/// </summary>
|
||||
//public VisualMap visualMap { get { return m_VisualMaps.Count > 0 ? m_VisualMaps[0] : null; } }
|
||||
//public List<VisualMap> visualMaps { get { return m_VisualMaps; } }
|
||||
/// <summary>
|
||||
/// The x of chart.
|
||||
/// 图表的X
|
||||
/// </summary>
|
||||
public float chartX { get { return m_ChartX; } }
|
||||
/// <summary>
|
||||
/// The y of chart.
|
||||
/// 图表的Y
|
||||
/// </summary>
|
||||
public float chartY { get { return m_ChartY; } }
|
||||
/// <summary>
|
||||
/// The width of chart.
|
||||
/// 图表的宽
|
||||
/// </summary>
|
||||
public float chartWidth { get { return m_ChartWidth; } }
|
||||
/// <summary>
|
||||
/// The height of chart.
|
||||
/// 图表的高
|
||||
/// </summary>
|
||||
public float chartHeight { get { return m_ChartHeight; } }
|
||||
public Vector2 chartMinAnchor { get { return m_ChartMinAnchor; } }
|
||||
public Vector2 chartMaxAnchor { get { return m_ChartMaxAnchor; } }
|
||||
public Vector2 chartPivot { get { return m_ChartPivot; } }
|
||||
public Vector2 chartSizeDelta { get { return m_ChartSizeDelta; } }
|
||||
/// <summary>
|
||||
/// The position of chart.
|
||||
/// 图表的左下角起始坐标。
|
||||
/// </summary>
|
||||
public Vector3 chartPosition { get { return m_ChartPosition; } }
|
||||
public Rect chartRect { get { return m_ChartRect; } }
|
||||
/// <summary>
|
||||
/// 自定义绘制回调。在绘制Serie前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper> onCustomDraw { set { m_OnCustomDrawBaseCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Serie绘制回调。在每个Serie绘制完前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper, Serie> onCustomDrawBeforeSerie { set { m_OnCustomDrawSerieBeforeCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Serie绘制回调。在每个Serie绘制完后调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper, Serie> onCustomDrawAfterSerie { set { m_OnCustomDrawSerieAfterCallback = value; } }
|
||||
/// <summary>
|
||||
/// 自定义Top绘制回调。在绘制Tooltip前调用。
|
||||
/// </summary>
|
||||
public Action<VertexHelper> onCustomDrawTop { set { m_OnCustomDrawTopCallback = value; } }
|
||||
/// <summary>
|
||||
/// the callback function of click pie area.
|
||||
/// 点击饼图区域回调。参数:PointerEventData,SerieIndex,SerieDataIndex
|
||||
/// </summary>
|
||||
public Action<PointerEventData, int, int> onPointerClickPie { set { m_OnPointerClickPie = value; m_ForceOpenRaycastTarget = true; } get { return m_OnPointerClickPie; } }
|
||||
/// <summary>
|
||||
/// the callback function of click bar.
|
||||
/// 点击柱形图柱条回调。参数:eventData, dataIndex
|
||||
/// </summary>
|
||||
public Action<PointerEventData, int> onPointerClickBar { set { m_OnPointerClickBar = value; m_ForceOpenRaycastTarget = true; } }
|
||||
/// <summary>
|
||||
/// Redraw chart in next frame.
|
||||
/// 在下一帧刷新图表。
|
||||
/// </summary>
|
||||
public void RefreshChart()
|
||||
{
|
||||
m_RefreshChart = true;
|
||||
if (m_Painter) m_Painter.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all series and legend data.
|
||||
/// It just emptying all of serie's data without emptying the list of series.
|
||||
/// 清除所有数据,系列中只是移除数据,列表会保留。
|
||||
/// </summary>
|
||||
public virtual void ClearData()
|
||||
{
|
||||
foreach(var serie in m_Series)
|
||||
serie.ClearData();
|
||||
foreach (var component in m_Components)
|
||||
component.ClearData();
|
||||
m_CheckAnimation = false;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all data from series and legend.
|
||||
/// The series list is also cleared.
|
||||
/// 清除所有系列和图例数据,系列的列表也会被清除。
|
||||
/// </summary>
|
||||
public virtual void RemoveData()
|
||||
{
|
||||
foreach (var component in m_Components)
|
||||
component.ClearData();
|
||||
m_Series.Clear();
|
||||
m_CheckAnimation = false;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove legend and serie by name.
|
||||
/// 清除指定系列名称的数据。
|
||||
/// </summary>
|
||||
/// <param name="serieName">the name of serie</param>
|
||||
public virtual void RemoveData(string serieName)
|
||||
{
|
||||
RemoveSerie(serieName);
|
||||
foreach (var component in m_Components)
|
||||
{
|
||||
if (component is Legend)
|
||||
{
|
||||
var legend = component as Legend;
|
||||
legend.RemoveData(serieName);
|
||||
}
|
||||
}
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
public virtual void UpdateLegendColor(string legendName, bool active)
|
||||
{
|
||||
var legendIndex = m_LegendRealShowName.IndexOf(legendName);
|
||||
if (legendIndex >= 0)
|
||||
{
|
||||
foreach (var component in m_Components)
|
||||
{
|
||||
if (component is Legend)
|
||||
{
|
||||
var legend = component as Legend;
|
||||
var iconColor = LegendHelper.GetIconColor(this, legend, legendIndex, legendName, active);
|
||||
var contentColor = LegendHelper.GetContentColor(legendIndex, legend, m_Theme, active);
|
||||
legend.UpdateButtonColor(legendName, iconColor);
|
||||
legend.UpdateContentColor(legendName, contentColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether serie is activated.
|
||||
/// 获得指定图例名字的系列是否显示。
|
||||
/// </summary>
|
||||
/// <param name="legendName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsActiveByLegend(string legendName)
|
||||
{
|
||||
foreach (var serie in m_Series)
|
||||
{
|
||||
if (serie.show && legendName.Equals(serie.serieName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
if (serieData.show && legendName.Equals(serieData.name))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update chart theme.
|
||||
/// 切换内置主题。
|
||||
/// </summary>
|
||||
/// <param name="theme">theme</param>
|
||||
public bool UpdateTheme(ThemeType theme)
|
||||
{
|
||||
if (theme == ThemeType.Custom)
|
||||
{
|
||||
Debug.LogError("UpdateTheme: not support switch to Custom theme.");
|
||||
return false;
|
||||
}
|
||||
m_Theme.sharedTheme.CopyTheme(theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update chart theme info.
|
||||
/// 切换图表主题。
|
||||
/// </summary>
|
||||
/// <param name="theme">theme</param>
|
||||
public void UpdateTheme(Theme theme)
|
||||
{
|
||||
m_Theme.sharedTheme = theme;
|
||||
SetAllComponentDirty();
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorUtility.SetDirty(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether series animation enabel.
|
||||
/// 启用或关闭起始动画。
|
||||
/// </summary>
|
||||
/// <param name="flag"></param>
|
||||
public void AnimationEnable(bool flag)
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationEnable(flag);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fadeIn animation.
|
||||
/// 开始渐入动画。
|
||||
/// </summary>
|
||||
public void AnimationFadeIn()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationFadeIn();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// fadeIn animation.
|
||||
/// 开始渐出动画。
|
||||
/// </summary>
|
||||
public void AnimationFadeOut()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationFadeOut();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pause animation.
|
||||
/// 暂停动画。
|
||||
/// </summary>
|
||||
public void AnimationPause()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationPause();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stop play animation.
|
||||
/// 继续动画。
|
||||
/// </summary>
|
||||
public void AnimationResume()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationResume();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset animation.
|
||||
/// 重置动画。
|
||||
/// </summary>
|
||||
public void AnimationReset()
|
||||
{
|
||||
foreach (var serie in m_Series) serie.AnimationReset();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击图例按钮
|
||||
/// </summary>
|
||||
/// <param name="legendIndex">图例按钮索引</param>
|
||||
/// <param name="legendName">图例按钮名称</param>
|
||||
/// <param name="show">显示还是隐藏</param>
|
||||
public void ClickLegendButton(int legendIndex, string legendName, bool show)
|
||||
{
|
||||
OnLegendButtonClick(legendIndex, legendName, show);
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 坐标是否在图表范围内
|
||||
/// </summary>
|
||||
/// <param name="local"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsInChart(Vector2 local)
|
||||
{
|
||||
return IsInChart(local.x, local.y);
|
||||
}
|
||||
|
||||
public bool IsInChart(float x, float y)
|
||||
{
|
||||
if (x < m_ChartX || x > m_ChartX + m_ChartWidth ||
|
||||
y < m_ChartY || y > m_ChartY + m_ChartHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void ClampInChart(ref Vector3 pos)
|
||||
{
|
||||
if (!IsInChart(pos.x, pos.y))
|
||||
{
|
||||
if (pos.x < m_ChartX) pos.x = m_ChartX;
|
||||
if (pos.x > m_ChartX + m_ChartWidth) pos.x = m_ChartX + m_ChartWidth;
|
||||
if (pos.y < m_ChartY) pos.y = m_ChartY;
|
||||
if (pos.y > m_ChartY + m_ChartHeight) pos.y = m_ChartY + m_ChartHeight;
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 ClampInGrid(GridCoord grid, Vector3 pos)
|
||||
{
|
||||
if (grid.Contains(pos)) return pos;
|
||||
else
|
||||
{
|
||||
// var pos = new Vector3(pos.x, pos.y);
|
||||
if (pos.x < grid.context.x) pos.x = grid.context.x;
|
||||
if (pos.x > grid.context.x + grid.context.width) pos.x = grid.context.x + grid.context.width;
|
||||
if (pos.y < grid.context.y) pos.y = grid.context.y;
|
||||
if (pos.y > grid.context.y + grid.context.height) pos.y = grid.context.y + grid.context.height;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换X轴和Y轴的配置
|
||||
/// </summary>
|
||||
/// <param name="index">坐标轴索引,0或1</param>
|
||||
public void CovertXYAxis(int index)
|
||||
{
|
||||
List<MainComponent> m_XAxes;
|
||||
List<MainComponent> m_YAxes;
|
||||
m_ComponentMaps.TryGetValue(typeof(XAxis), out m_XAxes);
|
||||
m_ComponentMaps.TryGetValue(typeof(YAxis), out m_YAxes);
|
||||
if (index >= 0 && index <= 1)
|
||||
{
|
||||
var xAxis = m_XAxes[index] as XAxis;
|
||||
var yAxis = m_YAxes[index] as YAxis;
|
||||
var tempX = xAxis.Clone();
|
||||
xAxis.Copy(yAxis);
|
||||
yAxis.Copy(tempX);
|
||||
xAxis.context.xOffset = 0;
|
||||
xAxis.context.yOffset = 0;
|
||||
yAxis.context.xOffset = 0;
|
||||
yAxis.context.yOffset = 0;
|
||||
xAxis.context.minValue = 0;
|
||||
xAxis.context.maxValue = 0;
|
||||
yAxis.context.minValue = 0;
|
||||
yAxis.context.maxValue = 0;
|
||||
RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在下一帧刷新DataZoom
|
||||
/// </summary>
|
||||
public void RefreshDataZoom()
|
||||
{
|
||||
foreach (var handler in m_ComponentHandlers)
|
||||
{
|
||||
if (handler is DataZoomHandler)
|
||||
{
|
||||
(handler as DataZoomHandler).RefreshDataZoomLabel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置可缓存的最大数据量。当数据量超过该值时,会自动删除第一个值再加入最新值。
|
||||
/// </summary>
|
||||
public void SetMaxCache(int maxCache)
|
||||
{
|
||||
foreach (var serie in m_Series)
|
||||
serie.maxCache = maxCache;
|
||||
foreach (var component in m_Components)
|
||||
{
|
||||
if (component is Axis)
|
||||
{
|
||||
(component as Axis).maxCache = maxCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetTitlePosition(Title title)
|
||||
{
|
||||
return chartPosition + title.location.GetPosition(chartWidth, chartHeight);
|
||||
}
|
||||
|
||||
public int GetLegendRealShowNameIndex(string name)
|
||||
{
|
||||
return m_LegendRealShowName.IndexOf(name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Base Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetBasePainterMaterial(Material material)
|
||||
{
|
||||
settings.basePainterMaterial = material;
|
||||
if (m_Painter != null)
|
||||
{
|
||||
m_Painter.material = material;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Serie Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetSeriePainterMaterial(Material material)
|
||||
{
|
||||
settings.basePainterMaterial = material;
|
||||
if (m_PainterList != null)
|
||||
{
|
||||
foreach (var painter in m_PainterList)
|
||||
painter.material = material;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置Top Painter的材质球
|
||||
/// </summary>
|
||||
/// <param name="material"></param>
|
||||
public void SetTopPainterMaterial(Material material)
|
||||
{
|
||||
settings.topPainterMaterial = material;
|
||||
if (m_PainterTop != null)
|
||||
{
|
||||
m_PainterTop.material = material;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d078e85e5877d4d0f990c8dc43006247
|
||||
guid: 1fc3767ca43f44f77a6d017fd55c8fec
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -22,7 +22,7 @@ namespace XCharts
|
||||
/// 背景组件。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public Background background { get { return m_Background; } }
|
||||
///public Background background { get { return m_Background; } }
|
||||
/// <summary>
|
||||
/// The x of graph.
|
||||
/// 图形的X
|
||||
@@ -63,7 +63,6 @@ namespace XCharts
|
||||
/// 警告信息。
|
||||
/// </summary>
|
||||
public string warningInfo { get; protected set; }
|
||||
public bool isControlledByLayout { get { return m_IsControlledByLayout; } }
|
||||
/// <summary>
|
||||
/// 强制开启鼠标事件检测。
|
||||
/// </summary>
|
||||
@@ -156,7 +155,7 @@ namespace XCharts
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 移除所有图表子节点,会自动重现初始化。
|
||||
/// 移除所有图表子节点,会自动重新初始化。
|
||||
/// </summary>
|
||||
public void RemoveChartObject()
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e17adfd3dc62d435cb79fa8c330fe186
|
||||
guid: ec7d385a69cce42fda86960eb0b23c3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -14,19 +14,22 @@ namespace XCharts
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class CandlestickChart : CoordinateChart
|
||||
public class CandlestickChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "CandlestickChart";
|
||||
tooltip.type = Tooltip.Type.Corss;
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.Corss;
|
||||
|
||||
RemoveData();
|
||||
var defaultDataCount = SerieTemplate.AddDefaultCandlestickSerie(this, "serie1");
|
||||
for (int i = 0; i < defaultDataCount; i++)
|
||||
Candlestick.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
27
Assets/XCharts/Runtime/Chart/GaugeChart.cs
Normal file
27
Assets/XCharts/Runtime/Chart/GaugeChart.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/GaugeChart", 19)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class GaugeChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
RemoveData();
|
||||
Gauge.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
86
Assets/XCharts/Runtime/Chart/HeatmapChart.cs
Normal file
86
Assets/XCharts/Runtime/Chart/HeatmapChart.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/HeatmapChart", 18)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class HeatmapChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.None;
|
||||
|
||||
var grid = GetOrAddChartComponent<GridCoord>();
|
||||
grid.left = 100;
|
||||
grid.right = 60;
|
||||
grid.bottom = 60;
|
||||
|
||||
var xAxis = GetOrAddChartComponent<XAxis>();
|
||||
xAxis.type = Axis.AxisType.Category;
|
||||
xAxis.boundaryGap = true;
|
||||
xAxis.splitNumber = 10;
|
||||
|
||||
var yAxis = GetOrAddChartComponent<YAxis>();
|
||||
yAxis.type = Axis.AxisType.Category;
|
||||
yAxis.boundaryGap = true;
|
||||
yAxis.splitNumber = 10;
|
||||
RemoveData();
|
||||
|
||||
var heatmapGridWid = 10f;
|
||||
int xSplitNumber = (int)(grid.context.width / heatmapGridWid);
|
||||
int ySplitNumber = (int)(grid.context.height / heatmapGridWid);
|
||||
|
||||
Heatmap.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
|
||||
var visualMap = GetOrAddChartComponent<VisualMap>();
|
||||
visualMap.max = 10;
|
||||
visualMap.range[0] = 0f;
|
||||
visualMap.range[1] = 10f;
|
||||
visualMap.orient = Orient.Vertical;
|
||||
visualMap.calculable = true;
|
||||
visualMap.location.align = Location.Align.BottomLeft;
|
||||
visualMap.location.bottom = 100;
|
||||
visualMap.location.left = 30;
|
||||
var colors = new List<string>{"#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf",
|
||||
"#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026"};
|
||||
visualMap.inRange.Clear();
|
||||
foreach (var str in colors)
|
||||
{
|
||||
visualMap.inRange.Add(ThemeStyle.GetColor(str));
|
||||
}
|
||||
for (int i = 0; i < xSplitNumber; i++)
|
||||
{
|
||||
xAxis.data.Add((i + 1).ToString());
|
||||
}
|
||||
for (int i = 0; i < ySplitNumber; i++)
|
||||
{
|
||||
yAxis.data.Add((i + 1).ToString());
|
||||
}
|
||||
for (int i = 0; i < xSplitNumber; i++)
|
||||
{
|
||||
for (int j = 0; j < ySplitNumber; j++)
|
||||
{
|
||||
var value = 0f;
|
||||
var rate = Random.Range(0, 101);
|
||||
if (rate > 70) value = Random.Range(8f, 10f);
|
||||
else value = Random.Range(1f, 8f);
|
||||
var list = new List<double> { i, j, value };
|
||||
AddData(0, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,23 @@ namespace XCharts
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class LineChart : CoordinateChart
|
||||
public class LineChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "LineChart";
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
visualMap.enable = false;
|
||||
visualMap.show = false;
|
||||
visualMap.autoMinMax = true;
|
||||
visualMap.inRange.Clear();
|
||||
visualMap.inRange.Add(Color.blue);
|
||||
visualMap.inRange.Add(Color.red);
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SerieTemplate.AddDefaultLineSerie(this, "serie1");
|
||||
Line.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
@@ -6,8 +6,6 @@
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
@@ -25,11 +23,10 @@ namespace XCharts
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "LiquidChart";
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.Line;
|
||||
RemoveData();
|
||||
RemoveVessel();
|
||||
AddVessel(Vessel.defaultVessel);
|
||||
SerieTemplate.AddDefaultLiquidSerie(this, "serie1");
|
||||
|
||||
Liquid.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
38
Assets/XCharts/Runtime/Chart/ParallelChart.cs
Normal file
38
Assets/XCharts/Runtime/Chart/ParallelChart.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/ParallelChart", 25)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ParallelChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<ParallelCoord>();
|
||||
AddChartComponentWhenNoExist<ParallelAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
Parallel.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
// for (int i = 0; i < 5; i++)
|
||||
// {
|
||||
// AddXAxisData("x" + (i + 1));
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 42960f04fcc2442baa061d32386aaaa8
|
||||
guid: 161753d0d6ce541c89483f8c3a21343f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -13,22 +13,17 @@ namespace XCharts
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public partial class PieChart : BaseChart
|
||||
public class PieChart : BaseChart
|
||||
{
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
raycastTarget = false;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "PieChart";
|
||||
m_Legends[0].show = true;
|
||||
var legend = GetOrAddChartComponent<Legend>();
|
||||
legend.show = true;
|
||||
|
||||
RemoveData();
|
||||
SerieTemplate.AddDefaultPieSerie(this, "serie1");
|
||||
Pie.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
@@ -19,7 +18,6 @@ namespace XCharts
|
||||
protected override void InitComponent()
|
||||
{
|
||||
base.InitComponent();
|
||||
if (m_Radars.Count == 0) m_Radars = new List<Radar>() { Radar.defaultRadar };
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
@@ -27,9 +25,9 @@ namespace XCharts
|
||||
{
|
||||
base.Reset();
|
||||
RemoveData();
|
||||
m_Radars.Clear();
|
||||
title.text = "RadarChart";
|
||||
SerieTemplate.AddDefaultRadarSerie(this, "serie1");
|
||||
RemoveChartComponents<RadarCoord>();
|
||||
AddChartComponent<RadarCoord>();
|
||||
Radar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -14,17 +14,16 @@ namespace XCharts
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public partial class RingChart : BaseChart
|
||||
public class RingChart : BaseChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
title.text = "RingChart";
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.Line;
|
||||
RemoveData();
|
||||
SerieTemplate.AddDefaultRingSerie(this, "serie1");
|
||||
Ring.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
41
Assets/XCharts/Runtime/Chart/ScatterChart.cs
Normal file
41
Assets/XCharts/Runtime/Chart/ScatterChart.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/ScatterChart", 17)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ScatterChart : BaseChart
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
|
||||
var tooltip = GetOrAddChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.None;
|
||||
tooltip.trigger = Tooltip.Trigger.Item;
|
||||
|
||||
var xAxis = GetOrAddChartComponent<XAxis>();
|
||||
xAxis.type = Axis.AxisType.Value;
|
||||
xAxis.boundaryGap = false;
|
||||
|
||||
var yAxis = GetOrAddChartComponent<YAxis>();
|
||||
yAxis.type = Axis.AxisType.Value;
|
||||
yAxis.boundaryGap = false;
|
||||
|
||||
RemoveData();
|
||||
Scatter.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1d3ce01c4a6f4e3482c1dc22f388889
|
||||
guid: 194a62edf7ec2484fa2eebbf5bde3e95
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3dbff4f83d24491da3a8a88e3e3ace4
|
||||
guid: 28b88ca3453f04fbdb23a53b5bcb4bf7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
50
Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs
Normal file
50
Assets/XCharts/Runtime/Component/Axis/AngleAxis/AngleAxis.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Angle axis of Polar Coordinate.
|
||||
/// 极坐标系的角度轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(AngleAxisHandler), true)]
|
||||
public class AngleAxis : Axis
|
||||
{
|
||||
[SerializeField] private float m_StartAngle = 90;
|
||||
|
||||
/// <summary>
|
||||
/// Starting angle of axis. 90 degrees by default, standing for top position of center.
|
||||
/// 0 degree stands for right position of center.
|
||||
/// 起始刻度的角度,默认为 90 度,即圆心的正上方。0 度为圆心的正右方。
|
||||
/// </summary>
|
||||
public float startAngle
|
||||
{
|
||||
get { return m_StartAngle; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_SplitNumber = 12;
|
||||
m_StartAngle = 90;
|
||||
m_BoundaryGap = false;
|
||||
m_Data = new List<string>(12);
|
||||
splitLine.show = true;
|
||||
splitLine.lineStyle.type = LineStyle.Type.Solid;
|
||||
axisLabel.textLimit.enable = false;
|
||||
minMaxType = AxisMinMaxType.Custom;
|
||||
min = 0;
|
||||
max = 360;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 032e5d8f514854bf39f5fd7052119271
|
||||
guid: 787015be923a74e1da4000c7abc2dcdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,148 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class AngleAxisHandler : MainComponentHandler<AngleAxis>
|
||||
{
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitAngleAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
component.startAngle = 90 - component.startAngle;
|
||||
UpdateAxisMinMaxValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawAngleAxis(vh, component);
|
||||
}
|
||||
|
||||
private void UpdateAxisMinMaxValue(AngleAxis axis, bool updateChart = true)
|
||||
{
|
||||
if (axis.IsCategory() || !axis.show) return;
|
||||
double tempMinValue = 0;
|
||||
double tempMaxValue = 0;
|
||||
SeriesHelper.GetYMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue,
|
||||
out tempMaxValue, true);
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue)
|
||||
{
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisLabelText(AngleAxis axis)
|
||||
{
|
||||
var runtimeWidth = 360;
|
||||
axis.UpdateLabelText(runtimeWidth, null, false, 500);
|
||||
}
|
||||
|
||||
private void InitAngleAxis(AngleAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
if (polar == null) return;
|
||||
PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
var radius = polar.context.radius;
|
||||
axis.context.labelObjectList.Clear();
|
||||
|
||||
string objName = "axis_angle" + axis.index;
|
||||
var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
axisObj.transform.localPosition = Vector3.zero;
|
||||
axisObj.SetActive(axis.show);
|
||||
axisObj.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(axisObj);
|
||||
var splitNumber = AxisHelper.GetSplitNumber(axis, radius, null);
|
||||
var totalAngle = axis.startAngle;
|
||||
var total = 360;
|
||||
var cenPos = polar.context.center;
|
||||
var txtHig = axis.axisLabel.textStyle.GetFontSize(chart.theme.axis) + 2;
|
||||
var margin = axis.axisLabel.margin;
|
||||
var isCategory = axis.IsCategory();
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
float scaleAngle = AxisHelper.GetScaleWidth(axis, total, i, null);
|
||||
bool inside = axis.axisLabel.inside;
|
||||
var labelName = AxisHelper.GetLabelName(axis, total, i, axis.context.minValue, axis.context.maxValue,
|
||||
null, isPercentStack);
|
||||
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(scaleAngle, txtHig), axis,
|
||||
chart.theme.axis, labelName);
|
||||
label.label.SetAlignment(axis.axisLabel.textStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
var pos = ChartHelper.GetPos(cenPos, radius + margin,
|
||||
isCategory ? (totalAngle + scaleAngle / 2) : totalAngle, true);
|
||||
AxisHelper.AdjustCircleLabelPos(label, pos, cenPos, txtHig, Vector3.zero);
|
||||
if (i == 0) axis.axisLabel.SetRelatedText(label.label, scaleAngle);
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalAngle += scaleAngle;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAngleAxis(VertexHelper vh, AngleAxis angleAxis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(angleAxis.polarIndex);
|
||||
var radius = polar.context.radius;
|
||||
var cenPos = polar.context.center;
|
||||
var total = 360;
|
||||
var size = AxisHelper.GetScaleNumber(angleAxis, total, null);
|
||||
var currAngle = angleAxis.startAngle;
|
||||
var tickWidth = angleAxis.axisTick.GetWidth(chart.theme.axis.tickWidth);
|
||||
var tickLength = angleAxis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(angleAxis, total, i);
|
||||
var pos = ChartHelper.GetPos(cenPos, radius, currAngle, true);
|
||||
if (angleAxis.show && angleAxis.splitLine.show)
|
||||
{
|
||||
var splitLineColor = angleAxis.splitLine.GetColor(chart.theme.axis.splitLineColor);
|
||||
var lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth);
|
||||
UGL.DrawLine(vh, cenPos, pos, lineWidth, splitLineColor);
|
||||
}
|
||||
if (angleAxis.show && angleAxis.axisTick.show)
|
||||
{
|
||||
var tickY = radius + tickLength;
|
||||
var tickPos = ChartHelper.GetPos(cenPos, tickY, currAngle, true);
|
||||
UGL.DrawLine(vh, pos, tickPos, tickWidth, chart.theme.axis.lineColor);
|
||||
}
|
||||
currAngle += scaleWidth;
|
||||
}
|
||||
if (angleAxis.show && angleAxis.axisLine.show)
|
||||
{
|
||||
var lineWidth = angleAxis.axisLine.GetWidth(chart.theme.axis.lineWidth);
|
||||
var outsideRaidus = radius + lineWidth * 2;
|
||||
UGL.DrawDoughnut(vh, cenPos, radius, outsideRaidus, chart.theme.axis.lineColor, Color.clear);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73ae9e0b481fc4587828be9149026b0f
|
||||
guid: 83f228c42435c4619943a2f187c98e7b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -8,7 +8,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
@@ -86,11 +85,12 @@ namespace XCharts
|
||||
[SerializeField] protected AxisMinMaxType m_MinMaxType;
|
||||
[SerializeField] protected int m_GridIndex;
|
||||
[SerializeField] protected int m_PolarIndex;
|
||||
[SerializeField] protected int m_ParallelIndex;
|
||||
[SerializeField] protected AxisPosition m_Position;
|
||||
[SerializeField] protected float m_Offset;
|
||||
[SerializeField] protected float m_Min;
|
||||
[SerializeField] protected float m_Max;
|
||||
[SerializeField] protected int m_SplitNumber = 5;
|
||||
[SerializeField] protected int m_SplitNumber = 0;
|
||||
[SerializeField] protected float m_Interval = 0;
|
||||
[SerializeField] protected bool m_BoundaryGap = true;
|
||||
[SerializeField] protected int m_MaxCache = 0;
|
||||
@@ -110,8 +110,7 @@ namespace XCharts
|
||||
[SerializeField] protected AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine;
|
||||
[SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
|
||||
|
||||
[NonSerialized] private double m_MinMaxValueRange;
|
||||
[NonSerialized] private bool m_NeedUpdateFilterData;
|
||||
public AxisContext context = new AxisContext();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show axis.
|
||||
@@ -159,6 +158,15 @@ namespace XCharts
|
||||
set { if (PropertyUtil.SetStruct(ref m_PolarIndex, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The index of the parallel on which the axis are located, by default, is in the first parallel.
|
||||
/// 坐标轴所在的 parallel 的索引,默认位于第一个 parallel。
|
||||
/// </summary>
|
||||
public int parallelIndex
|
||||
{
|
||||
get { return m_ParallelIndex; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ParallelIndex, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the position of axis in grid.
|
||||
/// 坐标轴在Grid中的位置。
|
||||
/// </summary>
|
||||
@@ -196,7 +204,7 @@ namespace XCharts
|
||||
}
|
||||
/// <summary>
|
||||
/// Number of segments that the axis is split into.
|
||||
/// 坐标轴的分割段数。
|
||||
/// 坐标轴的期望的分割段数。默认为0表示自动分割。
|
||||
/// </summary>
|
||||
public int splitNumber
|
||||
{
|
||||
@@ -368,14 +376,29 @@ namespace XCharts
|
||||
get { return m_IconStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_IconStyle, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public override bool vertsDirty
|
||||
{
|
||||
get { return m_VertsDirty || axisLine.anyDirty || axisTick.anyDirty || splitLine.anyDirty || splitArea.anyDirty; }
|
||||
get
|
||||
{
|
||||
return m_VertsDirty
|
||||
|| axisLine.anyDirty
|
||||
|| axisTick.anyDirty
|
||||
|| splitLine.anyDirty
|
||||
|| splitArea.anyDirty;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool componentDirty
|
||||
{
|
||||
get { return m_ComponentDirty || axisName.anyDirty || axisLabel.anyDirty; }
|
||||
get
|
||||
{
|
||||
return m_ComponentDirty
|
||||
|| axisName.anyDirty
|
||||
|| axisLabel.anyDirty;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
@@ -391,73 +414,12 @@ namespace XCharts
|
||||
splitLine.ClearVerticesDirty();
|
||||
splitArea.ClearVerticesDirty();
|
||||
}
|
||||
public int index { get; internal set; }
|
||||
public List<ChartLabel> runtimeAxisLabelList { get { return m_AxisLabelList; } set { m_AxisLabelList = value; } }
|
||||
/// <summary>
|
||||
/// the current minimun value.
|
||||
/// 当前最小值。
|
||||
/// </summary>
|
||||
public double runtimeMinValue
|
||||
|
||||
public override void SetComponentDirty()
|
||||
{
|
||||
get { return m_RuntimeMinValue; }
|
||||
internal set
|
||||
{
|
||||
m_RuntimeMinValue = value;
|
||||
m_RuntimeLastMinValue = value;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
}
|
||||
context.isNeedUpdateFilterData = true;
|
||||
base.SetComponentDirty();
|
||||
}
|
||||
/// <summary>
|
||||
/// the current maximum value.
|
||||
/// 当前最大值。
|
||||
/// </summary>
|
||||
public double runtimeMaxValue
|
||||
{
|
||||
get { return m_RuntimeMaxValue; }
|
||||
internal set
|
||||
{
|
||||
m_RuntimeMaxValue = value;
|
||||
m_RuntimeLastMaxValue = value;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the x offset of zero position.
|
||||
/// 坐标轴原点在X轴的偏移。
|
||||
/// </summary>
|
||||
public float runtimeZeroXOffset { get; internal set; }
|
||||
/// <summary>
|
||||
/// the y offset of zero position.
|
||||
/// 坐标轴原点在Y轴的偏移。
|
||||
/// </summary>
|
||||
public float runtimeZeroYOffset { get; internal set; }
|
||||
public int runtimeMinLogIndex { get { return logBaseE ? (int)Math.Log(runtimeMinValue) : (int)Math.Log(runtimeMinValue, logBase); } }
|
||||
public int runtimeMaxLogIndex { get { return logBaseE ? (int)Math.Log(runtimeMaxValue) : (int)Math.Log(runtimeMaxValue, logBase); } }
|
||||
public bool runtimeLastCheckInverse { get; set; }
|
||||
public double runtimeMinMaxRange { get { return m_MinMaxValueRange; } set { m_MinMaxValueRange = value; } }
|
||||
public List<string> runtimeData { get { return m_RuntimeData; } }
|
||||
public float runtimeScaleWidth { get; internal set; }
|
||||
private int filterStart;
|
||||
private int filterEnd;
|
||||
private int filterMinShow;
|
||||
private List<string> filterData;
|
||||
private List<ChartLabel> m_AxisLabelList = new List<ChartLabel>();
|
||||
private GameObject m_TooltipLabel;
|
||||
private ChartText m_TooltipLabelText;
|
||||
private RectTransform m_TooltipLabelRect;
|
||||
private double m_RuntimeMinValue;
|
||||
private double m_RuntimeLastMinValue;
|
||||
private bool m_RuntimeMinValueChanged;
|
||||
private float m_RuntimeMinValueUpdateTime;
|
||||
private double m_RuntimeMaxValue;
|
||||
private double m_RuntimeLastMaxValue;
|
||||
private bool m_RuntimeMaxValueChanged;
|
||||
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()
|
||||
{
|
||||
@@ -519,11 +481,11 @@ namespace XCharts
|
||||
/// <summary>
|
||||
/// 清空类目数据
|
||||
/// </summary>
|
||||
public void ClearData()
|
||||
public override void ClearData()
|
||||
{
|
||||
m_Data.Clear();
|
||||
m_Icons.Clear();
|
||||
m_RuntimeData.Clear();
|
||||
context.Clear();
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
@@ -562,9 +524,29 @@ namespace XCharts
|
||||
return type == AxisType.Time;
|
||||
}
|
||||
|
||||
public bool IsLeft()
|
||||
{
|
||||
return position == AxisPosition.Left;
|
||||
}
|
||||
|
||||
public bool IsRight()
|
||||
{
|
||||
return position == AxisPosition.Right;
|
||||
}
|
||||
|
||||
public bool IsTop()
|
||||
{
|
||||
return position == AxisPosition.Top;
|
||||
}
|
||||
|
||||
public bool IsBottom()
|
||||
{
|
||||
return position == AxisPosition.Bottom;
|
||||
}
|
||||
|
||||
public void SetNeedUpdateFilterData()
|
||||
{
|
||||
m_NeedUpdateFilterData = true;
|
||||
context.isNeedUpdateFilterData = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -577,12 +559,16 @@ namespace XCharts
|
||||
{
|
||||
while (m_Data.Count >= maxCache)
|
||||
{
|
||||
m_NeedUpdateFilterData = true;
|
||||
context.isNeedUpdateFilterData = true;
|
||||
m_Data.RemoveAt(m_InsertDataToHead ? m_Data.Count - 1 : 0);
|
||||
}
|
||||
}
|
||||
if (m_InsertDataToHead) m_Data.Insert(0, category);
|
||||
else m_Data.Add(category);
|
||||
|
||||
if (m_InsertDataToHead)
|
||||
m_Data.Insert(0, category);
|
||||
else
|
||||
m_Data.Add(category);
|
||||
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
@@ -668,6 +654,20 @@ namespace XCharts
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得值在坐标轴上的距离
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="axisLength"></param>
|
||||
/// <returns></returns>
|
||||
public float GetDistance(double value, float axisLength)
|
||||
{
|
||||
if (context.minMaxRange == 0)
|
||||
return 0;
|
||||
else
|
||||
return axisLength * (float)((value - context.minValue) / context.minMaxRange);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定区域缩放的类目数据列表
|
||||
/// </summary>
|
||||
@@ -678,20 +678,19 @@ namespace XCharts
|
||||
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
|
||||
{
|
||||
UpdateFilterData(dataZoom);
|
||||
return filterData;
|
||||
return context.filterData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Data.Count > 0 ? m_Data : m_RuntimeData;
|
||||
return m_Data.Count > 0 ? m_Data : context.runtimeData;
|
||||
}
|
||||
}
|
||||
|
||||
internal List<string> GetDataList()
|
||||
{
|
||||
return m_Data.Count > 0 ? m_Data : m_RuntimeData;
|
||||
return m_Data.Count > 0 ? m_Data : context.runtimeData;
|
||||
}
|
||||
|
||||
private List<string> emptyFliter = new List<string>();
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
/// </summary>
|
||||
@@ -701,45 +700,7 @@ namespace XCharts
|
||||
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
|
||||
{
|
||||
var data = GetDataList();
|
||||
var range = Mathf.RoundToInt(data.Count * (dataZoom.end - dataZoom.start) / 100);
|
||||
if (range <= 0) range = 1;
|
||||
int start = 0, end = 0;
|
||||
if (dataZoom.runtimeInvert)
|
||||
{
|
||||
end = Mathf.CeilToInt(data.Count * dataZoom.end / 100);
|
||||
start = end - range;
|
||||
if (start < 0) start = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = Mathf.FloorToInt(data.Count * dataZoom.start / 100);
|
||||
end = start + range;
|
||||
if (end > data.Count) end = data.Count;
|
||||
}
|
||||
if (start != filterStart || end != filterEnd || dataZoom.minShowNum != filterMinShow || m_NeedUpdateFilterData)
|
||||
{
|
||||
filterStart = start;
|
||||
filterEnd = end;
|
||||
filterMinShow = dataZoom.minShowNum;
|
||||
m_NeedUpdateFilterData = false;
|
||||
if (data.Count > 0)
|
||||
{
|
||||
if (range < dataZoom.minShowNum)
|
||||
{
|
||||
if (dataZoom.minShowNum > data.Count) range = data.Count;
|
||||
else range = dataZoom.minShowNum;
|
||||
}
|
||||
filterData = data.GetRange(start, range);
|
||||
}
|
||||
else
|
||||
{
|
||||
filterData = data;
|
||||
}
|
||||
}
|
||||
else if (end == 0)
|
||||
{
|
||||
filterData = emptyFliter;
|
||||
}
|
||||
context.UpdateFilterData(data, dataZoom);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,9 +709,9 @@ namespace XCharts
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
internal int GetDataNumber(DataZoom dataZoom)
|
||||
internal int GetDataCount(DataZoom dataZoom)
|
||||
{
|
||||
return GetDataList(dataZoom).Count;
|
||||
return IsCategory() ? GetDataList(dataZoom).Count : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -761,154 +722,66 @@ namespace XCharts
|
||||
{
|
||||
var minValue = GetCurrMinValue(duration);
|
||||
var maxValue = GetCurrMaxValue(duration);
|
||||
for (int i = 0; i < runtimeAxisLabelList.Count; i++)
|
||||
for (int i = 0; i < context.labelObjectList.Count; i++)
|
||||
{
|
||||
if (runtimeAxisLabelList[i] != null)
|
||||
if (context.labelObjectList[i] != null)
|
||||
{
|
||||
var text = AxisHelper.GetLabelName(this, coordinateWidth, i, minValue, maxValue, dataZoom, forcePercent);
|
||||
runtimeAxisLabelList[i].SetText(text);
|
||||
context.labelObjectList[i].SetText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetTooltipLabel(GameObject label)
|
||||
internal Vector3 GetLabelObjectPosition(int index)
|
||||
{
|
||||
m_TooltipLabel = label;
|
||||
m_TooltipLabelRect = label.GetComponent<RectTransform>();
|
||||
m_TooltipLabelText = new ChartText(label);
|
||||
ChartHelper.SetActive(m_TooltipLabel, true);
|
||||
if (context.labelObjectList != null && index < context.labelObjectList.Count)
|
||||
return context.labelObjectList[index].GetPosition();
|
||||
else
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
internal void SetTooltipLabelColor(Color bgColor, Color textColor)
|
||||
internal bool UpdateMinValue(double value, bool check)
|
||||
{
|
||||
m_TooltipLabel.GetComponent<Image>().color = bgColor;
|
||||
m_TooltipLabelText.SetColor(textColor);
|
||||
return context.UpdateMinValue(value, check);
|
||||
}
|
||||
|
||||
internal void SetTooltipLabelActive(bool flag)
|
||||
internal bool UpdateMaxValue(double value, bool check)
|
||||
{
|
||||
if (m_TooltipLabel == null) return;
|
||||
ChartHelper.SetActive(m_TooltipLabel, flag);
|
||||
return context.UpdateMaxValue(value, check);
|
||||
}
|
||||
|
||||
internal void UpdateTooptipLabelText(string text)
|
||||
internal void UpdateMinMaxValue(double minValue, double maxValue, bool check)
|
||||
{
|
||||
if (m_TooltipLabelText != null)
|
||||
UpdateMinValue(minValue, check);
|
||||
UpdateMaxValue(maxValue, check);
|
||||
double tempRange = maxValue - minValue;
|
||||
if (context.minMaxRange != tempRange)
|
||||
{
|
||||
m_TooltipLabelText.SetText(text);
|
||||
m_TooltipLabelRect.sizeDelta = new Vector2(m_TooltipLabelText.GetPreferredWidth() + 8,
|
||||
m_TooltipLabelText.GetPreferredHeight() + 8);
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateTooltipLabelPos(Vector2 pos)
|
||||
{
|
||||
if (m_TooltipLabel)
|
||||
{
|
||||
m_TooltipLabel.transform.localPosition = pos;
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateMinValue(double value, bool check)
|
||||
{
|
||||
if (value != m_RuntimeMaxValue)
|
||||
{
|
||||
if (check && Application.isPlaying)
|
||||
context.minMaxRange = tempRange;
|
||||
if (type == Axis.AxisType.Value && interval > 0)
|
||||
{
|
||||
if (m_RuntimeMinValueFirstChanged)
|
||||
{
|
||||
m_RuntimeMinValueFirstChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeLastMinValue = m_RuntimeMinValue;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
}
|
||||
m_RuntimeMinValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMinValue = value;
|
||||
m_RuntimeLastMinValue = value;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateMaxValue(double value, bool check)
|
||||
{
|
||||
if (value != m_RuntimeMaxValue)
|
||||
{
|
||||
if (check && Application.isPlaying)
|
||||
{
|
||||
if (m_RuntimeMaxValueFirstChanged)
|
||||
{
|
||||
m_RuntimeMaxValueFirstChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeLastMaxValue = m_RuntimeMaxValue;
|
||||
m_RuntimeMaxValueChanged = true;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
}
|
||||
m_RuntimeMaxValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMaxValue = value;
|
||||
m_RuntimeLastMaxValue = value;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double GetCurrMinValue(float duration)
|
||||
{
|
||||
if (!Application.isPlaying) return m_RuntimeMinValue;
|
||||
if (m_RuntimeMinValue == 0 && m_RuntimeMaxValue == 0) return 0;
|
||||
if (!m_RuntimeMinValueChanged) return m_RuntimeMinValue;
|
||||
var time = Time.time - m_RuntimeMinValueUpdateTime;
|
||||
if (time == 0) return m_RuntimeMinValue;
|
||||
var total = duration / 1000;
|
||||
if (duration > 0 && time <= total)
|
||||
{
|
||||
var curr = MathUtil.Lerp(m_RuntimeLastMinValue, m_RuntimeMinValue, time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMinValueChanged = false;
|
||||
return m_RuntimeMinValue;
|
||||
}
|
||||
return context.GetCurrMinValue(duration);
|
||||
}
|
||||
|
||||
public double GetCurrMaxValue(float duration)
|
||||
{
|
||||
if (!Application.isPlaying) return m_RuntimeMaxValue;
|
||||
if (m_RuntimeMinValue == 0 && m_RuntimeMaxValue == 0) return 0;
|
||||
if (!m_RuntimeMaxValueChanged) return m_RuntimeMaxValue;
|
||||
var time = Time.time - m_RuntimeMaxValueUpdateTime;
|
||||
if (time == 0) return m_RuntimeMaxValue;
|
||||
var total = duration / 1000;
|
||||
if (duration > 0 && time < total)
|
||||
{
|
||||
var curr = MathUtil.Lerp(m_RuntimeLastMaxValue, m_RuntimeMaxValue, time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
return m_RuntimeMaxValue;
|
||||
}
|
||||
return context.GetCurrMaxValue(duration);
|
||||
}
|
||||
|
||||
public bool IsValueChanging(float duration)
|
||||
{
|
||||
if (!Application.isPlaying) return false;
|
||||
if (GetCurrMinValue(duration) != m_RuntimeMinValue || GetCurrMaxValue(duration) != m_RuntimeMaxValue)
|
||||
if (!Application.isPlaying)
|
||||
return false;
|
||||
|
||||
if (GetCurrMinValue(duration) != context.minValue
|
||||
|| GetCurrMaxValue(duration) != context.maxValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -920,169 +793,42 @@ namespace XCharts
|
||||
|
||||
public float GetLogValue(double value)
|
||||
{
|
||||
if (value <= 0 || value == 1) return 0;
|
||||
return logBaseE ? (float)Math.Log(value) : (float)Math.Log(value, logBase);
|
||||
if (value <= 0 || value == 1)
|
||||
return 0;
|
||||
else
|
||||
return logBaseE ? (float)Math.Log(value) : (float)Math.Log(value, logBase);
|
||||
}
|
||||
|
||||
public bool IsLeft()
|
||||
public int GetLogMinIndex()
|
||||
{
|
||||
return position == AxisPosition.Left;
|
||||
return logBaseE
|
||||
? (int)Math.Log(context.minValue)
|
||||
: (int)Math.Log(context.minValue, logBase);
|
||||
}
|
||||
|
||||
public bool IsRight()
|
||||
public int GetLogMaxIndex()
|
||||
{
|
||||
return position == AxisPosition.Right;
|
||||
return logBaseE
|
||||
? (int)Math.Log(context.maxValue)
|
||||
: (int)Math.Log(context.maxValue, logBase);
|
||||
}
|
||||
|
||||
public bool IsTop()
|
||||
public double GetLabelValue(int index)
|
||||
{
|
||||
return position == AxisPosition.Top;
|
||||
if (index < 0)
|
||||
return context.minValue;
|
||||
else if (index > context.labelValueList.Count - 1)
|
||||
return context.maxValue;
|
||||
else
|
||||
return context.labelValueList[index];
|
||||
}
|
||||
|
||||
public bool IsBottom()
|
||||
public double GetLastLabelValue()
|
||||
{
|
||||
return position == AxisPosition.Bottom;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate. a grid component can place at most 2 x axis,
|
||||
/// one on the bottom and another on the top.
|
||||
/// <para>直角坐标系 grid 中的 x 轴,单个 grid 组件最多只能放上下两个 x 轴。</para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class XAxis : Axis
|
||||
{
|
||||
public static XAxis defaultXAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
var axis = new XAxis
|
||||
{
|
||||
m_Show = true,
|
||||
m_Type = AxisType.Category,
|
||||
m_Min = 0,
|
||||
m_Max = 0,
|
||||
m_SplitNumber = 5,
|
||||
m_BoundaryGap = true,
|
||||
m_Position = AxisPosition.Bottom,
|
||||
m_Offset = 0,
|
||||
m_Data = new List<string>()
|
||||
{
|
||||
"x1","x2","x3","x4","x5"
|
||||
},
|
||||
m_Icons = new List<Sprite>(5),
|
||||
};
|
||||
axis.splitLine.show = false;
|
||||
axis.splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axis.axisLabel.textLimit.enable = true;
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate. a grid component can place at most 2 x axis,
|
||||
/// one on the bottom and another on the top.
|
||||
/// <para>直角坐标系 grid 中的 y 轴,单个 grid 组件最多只能放左右两个 y 轴</para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class YAxis : Axis
|
||||
{
|
||||
public static YAxis defaultYAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
var axis = new YAxis
|
||||
{
|
||||
m_Show = true,
|
||||
m_Type = AxisType.Value,
|
||||
m_Min = 0,
|
||||
m_Max = 0,
|
||||
m_SplitNumber = 5,
|
||||
m_BoundaryGap = false,
|
||||
m_Position = AxisPosition.Left,
|
||||
m_Data = new List<string>(5),
|
||||
|
||||
};
|
||||
axis.splitLine.show = true;
|
||||
axis.splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axis.axisLabel.textLimit.enable = false;
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Radial axis of polar coordinate.
|
||||
/// 极坐标系的径向轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class RadiusAxis : Axis
|
||||
{
|
||||
public static RadiusAxis defaultRadiusAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
var axis = new RadiusAxis
|
||||
{
|
||||
m_Show = true,
|
||||
m_Type = AxisType.Value,
|
||||
m_Min = 0,
|
||||
m_Max = 0,
|
||||
m_SplitNumber = 5,
|
||||
m_BoundaryGap = false,
|
||||
m_Data = new List<string>(5),
|
||||
};
|
||||
axis.splitLine.show = true;
|
||||
axis.splitLine.lineStyle.type = LineStyle.Type.Solid;
|
||||
axis.axisLabel.textLimit.enable = false;
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Angle axis of Polar Coordinate.
|
||||
/// 极坐标系的角度轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AngleAxis : Axis
|
||||
{
|
||||
[SerializeField] private float m_StartAngle = 90;
|
||||
|
||||
/// <summary>
|
||||
/// Starting angle of axis. 90 degrees by default, standing for top position of center. 0 degree stands for right position of center.
|
||||
/// 起始刻度的角度,默认为 90 度,即圆心的正上方。0 度为圆心的正右方。
|
||||
/// </summary>
|
||||
public float startAngle
|
||||
{
|
||||
get { return m_StartAngle; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public float runtimeStartAngle { get; set; }
|
||||
|
||||
public static AngleAxis defaultAngleAxis
|
||||
{
|
||||
get
|
||||
{
|
||||
var axis = new AngleAxis
|
||||
{
|
||||
m_Show = true,
|
||||
m_Type = AxisType.Value,
|
||||
m_SplitNumber = 12,
|
||||
m_BoundaryGap = false,
|
||||
m_Data = new List<string>(12),
|
||||
};
|
||||
axis.splitLine.show = true;
|
||||
axis.splitLine.lineStyle.type = LineStyle.Type.Solid;
|
||||
axis.axisLabel.textLimit.enable = false;
|
||||
axis.minMaxType = AxisMinMaxType.Custom;
|
||||
axis.min = 0;
|
||||
axis.max = 360;
|
||||
return axis;
|
||||
}
|
||||
if (context.labelValueList.Count > 0)
|
||||
return context.labelValueList[context.labelValueList.Count - 1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4e87b6a821d94304af45b2955c293bb
|
||||
guid: d5c29555575e04db98ee243c3b17f0ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
268
Assets/XCharts/Runtime/Component/Axis/AxisContext.cs
Normal file
268
Assets/XCharts/Runtime/Component/Axis/AxisContext.cs
Normal file
@@ -0,0 +1,268 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class AxisContext : MainComponentContext
|
||||
{
|
||||
/// <summary>
|
||||
/// the current minimun value.
|
||||
/// 当前最小值。
|
||||
/// </summary>
|
||||
public double minValue
|
||||
{
|
||||
get { return m_RuntimeMinValue; }
|
||||
internal set
|
||||
{
|
||||
m_RuntimeMinValue = value;
|
||||
m_RuntimeLastMinValue = value;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the current maximum value.
|
||||
/// 当前最大值。
|
||||
/// </summary>
|
||||
public double maxValue
|
||||
{
|
||||
get { return m_RuntimeMaxValue; }
|
||||
internal set
|
||||
{
|
||||
m_RuntimeMaxValue = value;
|
||||
m_RuntimeLastMaxValue = value;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// the x offset of zero position.
|
||||
/// 坐标轴原点在X轴的偏移。
|
||||
/// </summary>
|
||||
public float xOffset { get; internal set; }
|
||||
/// <summary>
|
||||
/// the y offset of zero position.
|
||||
/// 坐标轴原点在Y轴的偏移。
|
||||
/// </summary>
|
||||
public float yOffset { get; internal set; }
|
||||
public double minMaxRange { get; internal set; }
|
||||
public float scaleWidth { get; internal set; }
|
||||
public float startAngle { get; set; }
|
||||
public double pointerValue { get; internal set; }
|
||||
public Vector3 pointerLabelPosition { get; internal set; }
|
||||
public double axisTooltipValue { get; internal set; }
|
||||
public List<string> runtimeData { get { return m_RuntimeData; } }
|
||||
public List<double> labelValueList { get { return m_LabelValueList; } }
|
||||
public List<ChartLabel> labelObjectList { get { return m_AxisLabelList; } }
|
||||
|
||||
internal List<string> filterData;
|
||||
internal bool lastCheckInverse { get; set; }
|
||||
internal bool isNeedUpdateFilterData;
|
||||
|
||||
private int filterStart;
|
||||
private int filterEnd;
|
||||
private int filterMinShow;
|
||||
private double m_RuntimeMinValue;
|
||||
private double m_RuntimeLastMinValue;
|
||||
private bool m_RuntimeMinValueChanged;
|
||||
private float m_RuntimeMinValueUpdateTime;
|
||||
private double m_RuntimeMaxValue;
|
||||
private double m_RuntimeLastMaxValue;
|
||||
private bool m_RuntimeMaxValueChanged;
|
||||
private float m_RuntimeMaxValueUpdateTime;
|
||||
private bool m_RuntimeMinValueFirstChanged = true;
|
||||
private bool m_RuntimeMaxValueFirstChanged = true;
|
||||
|
||||
private List<ChartLabel> m_AxisLabelList = new List<ChartLabel>();
|
||||
private List<double> m_LabelValueList = new List<double>();
|
||||
private List<string> m_RuntimeData = new List<string>();
|
||||
|
||||
|
||||
internal void Clear()
|
||||
{
|
||||
m_RuntimeData.Clear();
|
||||
}
|
||||
|
||||
internal bool UpdateMinValue(double value, bool check)
|
||||
{
|
||||
if (value != maxValue)
|
||||
{
|
||||
if (check && Application.isPlaying)
|
||||
{
|
||||
if (m_RuntimeMinValueFirstChanged)
|
||||
{
|
||||
m_RuntimeMinValueFirstChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeLastMinValue = minValue;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
}
|
||||
minValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = value;
|
||||
m_RuntimeLastMinValue = value;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool UpdateMaxValue(double value, bool check)
|
||||
{
|
||||
if (value != maxValue)
|
||||
{
|
||||
if (check && Application.isPlaying)
|
||||
{
|
||||
if (m_RuntimeMaxValueFirstChanged)
|
||||
{
|
||||
m_RuntimeMaxValueFirstChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeLastMaxValue = maxValue;
|
||||
m_RuntimeMaxValueChanged = true;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
}
|
||||
maxValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxValue = value;
|
||||
m_RuntimeLastMaxValue = value;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public double GetCurrMinValue(float duration)
|
||||
{
|
||||
if (!Application.isPlaying || !m_RuntimeMinValueChanged)
|
||||
return minValue;
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
return 0;
|
||||
|
||||
var time = Time.time - m_RuntimeMinValueUpdateTime;
|
||||
if (time == 0)
|
||||
return minValue;
|
||||
|
||||
var total = duration / 1000;
|
||||
if (duration > 0 && time <= total)
|
||||
{
|
||||
var curr = MathUtil.Lerp(m_RuntimeLastMinValue, minValue, time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMinValueChanged = false;
|
||||
return minValue;
|
||||
}
|
||||
}
|
||||
|
||||
public double GetCurrMaxValue(float duration)
|
||||
{
|
||||
if (!Application.isPlaying || !m_RuntimeMaxValueChanged)
|
||||
return maxValue;
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
return 0;
|
||||
|
||||
var time = Time.time - m_RuntimeMaxValueUpdateTime;
|
||||
if (time == 0)
|
||||
return maxValue;
|
||||
|
||||
var total = duration / 1000;
|
||||
if (duration > 0 && time < total)
|
||||
{
|
||||
var curr = MathUtil.Lerp(m_RuntimeLastMaxValue, maxValue, time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
return maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> m_EmptyFliter = new List<string>();
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateFilterData(List<string> data, DataZoom dataZoom)
|
||||
{
|
||||
int start = 0, end = 0;
|
||||
var range = Mathf.RoundToInt(data.Count * (dataZoom.end - dataZoom.start) / 100);
|
||||
if (range <= 0)
|
||||
range = 1;
|
||||
|
||||
if (dataZoom.context.invert)
|
||||
{
|
||||
end = Mathf.CeilToInt(data.Count * dataZoom.end / 100);
|
||||
start = end - range;
|
||||
if (start < 0) start = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = Mathf.FloorToInt(data.Count * dataZoom.start / 100);
|
||||
end = start + range;
|
||||
if (end > data.Count) end = data.Count;
|
||||
}
|
||||
|
||||
if (start != filterStart
|
||||
|| end != filterEnd
|
||||
|| dataZoom.minShowNum != filterMinShow
|
||||
|| isNeedUpdateFilterData)
|
||||
{
|
||||
filterStart = start;
|
||||
filterEnd = end;
|
||||
filterMinShow = dataZoom.minShowNum;
|
||||
isNeedUpdateFilterData = false;
|
||||
|
||||
if (data.Count > 0)
|
||||
{
|
||||
if (range < dataZoom.minShowNum)
|
||||
{
|
||||
if (dataZoom.minShowNum > data.Count)
|
||||
range = data.Count;
|
||||
else
|
||||
range = dataZoom.minShowNum;
|
||||
}
|
||||
filterData = data.GetRange(start, range);
|
||||
}
|
||||
else
|
||||
{
|
||||
filterData = data;
|
||||
}
|
||||
}
|
||||
else if (end == 0)
|
||||
{
|
||||
filterData = m_EmptyFliter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd14dec4102b848f699bbf42babbe4c4
|
||||
guid: 6525f065fa5d04663ab7026a3467f56e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
823
Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs
Normal file
823
Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs
Normal file
@@ -0,0 +1,823 @@
|
||||
/******************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/******************************************/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public abstract class AxisHandler<T> : MainComponentHandler
|
||||
where T : Axis
|
||||
{
|
||||
private static readonly string s_DefaultAxisName = "name";
|
||||
private double m_LastInterval = double.MinValue;
|
||||
private int m_LastSplitNumber = int.MinValue;
|
||||
public T component { get; internal set; }
|
||||
|
||||
internal override void SetComponent(MainComponent component)
|
||||
{
|
||||
this.component = (T)component;
|
||||
}
|
||||
|
||||
protected virtual Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
protected virtual Orient orient { get; }
|
||||
|
||||
protected void UpdatePointerValue(Axis axis)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
if (!grid.context.runtimeIsPointerEnter)
|
||||
{
|
||||
axis.context.pointerValue = double.PositiveInfinity;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var dataCount = chart.series.Count > 0 ? chart.series[0].GetDataList(dataZoom).Count : 0;
|
||||
var local = chart.pointerPos;
|
||||
|
||||
for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
|
||||
{
|
||||
if (axis is YAxis)
|
||||
{
|
||||
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.height, dataCount, dataZoom);
|
||||
float pY = grid.context.y + j * splitWid;
|
||||
if ((axis.boundaryGap && (local.y > pY && local.y <= pY + splitWid))
|
||||
|| (!axis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2)))
|
||||
{
|
||||
axis.context.pointerValue = j;
|
||||
axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.width, dataCount, dataZoom);
|
||||
float pX = grid.context.x + j * splitWid;
|
||||
if ((axis.boundaryGap && (local.x > pX && local.x <= pX + splitWid))
|
||||
|| (!axis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2)))
|
||||
{
|
||||
axis.context.pointerValue = j;
|
||||
axis.context.pointerLabelPosition = axis.GetLabelObjectPosition(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis is YAxis)
|
||||
{
|
||||
var yRate = axis.context.minMaxRange / grid.context.height;
|
||||
|
||||
var yValue = yRate * (chart.pointerPos.y - grid.context.y - axis.context.yOffset);
|
||||
if (axis.context.minValue > 0)
|
||||
yValue += axis.context.minValue;
|
||||
|
||||
var labelX = axis.GetLabelObjectPosition(0).x;
|
||||
axis.context.pointerValue = yValue;
|
||||
axis.context.pointerLabelPosition = new Vector3(labelX, chart.pointerPos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
var xRate = axis.context.minMaxRange / grid.context.width;
|
||||
|
||||
var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.xOffset);
|
||||
if (axis.context.minValue > 0)
|
||||
xValue += axis.context.minValue;
|
||||
|
||||
var labelY = axis.GetLabelObjectPosition(0).y;
|
||||
axis.context.pointerValue = xValue;
|
||||
axis.context.pointerLabelPosition = new Vector3(chart.pointerPos.x, labelY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true)
|
||||
{
|
||||
if (!axis.show)
|
||||
return;
|
||||
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
axis.context.minValue = 0;
|
||||
axis.context.maxValue = SeriesHelper.GetMaxSerieDataCount(chart.series) - 1;
|
||||
axis.context.minMaxRange = axis.context.maxValue;
|
||||
return;
|
||||
}
|
||||
|
||||
double tempMinValue = 0;
|
||||
double tempMaxValue = 0;
|
||||
chart.GetSeriesMinMaxValue(axis, axisIndex, out tempMinValue, out tempMaxValue);
|
||||
|
||||
if (tempMinValue != axis.context.minValue
|
||||
|| tempMaxValue != axis.context.maxValue
|
||||
|| m_LastInterval != axis.interval
|
||||
|| m_LastSplitNumber != axis.splitNumber)
|
||||
{
|
||||
m_LastSplitNumber = axis.splitNumber;
|
||||
m_LastInterval = axis.interval;
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
|
||||
UpdateAxisTickValueList(axis);
|
||||
|
||||
if (tempMinValue != 0 || tempMaxValue != 0)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid != null && axis is XAxis && axis.IsValue())
|
||||
{
|
||||
axis.context.xOffset = axis.context.minValue > 0
|
||||
? 0
|
||||
: (axis.context.maxValue < 0
|
||||
? grid.context.width
|
||||
: (float)(Math.Abs(axis.context.minValue) * (grid.context.width
|
||||
/ (Math.Abs(axis.context.minValue) + Math.Abs(axis.context.maxValue))))
|
||||
);
|
||||
}
|
||||
if (grid != null && axis is YAxis && axis.IsValue())
|
||||
{
|
||||
axis.context.yOffset = axis.context.minValue > 0
|
||||
? 0
|
||||
: (axis.context.maxValue < 0
|
||||
? grid.context.height
|
||||
: (float)(Math.Abs(axis.context.minValue) * (grid.context.height
|
||||
/ (Math.Abs(axis.context.minValue) + Math.Abs(axis.context.maxValue))))
|
||||
);
|
||||
}
|
||||
}
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
if (dataZoom != null && dataZoom.enable)
|
||||
{
|
||||
if (axis is XAxis)
|
||||
dataZoom.SetXAxisIndexValueInfo(axisIndex, tempMinValue, tempMaxValue);
|
||||
else
|
||||
dataZoom.SetYAxisIndexValueInfo(axisIndex, tempMinValue, tempMaxValue);
|
||||
}
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid == null || axis == null)
|
||||
return;
|
||||
|
||||
float runtimeWidth = axis is XAxis ? grid.context.width : grid.context.height;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack, 500);
|
||||
}
|
||||
|
||||
internal static void UpdateAxisTickValueList(Axis axis)
|
||||
{
|
||||
if (axis.IsTime())
|
||||
{
|
||||
var lastCount = axis.context.labelValueList.Count;
|
||||
DateTimeUtil.UpdateTimeAxisDateTimeList(axis.context.labelValueList, (int)axis.context.minValue,
|
||||
(int)axis.context.maxValue, axis.splitNumber);
|
||||
|
||||
if (axis.context.labelValueList.Count != lastCount)
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
else if (axis.IsValue())
|
||||
{
|
||||
var list = axis.context.labelValueList;
|
||||
var lastCount = list.Count;
|
||||
list.Clear();
|
||||
|
||||
var range = axis.context.maxValue - axis.context.minValue;
|
||||
if (range <= 0)
|
||||
return;
|
||||
|
||||
double tick = axis.interval;
|
||||
|
||||
if (axis.interval == 0)
|
||||
{
|
||||
if (axis.splitNumber > 0)
|
||||
{
|
||||
tick = range / axis.splitNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
var each = GetTick(range);
|
||||
tick = each;
|
||||
if (range / tick > 8)
|
||||
tick = 2 * each;
|
||||
else if (range / tick < 4)
|
||||
tick = each / 2;
|
||||
}
|
||||
}
|
||||
var value = 0d;
|
||||
if (Mathf.Approximately((float)(axis.context.minValue % tick), 0))
|
||||
{
|
||||
value = axis.context.minValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add(axis.context.minValue);
|
||||
value = Math.Ceiling(axis.context.minValue / tick) * tick;
|
||||
}
|
||||
while (value <= axis.context.maxValue)
|
||||
{
|
||||
list.Add(value);
|
||||
value += tick;
|
||||
|
||||
if (list.Count > 20)
|
||||
break;
|
||||
}
|
||||
if (!ChartHelper.IsEquals(axis.context.maxValue, list[list.Count - 1]))
|
||||
{
|
||||
list.Add(axis.context.maxValue);
|
||||
}
|
||||
if (lastCount != list.Count)
|
||||
{
|
||||
axis.SetAllDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static double GetTick(double max)
|
||||
{
|
||||
var bigger = Math.Ceiling(Math.Abs(max));
|
||||
int n = 1;
|
||||
while (bigger / (Mathf.Pow(10, n)) > 10)
|
||||
{
|
||||
n++;
|
||||
}
|
||||
return Math.Pow(10, n);
|
||||
}
|
||||
|
||||
internal void CheckValueLabelActive(Axis axis, int i, ChartLabel label, Vector3 pos)
|
||||
{
|
||||
if (axis.IsValue())
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var dist = GetLabelPosition(0, 1).x - pos.x;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredWidth());
|
||||
}
|
||||
else if (i == axis.context.labelValueList.Count - 1)
|
||||
{
|
||||
var dist = pos.x - GetLabelPosition(0, i - 1).x;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredWidth());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var dist = GetLabelPosition(0, 1).y - pos.y;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredHeight());
|
||||
}
|
||||
else if (i == axis.context.labelValueList.Count - 1)
|
||||
{
|
||||
var dist = pos.y - GetLabelPosition(0, i - 1).y;
|
||||
label.SetLabelActive(dist > label.label.GetPreferredHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InitAxis(Axis axis, Axis relativedAxis, BaseChart chart, AxisHandler<T> handler,
|
||||
Orient orient, float axisStartX, float axisStartY, float axisLength, float relativedLength)
|
||||
{
|
||||
chart.InitAxisRuntimeData(axis);
|
||||
|
||||
var objName = ChartCached.GetComponentObjectName(axis);
|
||||
var axisObj = ChartHelper.AddObject(objName,
|
||||
chart.transform,
|
||||
chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor,
|
||||
chart.chartPivot,
|
||||
chart.chartSizeDelta);
|
||||
|
||||
axisObj.SetActive(axis.show);
|
||||
axisObj.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(axisObj);
|
||||
|
||||
axis.gameObject = axisObj;
|
||||
axis.context.labelObjectList.Clear();
|
||||
|
||||
if (!axis.show)
|
||||
return;
|
||||
|
||||
var axisLabelTextStyle = axis.axisLabel.textStyle;
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
var splitNumber = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
|
||||
var totalWidth = 0f;
|
||||
var eachWidth = AxisHelper.GetEachWidth(axis, axisLength, dataZoom);
|
||||
var gapWidth = axis.boundaryGap ? eachWidth / 2 : 0;
|
||||
|
||||
var textWidth = axis.axisLabel.width > 0
|
||||
? axis.axisLabel.width
|
||||
: (orient == Orient.Horizonal
|
||||
? AxisHelper.GetScaleWidth(axis, axisLength, 0, dataZoom)
|
||||
: (axisStartX - chart.chartX)
|
||||
);
|
||||
|
||||
var textHeight = axis.axisLabel.height > 0
|
||||
? axis.axisLabel.height
|
||||
: 20f;
|
||||
|
||||
if (axis.IsCategory() && axis.boundaryGap)
|
||||
{
|
||||
splitNumber -= 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
ChartLabel label;
|
||||
|
||||
var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
|
||||
var inside = axis.axisLabel.inside;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
|
||||
var labelName = AxisHelper.GetLabelName(axis, axisLength, i,
|
||||
axis.context.minValue,
|
||||
axis.context.maxValue,
|
||||
dataZoom, isPercentStack);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((inside && axis.IsLeft()) || (!inside && axis.IsRight()))
|
||||
{
|
||||
label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
Vector2.zero,
|
||||
Vector2.zero,
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName);
|
||||
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleLeft));
|
||||
}
|
||||
else
|
||||
{
|
||||
label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
Vector2.zero,
|
||||
Vector2.zero,
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName);
|
||||
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
axis.axisLabel.SetRelatedText(label.label, labelWidth);
|
||||
|
||||
var pos = handler.GetLabelPosition(totalWidth + gapWidth, i);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.IsRight())
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleLeft));
|
||||
else
|
||||
label.label.SetAlignment(axisLabelTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
}
|
||||
|
||||
label.SetPosition(pos);
|
||||
handler.CheckValueLabelActive(axis, i, label, pos);
|
||||
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalWidth += labelWidth;
|
||||
}
|
||||
if (axis.axisName.show)
|
||||
{
|
||||
ChartText axisName = null;
|
||||
|
||||
var axisNameTextStyle = axis.axisName.textStyle;
|
||||
var offset = axisNameTextStyle.offset;
|
||||
|
||||
var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.yOffset);
|
||||
var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
switch (axis.axisName.location)
|
||||
{
|
||||
case AxisName.Location.Start:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform,
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(1, 0.5f),
|
||||
new Vector2(100, 20),
|
||||
axisNameTextStyle, chart.theme.axis);
|
||||
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Top
|
||||
? new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset)
|
||||
: new Vector2(zeroPos.x - offset.x, zeroPos.y + offset.y + axis.offset));
|
||||
break;
|
||||
|
||||
case AxisName.Location.Middle:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform,
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f),
|
||||
new Vector2(100, 20),
|
||||
axisNameTextStyle, chart.theme.axis);
|
||||
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Top
|
||||
? new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY + relativedLength - offset.y + axis.offset)
|
||||
: new Vector2(axisStartX + axisLength / 2 + offset.x, axisStartY - offset.y + axis.offset));
|
||||
break;
|
||||
|
||||
case AxisName.Location.End:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform,
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(0, 0.5f),
|
||||
new Vector2(100, 20),
|
||||
axisNameTextStyle, chart.theme.axis);
|
||||
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleLeft));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Top
|
||||
? new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset)
|
||||
: new Vector2(axisStartX + axisLength + offset.x, zeroPos.y + offset.y + axis.offset));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (axis.axisName.location)
|
||||
{
|
||||
case AxisName.Location.Start:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), axisNameTextStyle,
|
||||
chart.theme.axis);
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) :
|
||||
new Vector2(zeroPos.x + offset.x + axis.offset, axisStartY - offset.y));
|
||||
break;
|
||||
|
||||
case AxisName.Location.Middle:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, new Vector2(1, 0.5f),
|
||||
new Vector2(1, 0.5f), new Vector2(1, 0.5f), new Vector2(100, 20), axisNameTextStyle,
|
||||
chart.theme.axis);
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleRight));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) :
|
||||
new Vector2(axisStartX - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y));
|
||||
break;
|
||||
|
||||
case AxisName.Location.End:
|
||||
|
||||
axisName = ChartHelper.AddTextObject(s_DefaultAxisName, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100, 20), axisNameTextStyle,
|
||||
chart.theme.axis);
|
||||
axisName.SetAlignment(axisNameTextStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
axisName.SetLocalPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) :
|
||||
new Vector2(zeroPos.x + offset.x + axis.offset, axisStartY + axisLength + offset.y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
axisName.SetText(axis.axisName.name);
|
||||
}
|
||||
}
|
||||
|
||||
internal static Vector3 GetLabelPosition(int i, Orient orient, Axis axis, Axis relativedAxis, AxisTheme theme,
|
||||
float scaleWid, float axisStartX, float axisStartY, float axisLength, float relativedLength)
|
||||
{
|
||||
var inside = axis.axisLabel.inside;
|
||||
var fontSize = axis.axisLabel.textStyle.GetFontSize(theme);
|
||||
var current = axis.offset;
|
||||
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
scaleWid = axis.context.minMaxRange != 0
|
||||
? axis.GetDistance(axis.GetLabelValue(i), axisLength)
|
||||
: 0;
|
||||
}
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (axis.axisLabel.onZero && relativedAxis != null)
|
||||
axisStartY += relativedAxis.context.yOffset;
|
||||
|
||||
if (axis.IsTop())
|
||||
axisStartY += relativedLength;
|
||||
|
||||
if ((inside && axis.IsBottom()) || (!inside && axis.IsTop()))
|
||||
current += axisStartY + axis.axisLabel.margin + fontSize / 2;
|
||||
else
|
||||
current += axisStartY - axis.axisLabel.margin - fontSize / 2;
|
||||
|
||||
return new Vector3(axisStartX + scaleWid, current) + axis.axisLabel.textStyle.offsetv3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.axisLabel.onZero && relativedAxis != null)
|
||||
axisStartX += relativedAxis.context.yOffset;
|
||||
|
||||
if (axis.IsRight())
|
||||
axisStartX += relativedLength;
|
||||
|
||||
if ((inside && axis.IsLeft()) || (!inside && axis.IsRight()))
|
||||
current += axisStartX + axis.axisLabel.margin;
|
||||
else
|
||||
current += axisStartX - axis.axisLabel.margin;
|
||||
|
||||
return new Vector3(current, axisStartY + scaleWid) + axis.axisLabel.textStyle.offsetv3;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawAxisLine(VertexHelper vh, Axis axis, AxisTheme theme, Orient orient,
|
||||
float startX, float startY, float axisLength)
|
||||
{
|
||||
var inverse = axis.IsValue() && axis.inverse;
|
||||
var offset = AxisHelper.GetAxisLineArrowOffset(axis);
|
||||
|
||||
var lineWidth = axis.axisLine.GetWidth(theme.lineWidth);
|
||||
var lineType = axis.axisLine.GetType(theme.lineType);
|
||||
var lineColor = axis.axisLine.GetColor(theme.lineColor);
|
||||
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
var left = new Vector3(startX - lineWidth - (inverse ? offset : 0), startY);
|
||||
var right = new Vector3(startX + axisLength + lineWidth + (!inverse ? offset : 0), startY);
|
||||
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, left, right, lineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var bottom = new Vector3(startX, startY - lineWidth - (inverse ? offset : 0));
|
||||
var top = new Vector3(startX, startY + axisLength + lineWidth + (!inverse ? offset : 0));
|
||||
ChartDrawer.DrawLineStyle(vh, lineType, lineWidth, bottom, top, lineColor);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawAxisTick(VertexHelper vh, Axis axis, AxisTheme theme, DataZoom dataZoom,
|
||||
Orient orient, float startX, float startY, float axisLength)
|
||||
{
|
||||
var lineWidth = axis.axisLine.GetWidth(theme.lineWidth);
|
||||
var tickLength = axis.axisTick.GetLength(theme.tickLength);
|
||||
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
|
||||
|
||||
var current = orient == Orient.Horizonal
|
||||
? startX
|
||||
: startY;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
|
||||
if (i == 0 && (!axis.axisTick.showStartTick || axis.axisTick.alignWithLabel))
|
||||
{
|
||||
current += scaleWidth;
|
||||
continue;
|
||||
}
|
||||
if (i == size - 1 && !axis.axisTick.showEndTick)
|
||||
{
|
||||
current += scaleWidth;
|
||||
continue;
|
||||
}
|
||||
if (axis.axisTick.show)
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
float pX = axis.IsTime()
|
||||
? (startX + axis.GetDistance(axis.GetLabelValue(i), axisLength))
|
||||
: current;
|
||||
|
||||
if (axis.boundaryGap && axis.axisTick.alignWithLabel)
|
||||
pX -= scaleWidth / 2;
|
||||
|
||||
var sY = 0f;
|
||||
var eY = 0f;
|
||||
if ((axis.axisTick.inside && axis.IsBottom())
|
||||
|| (!axis.axisTick.inside && axis.IsTop()))
|
||||
{
|
||||
sY = startY + axis.offset + lineWidth;
|
||||
eY = sY + tickLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
sY = startY + axis.offset - lineWidth;
|
||||
eY = sY - tickLength;
|
||||
}
|
||||
|
||||
UGL.DrawLine(vh, new Vector3(pX, sY), new Vector3(pX, eY),
|
||||
axis.axisTick.GetWidth(theme.tickWidth),
|
||||
axis.axisTick.GetColor(theme.tickColor));
|
||||
}
|
||||
else
|
||||
{
|
||||
float pY = axis.IsTime()
|
||||
? (startY + axis.GetDistance(axis.GetLabelValue(i), axisLength))
|
||||
: current;
|
||||
|
||||
if (axis.boundaryGap && axis.axisTick.alignWithLabel)
|
||||
pY -= scaleWidth / 2;
|
||||
|
||||
var sX = 0f;
|
||||
var eX = 0f;
|
||||
if ((axis.axisTick.inside && axis.IsLeft())
|
||||
|| (!axis.axisTick.inside && axis.IsRight()))
|
||||
{
|
||||
sX = startX + axis.offset + lineWidth;
|
||||
eX = sX + tickLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
sX = startX + axis.offset - lineWidth;
|
||||
eX = sX - tickLength;
|
||||
}
|
||||
|
||||
UGL.DrawLine(vh, new Vector3(sX, pY), new Vector3(eX, pY),
|
||||
axis.axisTick.GetWidth(theme.tickWidth),
|
||||
axis.axisTick.GetColor(theme.tickColor));
|
||||
}
|
||||
}
|
||||
current += scaleWidth;
|
||||
}
|
||||
}
|
||||
if (axis.show && axis.axisLine.show && axis.axisLine.showArrow)
|
||||
{
|
||||
var lineY = startY + axis.offset;
|
||||
var inverse = axis.IsValue() && axis.inverse;
|
||||
var axisArrow = axis.axisLine.arrow;
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (inverse)
|
||||
{
|
||||
var startPos = new Vector3(startX + axisLength, lineY);
|
||||
var arrowPos = new Vector3(startX, lineY);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var arrowPosX = startX + axisLength + lineWidth;
|
||||
var startPos = new Vector3(startX, lineY);
|
||||
var arrowPos = new Vector3(arrowPosX, lineY);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inverse)
|
||||
{
|
||||
var startPos = new Vector3(startX, startY + axisLength);
|
||||
var arrowPos = new Vector3(startX, startY);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
else
|
||||
{
|
||||
var startPos = new Vector3(startX, startY);
|
||||
var arrowPos = new Vector3(startX, startY + axisLength + lineWidth);
|
||||
UGL.DrawArrow(vh, startPos, arrowPos, axisArrow.width, axisArrow.height,
|
||||
axisArrow.offset, axisArrow.dent,
|
||||
axisArrow.GetColor(axis.axisLine.GetColor(theme.lineColor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void DrawAxisSplit(VertexHelper vh, Axis axis, AxisTheme theme, DataZoom dataZoom,
|
||||
Orient orient, float startX, float startY, float axisLength, float splitLength)
|
||||
{
|
||||
var lineColor = axis.splitLine.GetColor(theme.splitLineColor);
|
||||
var lineWidth = axis.splitLine.GetWidth(theme.lineWidth);
|
||||
var lineType = axis.splitLine.GetType(theme.splitLineType);
|
||||
|
||||
var size = AxisHelper.GetScaleNumber(axis, axisLength, dataZoom);
|
||||
if (axis.IsTime())
|
||||
{
|
||||
size += 1;
|
||||
if (!ChartHelper.IsEquals(axis.GetLastLabelValue(), axis.context.maxValue))
|
||||
size += 1;
|
||||
}
|
||||
|
||||
var current = orient == Orient.Horizonal
|
||||
? startX
|
||||
: startY;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(axis, axisLength, axis.IsTime() ? i : i + 1, dataZoom);
|
||||
|
||||
if (axis.boundaryGap && axis.axisTick.alignWithLabel)
|
||||
current -= scaleWidth / 2;
|
||||
|
||||
if (axis.splitArea.show && i <= size - 1)
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
UGL.DrawQuadrilateral(vh,
|
||||
new Vector2(current, startY),
|
||||
new Vector2(current, startY + splitLength),
|
||||
new Vector2(current + scaleWidth, startY + splitLength),
|
||||
new Vector2(current + scaleWidth, startY),
|
||||
axis.splitArea.GetColor(i, theme));
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawQuadrilateral(vh,
|
||||
new Vector2(startX, current),
|
||||
new Vector2(startX + splitLength, current),
|
||||
new Vector2(startX + splitLength, current + scaleWidth),
|
||||
new Vector2(startX, current + scaleWidth),
|
||||
axis.splitArea.GetColor(i, theme));
|
||||
}
|
||||
|
||||
}
|
||||
if (axis.splitLine.show)
|
||||
{
|
||||
if (axis.splitLine.NeedShow(i))
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
ChartDrawer.DrawLineStyle(vh,
|
||||
lineType,
|
||||
lineWidth,
|
||||
new Vector3(current, startY),
|
||||
new Vector3(current, startY + splitLength),
|
||||
lineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChartDrawer.DrawLineStyle(vh,
|
||||
lineType,
|
||||
lineWidth,
|
||||
new Vector3(startX, current),
|
||||
new Vector3(startX + splitLength, current),
|
||||
lineColor);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
current += scaleWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs.meta
Normal file
11
Assets/XCharts/Runtime/Component/Axis/AxisHandler.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0babef8a2708b4745bbb0a0648913a35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -16,7 +16,7 @@ namespace XCharts
|
||||
/// </summary>
|
||||
/// <param name="axis"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetAxisLineSymbolOffset(Axis axis)
|
||||
public static float GetAxisLineArrowOffset(Axis axis)
|
||||
{
|
||||
if (axis.axisLine.show && axis.axisLine.showArrow && axis.axisLine.arrow.offset > 0)
|
||||
{
|
||||
@@ -34,41 +34,11 @@ namespace XCharts
|
||||
{
|
||||
if (axis.type == Axis.AxisType.Value)
|
||||
{
|
||||
if (axis.interval > 0)
|
||||
{
|
||||
if (coordinateWid <= 0) return 0;
|
||||
int num = (int)(axis.runtimeMinMaxRange / axis.interval);
|
||||
int maxNum = Mathf.CeilToInt(coordinateWid / 15);
|
||||
if (num > maxNum)
|
||||
{
|
||||
axis.interval *= 2;
|
||||
num = (int)(axis.runtimeMinMaxRange / axis.interval);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
else
|
||||
{
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
}
|
||||
return axis.context.labelValueList.Count - 1;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
if (axis.interval > 0)
|
||||
{
|
||||
if (coordinateWid <= 0) return 0;
|
||||
int num = (int)(axis.runtimeMinMaxRange / axis.interval);
|
||||
int maxNum = Mathf.CeilToInt(coordinateWid / 15);
|
||||
if (num > maxNum)
|
||||
{
|
||||
axis.interval *= 2;
|
||||
num = (int)(axis.runtimeMinMaxRange / axis.interval);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
else
|
||||
{
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
}
|
||||
return axis.context.labelValueList.Count;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
@@ -78,12 +48,16 @@ namespace XCharts
|
||||
{
|
||||
int dataCount = axis.GetDataList(dataZoom).Count;
|
||||
if (!axis.boundaryGap)
|
||||
{
|
||||
dataCount -= 1;
|
||||
}
|
||||
if (axis.splitNumber <= 0 || axis.splitNumber > dataCount) return dataCount;
|
||||
if (dataCount >= axis.splitNumber * 2) return axis.splitNumber;
|
||||
else return dataCount;
|
||||
if (dataCount <= 0)
|
||||
dataCount = 1;
|
||||
|
||||
if (axis.splitNumber <= 0 || axis.splitNumber > dataCount)
|
||||
return dataCount;
|
||||
if (dataCount >= axis.splitNumber * 2)
|
||||
return axis.splitNumber;
|
||||
else
|
||||
return dataCount;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -96,11 +70,14 @@ namespace XCharts
|
||||
/// <returns></returns>
|
||||
public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
|
||||
{
|
||||
if (dataCount < 1) dataCount = 1;
|
||||
var categoryCount = axis.GetDataNumber(dataZoom);
|
||||
if (dataCount < 1)
|
||||
dataCount = 1;
|
||||
var categoryCount = axis.GetDataCount(dataZoom);
|
||||
int segment = (axis.boundaryGap ? categoryCount : categoryCount - 1);
|
||||
segment = segment <= 0 ? dataCount : segment;
|
||||
if (segment <= 0) segment = 1;
|
||||
if (segment <= 0)
|
||||
segment = 1;
|
||||
|
||||
return coordinateWidth / segment;
|
||||
}
|
||||
|
||||
@@ -121,30 +98,26 @@ namespace XCharts
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
maxValue = axis.max != 0 ? axis.max : 1;
|
||||
double value = 0;
|
||||
if (forcePercent) maxValue = 100;
|
||||
if (axis.interval > 0)
|
||||
{
|
||||
if (index == split) value = maxValue;
|
||||
else value = minValue + index * axis.interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = minValue + (maxValue - minValue) * index / split;
|
||||
if (!axis.clockwise && value != minValue) value = maxValue - value;
|
||||
}
|
||||
if (forcePercent)
|
||||
maxValue = 100;
|
||||
|
||||
value = axis.GetLabelValue(index);
|
||||
if (axis.inverse)
|
||||
{
|
||||
value = -value;
|
||||
minValue = -minValue;
|
||||
maxValue = -maxValue;
|
||||
}
|
||||
if (forcePercent) return string.Format("{0}%", (int)value);
|
||||
else return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue);
|
||||
if (forcePercent)
|
||||
return string.Format("{0}%", (int)value);
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue);
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
float value = axis.logBaseE ? Mathf.Exp(axis.runtimeMinLogIndex + index) :
|
||||
Mathf.Pow(axis.logBase, axis.runtimeMinLogIndex + index);
|
||||
float value = axis.logBaseE
|
||||
? Mathf.Exp(axis.GetLogMinIndex() + index)
|
||||
: Mathf.Pow(axis.logBase, axis.GetLogMinIndex() + index);
|
||||
if (axis.inverse)
|
||||
{
|
||||
value = -value;
|
||||
@@ -155,22 +128,18 @@ namespace XCharts
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
if (minValue == 0 && maxValue == 0) return string.Empty;
|
||||
double value = 0;
|
||||
if (axis.interval > 0)
|
||||
{
|
||||
if (index == split) value = maxValue;
|
||||
else value = minValue + index * axis.interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = minValue + (maxValue - minValue) * index / split;
|
||||
}
|
||||
return axis.axisLabel.GetFormatterDateTime(index, value);
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
return string.Empty;
|
||||
if (index > axis.context.labelValueList.Count - 1)
|
||||
return string.Empty;
|
||||
|
||||
var value = axis.GetLabelValue(index);
|
||||
return axis.axisLabel.GetFormatterDateTime(index, value, minValue, maxValue);
|
||||
}
|
||||
var showData = axis.GetDataList(dataZoom);
|
||||
int dataCount = showData.Count;
|
||||
if (dataCount <= 0) return "";
|
||||
if (dataCount <= 0)
|
||||
return "";
|
||||
int rate = axis.boundaryGap ? (dataCount / split) : (dataCount - 1) / split;
|
||||
if (rate == 0) rate = 1;
|
||||
if (axis.insertDataToHead)
|
||||
@@ -179,13 +148,16 @@ namespace XCharts
|
||||
{
|
||||
var residue = (dataCount - 1) - split * rate;
|
||||
var newIndex = residue + (index - 1) * rate;
|
||||
if (newIndex < 0) newIndex = 0;
|
||||
if (newIndex < 0)
|
||||
newIndex = 0;
|
||||
return axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5) return string.Empty;
|
||||
else return axis.axisLabel.GetFormatterContent(0, showData[0]);
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5)
|
||||
return string.Empty;
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(0, showData[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -197,8 +169,10 @@ namespace XCharts
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5) return string.Empty;
|
||||
else return axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]);
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5)
|
||||
return string.Empty;
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -211,27 +185,30 @@ namespace XCharts
|
||||
public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
|
||||
{
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (splitNum == 0) return 0;
|
||||
if (splitNum == 0)
|
||||
return 0;
|
||||
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
var data = axis.GetDataList(dataZoom);
|
||||
var scaleNum = 0;
|
||||
|
||||
if (axis.boundaryGap)
|
||||
{
|
||||
scaleNum = data.Count % splitNum == 0 ? splitNum + 1 : splitNum + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data.Count < splitNum) scaleNum = splitNum;
|
||||
else scaleNum = data.Count % splitNum == 0 ? splitNum : splitNum + 1;
|
||||
if (data.Count < splitNum)
|
||||
scaleNum = splitNum;
|
||||
else
|
||||
scaleNum = data.Count % splitNum == 0 ? splitNum : splitNum + 1;
|
||||
}
|
||||
return scaleNum;
|
||||
}
|
||||
else if (axis.IsTime())
|
||||
return splitNum;
|
||||
else
|
||||
{
|
||||
return splitNum + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -242,21 +219,21 @@ namespace XCharts
|
||||
/// <returns></returns>
|
||||
public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
|
||||
{
|
||||
if (index < 0) return 0;
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
int num = GetScaleNumber(axis, coordinateWidth, dataZoom);
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (num <= 0) num = 1;
|
||||
if (axis.type == Axis.AxisType.Value && axis.interval > 0)
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
if (axis.runtimeMinMaxRange <= 0) return 0;
|
||||
if (index >= splitNum)
|
||||
{
|
||||
return (float)(coordinateWidth - (index - 1) * axis.interval * coordinateWidth / axis.runtimeMinMaxRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (float)(axis.interval * coordinateWidth / axis.runtimeMinMaxRange);
|
||||
}
|
||||
var value = axis.GetLabelValue(index);
|
||||
var lastValue = axis.GetLabelValue(index - 1);
|
||||
return axis.context.minMaxRange == 0
|
||||
? 0
|
||||
: (float)(coordinateWidth * (value - lastValue) / axis.context.minMaxRange);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -265,20 +242,26 @@ namespace XCharts
|
||||
{
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
int tick = count / splitNum;
|
||||
if (count <= 0) return 0;
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
var each = coordinateWidth / count;
|
||||
if (axis.insertDataToHead)
|
||||
{
|
||||
var max = axis.boundaryGap ? splitNum : splitNum - 1;
|
||||
if (index == 1)
|
||||
{
|
||||
if (axis.axisTick.alignWithLabel) return each * tick;
|
||||
else return coordinateWidth - each * tick * max;
|
||||
if (axis.axisTick.alignWithLabel)
|
||||
return each * tick;
|
||||
else
|
||||
return coordinateWidth - each * tick * max;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count < splitNum) return each;
|
||||
else return each * (count / splitNum);
|
||||
if (count < splitNum)
|
||||
return each;
|
||||
else
|
||||
return each * (count / splitNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -286,20 +269,26 @@ namespace XCharts
|
||||
var max = axis.boundaryGap ? num - 1 : num;
|
||||
if (index >= max)
|
||||
{
|
||||
if (axis.axisTick.alignWithLabel) return each * tick;
|
||||
else return coordinateWidth - each * tick * (index - 1);
|
||||
if (axis.axisTick.alignWithLabel)
|
||||
return each * tick;
|
||||
else
|
||||
return coordinateWidth - each * tick * (index - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count < splitNum) return each;
|
||||
else return each * (count / splitNum);
|
||||
if (count < splitNum)
|
||||
return each;
|
||||
else
|
||||
return each * (count / splitNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (splitNum <= 0) return 0;
|
||||
else return coordinateWidth / splitNum;
|
||||
if (splitNum <= 0)
|
||||
return 0;
|
||||
else
|
||||
return coordinateWidth / splitNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -335,7 +324,10 @@ namespace XCharts
|
||||
axis.splitNumber = (minSplit > 0 && maxSplit > 0) ? (maxSplit + minSplit - 1) : (maxSplit + minSplit);
|
||||
return;
|
||||
}
|
||||
if (axis.minMaxType == Axis.AxisMinMaxType.Custom)
|
||||
if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
}
|
||||
else if (axis.minMaxType == Axis.AxisMinMaxType.Custom)
|
||||
{
|
||||
if (axis.min != 0 || axis.max != 0)
|
||||
{
|
||||
@@ -357,6 +349,7 @@ namespace XCharts
|
||||
switch (axis.minMaxType)
|
||||
{
|
||||
case Axis.AxisMinMaxType.Default:
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
{
|
||||
}
|
||||
@@ -376,28 +369,24 @@ namespace XCharts
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
break;
|
||||
|
||||
case Axis.AxisMinMaxType.MinMax:
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
|
||||
minValue = ceilRate != 0 ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = ceilRate != 0 ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
double tempRange = maxValue - minValue;
|
||||
if (axis.runtimeMinMaxRange != tempRange)
|
||||
{
|
||||
axis.runtimeMinMaxRange = tempRange;
|
||||
if (axis.type == Axis.AxisType.Value && axis.interval > 0)
|
||||
{
|
||||
axis.SetComponentDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool NeedShowSplit(Axis axis)
|
||||
{
|
||||
if (!axis.show) return false;
|
||||
if (axis.IsCategory() && axis.GetDataList().Count <= 0) return false;
|
||||
else return true;
|
||||
if (!axis.show)
|
||||
return false;
|
||||
if (axis.IsCategory() && axis.GetDataList().Count <= 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void AdjustCircleLabelPos(ChartText txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
|
||||
@@ -466,22 +455,22 @@ namespace XCharts
|
||||
txt.SetLocalPosition(pos);
|
||||
}
|
||||
|
||||
public static float GetAxisPosition(Grid grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
|
||||
public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
|
||||
{
|
||||
var gridHeight = axis is YAxis ? grid.runtimeHeight : grid.runtimeWidth;
|
||||
var gridXY = axis is YAxis ? grid.runtimeY : grid.runtimeX;
|
||||
var gridHeight = axis is YAxis ? grid.context.height : grid.context.width;
|
||||
var gridXY = axis is YAxis ? grid.context.y : grid.context.x;
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
if (dataCount == 0) dataCount = axis.data.Count;
|
||||
var categoryIndex = (int)value;
|
||||
var scaleWid = AxisHelper.GetDataWidth(axis, grid.runtimeHeight, dataCount, dataZoom);
|
||||
var scaleWid = AxisHelper.GetDataWidth(axis, gridHeight, dataCount, dataZoom);
|
||||
float startY = gridXY + (axis.boundaryGap ? scaleWid / 2 : 0);
|
||||
return startY + scaleWid * categoryIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
var yDataHig = (axis.runtimeMinMaxRange == 0) ? 0f :
|
||||
(float)((value - axis.runtimeMinValue) / axis.runtimeMinMaxRange * gridHeight);
|
||||
var yDataHig = (axis.context.minMaxRange == 0) ? 0f :
|
||||
(float)((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
|
||||
return gridXY + yDataHig;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca154a2444b924ff98ce6091280227c8
|
||||
guid: 566e3426780cc4339a1fb92d9604d21f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -16,7 +16,7 @@ namespace XCharts
|
||||
/// 坐标轴刻度标签的相关设置。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisLabel : SubComponent
|
||||
public class AxisLabel : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private string m_Formatter;
|
||||
@@ -236,7 +236,9 @@ namespace XCharts
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, 0, category);
|
||||
}
|
||||
if (string.IsNullOrEmpty(category)) return category;
|
||||
if (string.IsNullOrEmpty(category))
|
||||
return category;
|
||||
|
||||
if (string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
return m_TextLimit.GetLimitContent(category);
|
||||
@@ -283,7 +285,7 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFormatterDateTime(int labelIndex, double value)
|
||||
public string GetFormatterDateTime(int labelIndex, double value, double minValue, double maxValue)
|
||||
{
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
@@ -291,17 +293,24 @@ namespace XCharts
|
||||
}
|
||||
var timestamp = (int)value;
|
||||
var dateTime = DateTimeUtil.GetDateTime(timestamp);
|
||||
var format = string.IsNullOrEmpty(numericFormatter) ? "yyyy/M/d" : numericFormatter;
|
||||
var dateString = string.Empty;
|
||||
if (string.IsNullOrEmpty(numericFormatter))
|
||||
{
|
||||
dateString = DateTimeUtil.GetDateTimeFormatString(dateTime, maxValue - minValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
dateString = dateTime.ToString(numericFormatter);
|
||||
}
|
||||
if (!string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, dateTime.ToString(format));
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, dateString);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = dateTime.ToString(format);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
return m_TextLimit.GetLimitContent(dateString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 867b1c4fd101c43f79a82de245e9c1d2
|
||||
guid: 051f9473d1beb4e0bb35aa1600cb44bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -18,7 +18,7 @@ namespace XCharts
|
||||
{
|
||||
[SerializeField] private bool m_OnZero;
|
||||
[SerializeField] private bool m_ShowArrow;
|
||||
[SerializeField] private Arrow m_Arrow = new Arrow();
|
||||
[SerializeField] private ArrowStyle m_Arrow = new ArrowStyle();
|
||||
|
||||
/// <summary>
|
||||
/// When mutiple axes exists, this option can be used to specify which axis can be "onZero" to.
|
||||
@@ -42,7 +42,7 @@ namespace XCharts
|
||||
/// the arrow of line.
|
||||
/// 轴线箭头。
|
||||
/// </summary>
|
||||
public Arrow arrow
|
||||
public ArrowStyle arrow
|
||||
{
|
||||
get { return m_Arrow; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Arrow, value)) SetVerticesDirty(); }
|
||||
@@ -56,7 +56,7 @@ namespace XCharts
|
||||
m_Show = true,
|
||||
m_OnZero = true,
|
||||
m_ShowArrow = false,
|
||||
m_Arrow = new Arrow(),
|
||||
m_Arrow = new ArrowStyle(),
|
||||
m_LineStyle = new LineStyle(LineStyle.Type.None),
|
||||
};
|
||||
return axisLine;
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dee861621714d43519f0f1581e027a57
|
||||
guid: 2748c2a8789724709aa76f6056eb708d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -15,7 +15,7 @@ namespace XCharts
|
||||
/// 坐标轴名称。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisName : SubComponent
|
||||
public class AxisName : ChildComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// the location of axis name.
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f354d1d9b4e841c1b0068bf656b28c7
|
||||
guid: 878555ba3c6b1479f94f38185700531e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -16,7 +16,7 @@ namespace XCharts
|
||||
/// 坐标轴在 grid 区域中的分隔区域,默认不显示。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisSplitArea : SubComponent
|
||||
public class AxisSplitArea : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private List<Color32> m_Color;
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e3ad5d1729154c73b47342a46f0d3b5
|
||||
guid: 18702fd7797054670af64546b7304bb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 62c6ea03f6ffe431a9c4730cce152c80
|
||||
guid: 3da942a7a6bea44e2998ed993c0641ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9cff8225584c4d9492c252c09977060
|
||||
guid: 60278762ed892450d85e27b7df8f997e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e4276d289bef4136b22e6cc8b207d99
|
||||
guid: 24693180b2a2e41b2ab4025b2bbebf01
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
@@ -0,0 +1,40 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(ParallelCoord))]
|
||||
[ComponentHandler(typeof(ParallelAxisHander), true)]
|
||||
public class ParallelAxis : Axis
|
||||
{
|
||||
public new ParallelAxisContext context = new ParallelAxisContext();
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Category;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = true;
|
||||
m_Position = AxisPosition.Bottom;
|
||||
m_Offset = 0;
|
||||
m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
m_Icons = new List<Sprite>(5);
|
||||
splitLine.show = false;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7bc01c54f4d6485389fd57c37810c74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class ParallelAxisContext : AxisContext, IRectContext
|
||||
{
|
||||
internal ParallelCoord parallel { get; set; }
|
||||
internal Orient orient { get; set; }
|
||||
public float x { get; internal set; }
|
||||
public float y { get; internal set; }
|
||||
public float width { get; internal set; }
|
||||
public float height { get; internal set; }
|
||||
public Vector3 position { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b92542e13620d417d819e8573b430dc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,169 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class ParallelAxisHander : AxisHandler<ParallelAxis>
|
||||
{
|
||||
private Orient m_Orient;
|
||||
protected override Orient orient { get { return m_Orient; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitParallelAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateContext(component);
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
//UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
UpdateContext(component);
|
||||
DrawParallelAxisSplit(vh, component);
|
||||
DrawParallelAxisLine(vh, component);
|
||||
DrawParallelAxisTick(vh, component);
|
||||
}
|
||||
|
||||
private void UpdateContext(ParallelAxis axis)
|
||||
{
|
||||
var parallel = chart.GetChartComponent<ParallelCoord>(axis.parallelIndex);
|
||||
if (parallel == null)
|
||||
return;
|
||||
|
||||
m_Orient = parallel.orient;
|
||||
axis.context.parallel = parallel;
|
||||
var axisCount = chart.GetChartComponentNum<ParallelAxis>();
|
||||
|
||||
if (m_Orient == Orient.Horizonal)
|
||||
{
|
||||
var each = parallel.context.height / (axisCount - 1);
|
||||
axis.context.x = parallel.context.x;
|
||||
axis.context.y = parallel.context.y + (axis.index) * each;
|
||||
axis.context.width = parallel.context.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
var each = parallel.context.width / (axisCount - 1);
|
||||
axis.context.x = parallel.context.x + (axis.index) * each;
|
||||
axis.context.y = parallel.context.y;
|
||||
axis.context.width = parallel.context.height;
|
||||
}
|
||||
axis.context.orient = m_Orient;
|
||||
axis.context.height = 0;
|
||||
axis.context.position = new Vector3(axis.context.x, axis.context.y);
|
||||
}
|
||||
|
||||
private void InitParallelAxis(ParallelAxis axis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var xAxisIndex = axis.index;
|
||||
axis.painter = chart.painter;
|
||||
axis.refreshComponent = delegate ()
|
||||
{
|
||||
UpdateContext(axis);
|
||||
InitAxis(axis, null, chart, this,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
};
|
||||
axis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(component, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
if (component.context.parallel == null)
|
||||
return Vector3.zero;
|
||||
|
||||
return GetLabelPosition(i, m_Orient, component, null,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
component.context.x,
|
||||
component.context.y,
|
||||
component.context.width,
|
||||
component.context.height);
|
||||
}
|
||||
|
||||
private void DrawParallelAxisSplit(VertexHelper vh, ParallelAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
if (axis.context.parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
DrawAxisSplit(vh, axis, chart.theme.axis, dataZoom,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawParallelAxisTick(VertexHelper vh, ParallelAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
if (axis.context.parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
DrawAxisTick(vh, axis, chart.theme.axis, dataZoom,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawParallelAxisLine(VertexHelper vh, ParallelAxis axis)
|
||||
{
|
||||
if (axis.show && axis.axisLine.show)
|
||||
{
|
||||
if (axis.context.parallel == null)
|
||||
return;
|
||||
|
||||
DrawAxisLine(vh, axis,
|
||||
chart.theme.axis,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26ab25bf702c54ad38461c91ba1451af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XCharts/Runtime/Component/Axis/RadiusAxis.meta
Normal file
8
Assets/XCharts/Runtime/Component/Axis/RadiusAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c8971958a94d47e68f7ebdff5872b71
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Radial axis of polar coordinate.
|
||||
/// 极坐标系的径向轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(RadiusAxisHandler), true)]
|
||||
public class RadiusAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 5;
|
||||
m_BoundaryGap = false;
|
||||
m_Data = new List<string>(5);
|
||||
splitLine.show = true;
|
||||
splitLine.lineStyle.type = LineStyle.Type.Solid;
|
||||
axisLabel.textLimit.enable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6429398a27934726ba49d387d681728
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,168 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class RadiusAxisHandler : MainComponentHandler<RadiusAxis>
|
||||
{
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitRadiusAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawRadiusAxis(vh, component);
|
||||
}
|
||||
|
||||
private void UpdateAxisMinMaxValue(RadiusAxis axis, bool updateChart = true)
|
||||
{
|
||||
if (axis.IsCategory() || !axis.show) return;
|
||||
double tempMinValue = 0;
|
||||
double tempMaxValue = 0;
|
||||
SeriesHelper.GetXMinMaxValue(chart.series, null, axis.polarIndex, true, axis.inverse, out tempMinValue,
|
||||
out tempMaxValue, true);
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue)
|
||||
{
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisLabelText(RadiusAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
axis.UpdateLabelText(polar.context.radius, null, false, 500);
|
||||
}
|
||||
|
||||
private void InitRadiusAxis(RadiusAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.index);
|
||||
if (polar == null)
|
||||
return;
|
||||
|
||||
var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index);
|
||||
if (angleAxis == null)
|
||||
return;
|
||||
|
||||
PolarHelper.UpdatePolarCenter(polar, chart.chartPosition, chart.chartWidth, chart.chartHeight);
|
||||
axis.context.labelObjectList.Clear();
|
||||
var radius = polar.context.radius;
|
||||
var objName = "axis_radius" + axis.index;
|
||||
var axisObj = ChartHelper.AddObject(objName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
axisObj.transform.localPosition = Vector3.zero;
|
||||
axisObj.SetActive(axis.show && axis.axisLabel.show);
|
||||
axisObj.hideFlags = chart.chartHideFlags;
|
||||
ChartHelper.HideAllObject(axisObj);
|
||||
var textStyle = axis.axisLabel.textStyle;
|
||||
var splitNumber = AxisHelper.GetSplitNumber(axis, radius, null);
|
||||
var totalWidth = 0f;
|
||||
var startAngle = angleAxis.startAngle;
|
||||
var cenPos = polar.context.center;
|
||||
var txtHig = textStyle.GetFontSize(chart.theme.axis) + 2;
|
||||
var dire = ChartHelper.GetDire(startAngle, true).normalized;
|
||||
var tickWidth = axis.axisTick.GetLength(chart.theme.axis.tickWidth);
|
||||
var tickVector = ChartHelper.GetVertialDire(dire)
|
||||
* (tickWidth + axis.axisLabel.margin);
|
||||
for (int i = 0; i <= splitNumber; i++)
|
||||
{
|
||||
var labelWidth = AxisHelper.GetScaleWidth(axis, radius, i, null);
|
||||
var inside = axis.axisLabel.inside;
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
var labelName = AxisHelper.GetLabelName(axis, radius, i, axis.context.minValue, axis.context.maxValue,
|
||||
null, isPercentStack);
|
||||
var label = ChartHelper.AddAxisLabelObject(splitNumber, i, objName + i, axisObj.transform, new Vector2(0.5f, 0.5f),
|
||||
new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(labelWidth, txtHig), axis, chart.theme.axis,
|
||||
labelName);
|
||||
|
||||
if (i == 0)
|
||||
axis.axisLabel.SetRelatedText(label.label, labelWidth);
|
||||
|
||||
label.label.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
label.SetText(labelName);
|
||||
label.SetPosition(ChartHelper.GetPos(cenPos, totalWidth, startAngle, true) + tickVector);
|
||||
label.SetActive(true);
|
||||
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalWidth += labelWidth;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRadiusAxis(VertexHelper vh, RadiusAxis radiusAxis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(radiusAxis.polarIndex);
|
||||
if (polar == null)
|
||||
return;
|
||||
|
||||
var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index);
|
||||
if (angleAxis == null)
|
||||
return;
|
||||
|
||||
var startAngle = angleAxis.startAngle;
|
||||
var radius = polar.context.radius;
|
||||
var cenPos = polar.context.center;
|
||||
var size = AxisHelper.GetScaleNumber(radiusAxis, radius, null);
|
||||
var totalWidth = 0f;
|
||||
var dire = ChartHelper.GetDire(startAngle, true).normalized;
|
||||
var tickWidth = radiusAxis.axisTick.GetLength(chart.theme.axis.tickWidth);
|
||||
var tickLength = radiusAxis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
var tickVetor = ChartHelper.GetVertialDire(dire) * tickLength;
|
||||
for (int i = 0; i < size - 1; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i);
|
||||
var pos = ChartHelper.GetPos(cenPos, totalWidth, startAngle, true);
|
||||
if (radiusAxis.show && radiusAxis.splitLine.show)
|
||||
{
|
||||
var outsideRaidus = totalWidth + radiusAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth) * 2;
|
||||
var splitLineColor = radiusAxis.splitLine.GetColor(chart.theme.axis.splitLineColor);
|
||||
UGL.DrawDoughnut(vh, cenPos, totalWidth, outsideRaidus, splitLineColor, Color.clear);
|
||||
}
|
||||
if (radiusAxis.show && radiusAxis.axisTick.show)
|
||||
{
|
||||
UGL.DrawLine(vh, pos, pos + tickVetor, tickWidth, chart.theme.axis.lineColor);
|
||||
}
|
||||
totalWidth += scaleWidth;
|
||||
}
|
||||
if (radiusAxis.show && radiusAxis.axisLine.show)
|
||||
{
|
||||
var lineStartPos = polar.context.center - dire * tickWidth;
|
||||
var lineEndPos = polar.context.center + dire * (radius + tickWidth);
|
||||
var lineWidth = radiusAxis.axisLine.GetWidth(chart.theme.axis.lineWidth);
|
||||
UGL.DrawLine(vh, lineStartPos, lineEndPos, lineWidth, chart.theme.axis.lineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f2cb79bfe30c4f14a3117f9f30ed3bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XCharts/Runtime/Component/Axis/SingleAxis.meta
Normal file
8
Assets/XCharts/Runtime/Component/Axis/SingleAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17498717d39c14b43a91c67401407410
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
154
Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs
Normal file
154
Assets/XCharts/Runtime/Component/Axis/SingleAxis/SingleAxis.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Single axis.
|
||||
/// 单轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[ComponentHandler(typeof(SingleAxisHander), true)]
|
||||
public class SingleAxis : Axis, IUpdateRuntimeData
|
||||
{
|
||||
[SerializeField] protected Orient m_Orient = Orient.Horizonal;
|
||||
[SerializeField] private float m_Left = 0.1f;
|
||||
[SerializeField] private float m_Right = 0.1f;
|
||||
[SerializeField] private float m_Top = 0f;
|
||||
[SerializeField] private float m_Bottom = 0.2f;
|
||||
[SerializeField] private float m_Width = 0;
|
||||
[SerializeField] private float m_Height = 50;
|
||||
|
||||
public new SingleAxisContext context = new SingleAxisContext();
|
||||
|
||||
/// <summary>
|
||||
/// Orientation of the axis. By default, it's 'Horizontal'. You can set it to be 'Vertical' to make a vertical axis.
|
||||
/// 坐标轴朝向。默认为水平朝向。
|
||||
/// </summary>
|
||||
public Orient orient
|
||||
{
|
||||
get { return m_Orient; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Orient, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the left side of the container.
|
||||
/// 组件离容器左侧的距离。
|
||||
/// </summary>
|
||||
public float left
|
||||
{
|
||||
get { return m_Left; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Left, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the right side of the container.
|
||||
/// 组件离容器右侧的距离。
|
||||
/// </summary>
|
||||
public float right
|
||||
{
|
||||
get { return m_Right; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Right, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the top side of the container.
|
||||
/// 组件离容器上侧的距离。
|
||||
/// </summary>
|
||||
public float top
|
||||
{
|
||||
get { return m_Top; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Top, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Distance between component and the bottom side of the container.
|
||||
/// 组件离容器下侧的距离。
|
||||
/// </summary>
|
||||
public float bottom
|
||||
{
|
||||
get { return m_Bottom; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Bottom, value)) SetAllDirty(); }
|
||||
}
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); }
|
||||
}
|
||||
public float height
|
||||
{
|
||||
get { return m_Height; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public void UpdateRuntimeData(float chartX, float chartY, float chartWidth, float chartHeight)
|
||||
{
|
||||
context.left = left <= 1 ? left * chartWidth : left;
|
||||
context.bottom = bottom <= 1 ? bottom * chartHeight : bottom;
|
||||
context.top = top <= 1 ? top * chartHeight : top;
|
||||
context.right = right <= 1 ? right * chartWidth : right;
|
||||
|
||||
context.height = height <= 1 ? height * chartHeight : height;
|
||||
|
||||
if (m_Orient == Orient.Horizonal)
|
||||
{
|
||||
context.width = width == 0
|
||||
? chartWidth - context.left - context.right
|
||||
: (width <= 1 ? chartWidth * width : width);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.width = width == 0
|
||||
? chartHeight - context.top - context.bottom
|
||||
: (width <= 1 ? chartHeight * width : width);
|
||||
}
|
||||
|
||||
if (context.left != 0 && context.right == 0)
|
||||
context.x = chartX + context.left;
|
||||
else if (context.left == 0 && context.right != 0)
|
||||
context.x = chartX + chartWidth - context.right - context.width;
|
||||
else
|
||||
context.x = chartX + context.left;
|
||||
|
||||
if (context.bottom != 0 && context.top == 0)
|
||||
context.y = chartY + context.bottom;
|
||||
else if (context.bottom == 0 && context.top != 0)
|
||||
context.y = chartY + chartHeight - context.top - context.height;
|
||||
else
|
||||
context.y = chartY + context.bottom;
|
||||
|
||||
context.position = new Vector3(context.x, context.y);
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Category;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = true;
|
||||
m_Position = AxisPosition.Bottom;
|
||||
m_Offset = 0;
|
||||
|
||||
m_Left = 0.1f;
|
||||
m_Right = 0.1f;
|
||||
m_Top = 0;
|
||||
m_Bottom = 0.2f;
|
||||
m_Width = 0;
|
||||
m_Height = 50;
|
||||
|
||||
m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
m_Icons = new List<Sprite>(5);
|
||||
splitLine.show = false;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = true;
|
||||
axisTick.showStartTick = true;
|
||||
axisTick.showEndTick = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeb871d6555744e609bd651306c601a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class SingleAxisContext : AxisContext, IRectContext
|
||||
{
|
||||
public float x { get; internal set; }
|
||||
public float y { get; internal set; }
|
||||
public float width { get; internal set; }
|
||||
public float height { get; internal set; }
|
||||
public Vector3 position { get; internal set; }
|
||||
public float left { get; internal set; }
|
||||
public float right { get; internal set; }
|
||||
public float bottom { get; internal set; }
|
||||
public float top { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 435915ad1c7fc41bb8362244d7bae638
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class SingleAxisHander : AxisHandler<SingleAxis>
|
||||
{
|
||||
protected override Orient orient { get { return component.orient; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitXAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawSingleAxisSplit(vh, component);
|
||||
DrawSingleAxisLine(vh, component);
|
||||
DrawSingleAxisTick(vh, component);
|
||||
}
|
||||
|
||||
private void InitXAxis(SingleAxis axis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var xAxisIndex = axis.index;
|
||||
axis.painter = chart.painter;
|
||||
axis.refreshComponent = delegate ()
|
||||
{
|
||||
axis.UpdateRuntimeData(chart.chartX,
|
||||
chart.chartY,
|
||||
chart.chartWidth,
|
||||
chart.chartHeight);
|
||||
|
||||
InitAxis(axis, null, chart, this,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
};
|
||||
axis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(component, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
return GetLabelPosition(i, component.orient, component, null,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
component.context.x,
|
||||
component.context.y,
|
||||
component.context.width,
|
||||
component.context.height);
|
||||
}
|
||||
|
||||
private void DrawSingleAxisSplit(VertexHelper vh, SingleAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
DrawAxisSplit(vh, axis, chart.theme.axis, dataZoom,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width,
|
||||
axis.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSingleAxisTick(VertexHelper vh, SingleAxis axis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
DrawAxisTick(vh, axis, chart.theme.axis, dataZoom,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSingleAxisLine(VertexHelper vh, SingleAxis axis)
|
||||
{
|
||||
if (axis.show && axis.axisLine.show)
|
||||
{
|
||||
var axisStartY = axis.context.y + axis.offset;
|
||||
DrawAxisLine(vh, axis,
|
||||
chart.theme.axis,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
axisStartY,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b3514e3079543ea9000d21d809cad3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XCharts/Runtime/Component/Axis/XAxis.meta
Normal file
8
Assets/XCharts/Runtime/Component/Axis/XAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5e50f8f0f8bb406b99fb32d6b5c7769
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
40
Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs
Normal file
40
Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate.
|
||||
/// <para>直角坐标系 grid 中的 x 轴。</para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(GridCoord))]
|
||||
[ComponentHandler(typeof(XAxisHander), true)]
|
||||
public class XAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Category;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = true;
|
||||
m_Position = AxisPosition.Bottom;
|
||||
m_Offset = 0;
|
||||
m_Data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
m_Icons = new List<Sprite>(5);
|
||||
splitLine.show = false;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs.meta
Normal file
11
Assets/XCharts/Runtime/Component/Axis/XAxis/XAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a71be0d36b9745c2894e598b3d9188a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
158
Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs
Normal file
158
Assets/XCharts/Runtime/Component/Axis/XAxis/XAxisHander.cs
Normal file
@@ -0,0 +1,158 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class XAxisHander : AxisHandler<XAxis>
|
||||
{
|
||||
protected override Orient orient { get { return Orient.Horizonal; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitXAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawXAxisSplit(vh, component);
|
||||
DrawXAxisLine(vh, component);
|
||||
DrawXAxisTick(vh, component);
|
||||
}
|
||||
|
||||
private void InitXAxis(XAxis xAxis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var xAxisIndex = xAxis.index;
|
||||
xAxis.painter = chart.painter;
|
||||
xAxis.refreshComponent = delegate ()
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid != null)
|
||||
{
|
||||
var yAxis = chart.GetChartComponent<YAxis>(xAxis.index);
|
||||
InitAxis(xAxis, yAxis, chart, this,
|
||||
orient,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height);
|
||||
}
|
||||
};
|
||||
xAxis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(component, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(component.gridIndex);
|
||||
if (grid == null)
|
||||
return Vector3.zero;
|
||||
|
||||
var yAxis = chart.GetChartComponent<YAxis>(component.index);
|
||||
|
||||
return GetLabelPosition(i, Orient.Horizonal, component, yAxis,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height);
|
||||
}
|
||||
|
||||
private void DrawXAxisSplit(VertexHelper vh, XAxis xAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(xAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
|
||||
DrawAxisSplit(vh, xAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawXAxisTick(VertexHelper vh, XAxis xAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(xAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
|
||||
var startY = grid.context.y + xAxis.offset;
|
||||
if (xAxis.IsTop())
|
||||
startY += grid.context.height;
|
||||
else
|
||||
startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis);
|
||||
|
||||
DrawAxisTick(vh, xAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
startY,
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawXAxisLine(VertexHelper vh, XAxis xAxis)
|
||||
{
|
||||
if (xAxis.show && xAxis.axisLine.show)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var startY = grid.context.y + xAxis.offset;
|
||||
if (xAxis.IsTop())
|
||||
startY += grid.context.height;
|
||||
else
|
||||
startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis);
|
||||
|
||||
DrawAxisLine(vh, xAxis, chart.theme.axis,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
startY,
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7818e1175663412196de53f19b5ac08
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XCharts/Runtime/Component/Axis/YAxis.meta
Normal file
8
Assets/XCharts/Runtime/Component/Axis/YAxis.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69f8ba8fcc7d84b12b42f837f9f2b94b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
40
Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs
Normal file
40
Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate.
|
||||
/// <para>
|
||||
/// 直角坐标系 grid 中的 y 轴。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(GridCoord), typeof(XAxis))]
|
||||
[ComponentHandler(typeof(YAxisHander), true)]
|
||||
public class YAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
m_BoundaryGap = false;
|
||||
m_Position = AxisPosition.Left;
|
||||
m_Data = new List<string>(5);
|
||||
splitLine.show = true;
|
||||
splitLine.lineStyle.type = LineStyle.Type.None;
|
||||
axisLabel.textLimit.enable = false;
|
||||
axisTick.showStartTick = true;
|
||||
iconStyle.show = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs.meta
Normal file
11
Assets/XCharts/Runtime/Component/Axis/YAxis/YAxis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ac60b8329f7a45c3898c7539d78f091
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
155
Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs
Normal file
155
Assets/XCharts/Runtime/Component/Axis/YAxis/YAxisHander.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class YAxisHander : AxisHandler<YAxis>
|
||||
{
|
||||
protected override Orient orient { get { return Orient.Vertical; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitYAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawYAxisSplit(vh, component.index, component);
|
||||
DrawYAxisLine(vh, component.index, component);
|
||||
DrawYAxisTick(vh, component.index, component);
|
||||
}
|
||||
|
||||
private void InitYAxis(YAxis yAxis)
|
||||
{
|
||||
var theme = chart.theme;
|
||||
var yAxisIndex = yAxis.index;
|
||||
yAxis.painter = chart.painter;
|
||||
yAxis.refreshComponent = delegate ()
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid != null)
|
||||
{
|
||||
var xAxis = chart.GetChartComponent<YAxis>(yAxis.index);
|
||||
InitAxis(yAxis, xAxis, chart, this,
|
||||
orient,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width);
|
||||
}
|
||||
};
|
||||
yAxis.refreshComponent();
|
||||
}
|
||||
|
||||
internal override void UpdateAxisLabelText(Axis axis)
|
||||
{
|
||||
base.UpdateAxisLabelText(axis);
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
for (int i = 0; i < axis.context.labelObjectList.Count; i++)
|
||||
{
|
||||
var label = axis.context.labelObjectList[i];
|
||||
if (label != null)
|
||||
{
|
||||
var pos = GetLabelPosition(0, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(axis, i, label, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(component.gridIndex);
|
||||
if (grid == null)
|
||||
return Vector3.zero;
|
||||
|
||||
return GetLabelPosition(i, Orient.Vertical, component, null,
|
||||
chart.theme.axis,
|
||||
scaleWid,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width);
|
||||
}
|
||||
|
||||
private void DrawYAxisSplit(VertexHelper vh, int yAxisIndex, YAxis yAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(yAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
|
||||
DrawAxisSplit(vh, yAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Vertical,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawYAxisTick(VertexHelper vh, int yAxisIndex, YAxis yAxis)
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(yAxis))
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
|
||||
|
||||
var startX = grid.context.x + yAxis.offset;
|
||||
if (yAxis.IsRight())
|
||||
startX += grid.context.width;
|
||||
else
|
||||
startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis);
|
||||
|
||||
DrawAxisTick(vh, yAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Vertical,
|
||||
startX,
|
||||
grid.context.y,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawYAxisLine(VertexHelper vh, int yAxisIndex, YAxis yAxis)
|
||||
{
|
||||
if (yAxis.show && yAxis.axisLine.show)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
|
||||
var startX = grid.context.x + yAxis.offset;
|
||||
if (yAxis.IsRight())
|
||||
startX += grid.context.width;
|
||||
else
|
||||
startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis);
|
||||
|
||||
DrawAxisLine(vh, yAxis, chart.theme.axis,
|
||||
Orient.Vertical,
|
||||
startX,
|
||||
grid.context.y,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f09b5dcb5fcc54583bcd7946f18dfa48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/XCharts/Runtime/Component/Background.meta
Normal file
8
Assets/XCharts/Runtime/Component/Background.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7db6fdcbbbfd148f58ff7a1f1a569d51
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Net.Mime;
|
||||
/************************************************/
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
@@ -14,17 +13,12 @@ namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// Background component.
|
||||
/// Due to the limitations of the framework, there are two limitations to the use of background component:
|
||||
/// 1: The parent node of chart cannot have a layout control class component.
|
||||
/// 2: The parent node of Chart can only have one child node of the current chart.
|
||||
///
|
||||
/// 背景组件。
|
||||
/// 由于框架的局限性,背景组件使用有以下两个限制:
|
||||
/// 1:chart的父节点不能有布局控制类组件。
|
||||
/// 2:chart的父节点只能有当前chart一个子节点。
|
||||
/// 背景组件的开启需要通过接口来开启:BaseChart.EnableBackground(bool flag)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DisallowMultipleComponent]
|
||||
[ComponentHandler(typeof(BackgroundHandler), false)]
|
||||
public class Background : MainComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
@@ -34,9 +28,8 @@ namespace XCharts
|
||||
[SerializeField] private bool m_HideThemeBackgroundColor = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable the background component. However,
|
||||
/// the ability to activate the background component is subject to other conditions.
|
||||
/// 是否启用背景组件。但能否激活背景组件还要受其他条件限制。
|
||||
/// Whether to enable the background component.
|
||||
/// 是否启用背景组件。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
@@ -82,20 +75,13 @@ namespace XCharts
|
||||
set { if (PropertyUtil.SetStruct(ref m_HideThemeBackgroundColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public static Background defaultBackground
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
get
|
||||
{
|
||||
var background = new Background
|
||||
{
|
||||
m_Show = false,
|
||||
m_Image = null,
|
||||
m_ImageType = Image.Type.Sliced,
|
||||
m_ImageColor = Color.white,
|
||||
m_HideThemeBackgroundColor = true,
|
||||
};
|
||||
return background;
|
||||
}
|
||||
m_Show = false;
|
||||
m_Image = null;
|
||||
m_ImageType = Image.Type.Sliced;
|
||||
m_ImageColor = Color.white;
|
||||
m_HideThemeBackgroundColor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20bad62e2503e49dcacbecdc99542025
|
||||
guid: 524f7df5241cc4379ae241a73d5b2ff2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
@@ -0,0 +1,82 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class BackgroundHandler : MainComponentHandler<Background>
|
||||
{
|
||||
private readonly string s_BackgroundObjectName = "background";
|
||||
public override void InitComponent()
|
||||
{
|
||||
component.painter = chart.painter;
|
||||
component.refreshComponent = delegate ()
|
||||
{
|
||||
var backgroundObj = ChartHelper.AddObject(s_BackgroundObjectName, chart.transform, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
component.gameObject = backgroundObj;
|
||||
backgroundObj.hideFlags = chart.chartHideFlags;
|
||||
|
||||
var backgroundImage = ChartHelper.GetOrAddComponent<Image>(backgroundObj);
|
||||
ChartHelper.UpdateRectTransform(backgroundObj, chart.chartMinAnchor,
|
||||
chart.chartMaxAnchor, chart.chartPivot, chart.chartSizeDelta);
|
||||
backgroundImage.sprite = component.image;
|
||||
backgroundImage.type = component.imageType;
|
||||
backgroundImage.color = component.imageColor;
|
||||
|
||||
backgroundObj.transform.SetSiblingIndex(0);
|
||||
backgroundObj.SetActive(component.show);
|
||||
};
|
||||
component.refreshComponent();
|
||||
}
|
||||
|
||||
//protected void DrawBackground(VertexHelper vh)
|
||||
//{
|
||||
//TODO: CooridateChart
|
||||
// if (SeriesHelper.IsAnyClipSerie(m_Series))
|
||||
// {
|
||||
// var xLineDiff = xAxis0.axisLine.GetWidth(m_Theme.axis.lineWidth);
|
||||
// var yLineDiff = yAxis0.axisLine.GetWidth(m_Theme.axis.lineWidth);
|
||||
// var xSplitDiff = xAxis0.splitLine.GetWidth(m_Theme.axis.splitLineWidth);
|
||||
// var ySplitDiff = yAxis0.splitLine.GetWidth(m_Theme.axis.splitLineWidth);
|
||||
// foreach (var grid in m_Grids)
|
||||
// {
|
||||
// var cpty = grid.context.runtimeY + grid.context.runtimeHeight + ySplitDiff;
|
||||
// var cp1 = new Vector3(grid.context.runtimeX - yLineDiff, grid.context.runtimeY - xLineDiff);
|
||||
// var cp2 = new Vector3(grid.context.runtimeX - yLineDiff, cpty);
|
||||
// var cp3 = new Vector3(grid.context.runtimeX + grid.context.runtimeWidth + xSplitDiff, cpty);
|
||||
// var cp4 = new Vector3(grid.context.runtimeX + grid.context.runtimeWidth + xSplitDiff, grid.context.runtimeY - xLineDiff);
|
||||
// var backgroundColor = ThemeHelper.GetBackgroundColor(m_Theme, m_Background);
|
||||
// UGL.DrawQuadrilateral(vh, cp1, cp2, cp3, cp4, backgroundColor);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// base.DrawBackground(vh);
|
||||
// }
|
||||
// }
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
if (!component.show)
|
||||
return;
|
||||
|
||||
var p1 = new Vector3(chart.chartX, chart.chartY + chart.chartHeight);
|
||||
var p2 = new Vector3(chart.chartX + chart.chartWidth, chart.chartY + chart.chartHeight);
|
||||
var p3 = new Vector3(chart.chartX + chart.chartWidth, chart.chartY);
|
||||
var p4 = new Vector3(chart.chartX, chart.chartY);
|
||||
var backgroundColor = chart.theme.GetBackgroundColor(component);
|
||||
|
||||
UGL.DrawQuadrilateral(vh, p1, p2, p3, p4, backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1cb3d1a2aa224bbe84eef2681cf3df4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0af5e768fe0e407cb5b023b37c41597
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -15,7 +15,7 @@ namespace XCharts
|
||||
/// 区域填充样式。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AreaStyle : SubComponent
|
||||
public class AreaStyle : ChildComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Origin position of area.
|
||||
@@ -137,7 +137,9 @@ namespace XCharts
|
||||
|
||||
public Color32 GetColor()
|
||||
{
|
||||
if (m_Opacity == 1) return m_Color;
|
||||
if (m_Opacity == 1)
|
||||
return m_Color;
|
||||
|
||||
var color = m_Color;
|
||||
color.a = (byte)(color.a * m_Opacity);
|
||||
return color;
|
||||
@@ -13,7 +13,7 @@ namespace XCharts
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Arrow : SubComponent
|
||||
public class ArrowStyle : ChildComponent
|
||||
{
|
||||
[SerializeField] private float m_Width = 10;
|
||||
[SerializeField] private float m_Height = 15;
|
||||
@@ -68,9 +68,9 @@ namespace XCharts
|
||||
set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public Arrow Clone()
|
||||
public ArrowStyle Clone()
|
||||
{
|
||||
var arrow = new Arrow();
|
||||
var arrow = new ArrowStyle();
|
||||
arrow.width = width;
|
||||
arrow.height = height;
|
||||
arrow.offset = offset;
|
||||
@@ -79,7 +79,7 @@ namespace XCharts
|
||||
return arrow;
|
||||
}
|
||||
|
||||
public void Copy(Arrow arrow)
|
||||
public void Copy(ArrowStyle arrow)
|
||||
{
|
||||
width = arrow.width;
|
||||
height = arrow.height;
|
||||
@@ -90,8 +90,10 @@ namespace XCharts
|
||||
|
||||
public Color32 GetColor(Color32 defaultColor)
|
||||
{
|
||||
if (ChartHelper.IsClearColor(color)) return defaultColor;
|
||||
else return color;
|
||||
if (ChartHelper.IsClearColor(color))
|
||||
return defaultColor;
|
||||
else
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user