3.0 commit

This commit is contained in:
monitor1394
2021-11-23 13:20:07 +08:00
parent d87e0f8267
commit 1b3fa7fb43
796 changed files with 410878 additions and 1656601 deletions

View File

@@ -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.
/// 点击饼图区域回调。参数PointerEventDataSerieIndexSerieDataIndex
/// </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;
}
}
}
}

View File

@@ -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 chartsuch 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 AxesxAxes[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;
}
}
}

View File

@@ -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];
}
}
}

View File

@@ -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; } }
}
}

View File

@@ -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;
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f17a7aa35fdd3417dab9414f10fe2886
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 7a1cd7e0dade8470cb91d6a7971ff022
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 94d1c19509a514ffab61efb88d3281fd
guid: 900b05585ba864df1aa05dcdb36b324b
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -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);
}
}
}
}

View 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.
/// 点击饼图区域回调。参数PointerEventDataSerieIndexSerieDataIndex
/// </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;
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d078e85e5877d4d0f990c8dc43006247
guid: 1fc3767ca43f44f77a6d017fd55c8fec
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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()
{

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: e17adfd3dc62d435cb79fa8c330fe186
guid: ec7d385a69cce42fda86960eb0b23c3b
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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));
}

View 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
}
}

View 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
}
}

View File

@@ -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));

View File

@@ -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
}

View 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
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 42960f04fcc2442baa061d32386aaaa8
guid: 161753d0d6ce541c89483f8c3a21343f
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View 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
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: d1d3ce01c4a6f4e3482c1dc22f388889
guid: 194a62edf7ec2484fa2eebbf5bde3e95
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: b3dbff4f83d24491da3a8a88e3e3ace4
guid: 28b88ca3453f04fbdb23a53b5bcb4bf7
folderAsset: yes
DefaultImporter:
externalObjects: {}

View 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;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 032e5d8f514854bf39f5fd7052119271
guid: 787015be923a74e1da4000c7abc2dcdf
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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);
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 73ae9e0b481fc4587828be9149026b0f
guid: 83f228c42435c4619943a2f187c98e7b
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f4e87b6a821d94304af45b2955c293bb
guid: d5c29555575e04db98ee243c3b17f0ed
MonoImporter:
externalObjects: {}
serializedVersion: 2

View 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;
}
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: fd14dec4102b848f699bbf42babbe4c4
guid: 6525f065fa5d04663ab7026a3467f56e
MonoImporter:
externalObjects: {}
serializedVersion: 2

View 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;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0babef8a2708b4745bbb0a0648913a35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ca154a2444b924ff98ce6091280227c8
guid: 566e3426780cc4339a1fb92d9604d21f
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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);
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 867b1c4fd101c43f79a82de245e9c1d2
guid: 051f9473d1beb4e0bb35aa1600cb44bd
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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;

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: dee861621714d43519f0f1581e027a57
guid: 2748c2a8789724709aa76f6056eb708d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -15,7 +15,7 @@ namespace XCharts
/// 坐标轴名称。
/// </summary>
[Serializable]
public class AxisName : SubComponent
public class AxisName : ChildComponent
{
/// <summary>
/// the location of axis name.

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 6f354d1d9b4e841c1b0068bf656b28c7
guid: 878555ba3c6b1479f94f38185700531e
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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;

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 1e3ad5d1729154c73b47342a46f0d3b5
guid: 18702fd7797054670af64546b7304bb4
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 62c6ea03f6ffe431a9c4730cce152c80
guid: 3da942a7a6bea44e2998ed993c0641ab
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: a9cff8225584c4d9492c252c09977060
guid: 60278762ed892450d85e27b7df8f997e
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 4e4276d289bef4136b22e6cc8b207d99
guid: 24693180b2a2e41b2ab4025b2bbebf01
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7bc01c54f4d6485389fd57c37810c74
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b92542e13620d417d819e8573b430dc8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 26ab25bf702c54ad38461c91ba1451af
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7c8971958a94d47e68f7ebdff5872b71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f6429398a27934726ba49d387d681728
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f2cb79bfe30c4f14a3117f9f30ed3bd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 17498717d39c14b43a91c67401407410
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: aeb871d6555744e609bd651306c601a8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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; }
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 435915ad1c7fc41bb8362244d7bae638
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50b3514e3079543ea9000d21d809cad3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e5e50f8f0f8bb406b99fb32d6b5c7769
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a71be0d36b9745c2894e598b3d9188a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d7818e1175663412196de53f19b5ac08
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 69f8ba8fcc7d84b12b42f837f9f2b94b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ac60b8329f7a45c3898c7539d78f091
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View 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);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f09b5dcb5fcc54583bcd7946f18dfa48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7db6fdcbbbfd148f58ff7a1f1a569d51
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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.
///
/// 背景组件。
/// 由于框架的局限性,背景组件使用有以下两个限制:
/// 1chart的父节点不能有布局控制类组件。
/// 2chart的父节点只能有当前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;
}
}
}

View File

@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 20bad62e2503e49dcacbecdc99542025
guid: 524f7df5241cc4379ae241a73d5b2ff2
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@@ -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);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f1cb3d1a2aa224bbe84eef2681cf3df4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: b0af5e768fe0e407cb5b023b37c41597
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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;

View File

@@ -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