Aimbot Enviroment very first
Basic environment include Multi scene, Reward Change, Visible chart, etc....
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 900b05585ba864df1aa05dcdb36b324b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/BarChart", 14)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class BarChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetOrAddChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
Bar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 535d2697503c2a94a887354e22a5414d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/CandlestickChart", 23)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class CandlestickChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetOrAddChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
var serie = Candlestick.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < serie.dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7b64f0bb738cc4acfa72fff2c30212b4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,84 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/HeatmapChart", 18)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class HeatmapChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.None;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
var grid = GetOrAddChartComponent<GridCoord>();
|
||||
grid.left = 0.12f;
|
||||
|
||||
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.AddColors(colors);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31aa03cd4ce594c239ae746791b3b59f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/LineChart", 13)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class LineChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetOrAddChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
Line.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4f38bd00b4648c448cabfc167538f7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/ParallelChart", 25)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ParallelChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
RemoveData();
|
||||
AddChartComponent<ParallelCoord>();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
var valueAxis = AddChartComponent<ParallelAxis>();
|
||||
valueAxis.type = Axis.AxisType.Value;
|
||||
}
|
||||
var categoryAxis = AddChartComponent<ParallelAxis>();
|
||||
categoryAxis.type = Axis.AxisType.Category;
|
||||
categoryAxis.position = Axis.AxisPosition.Right;
|
||||
categoryAxis.data = new List<string>() { "x1", "x2", "x3", "x4", "x5" };
|
||||
|
||||
Parallel.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 161753d0d6ce541c89483f8c3a21343f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/PieChart", 15)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class PieChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
var legend = GetOrAddChartComponent<Legend>();
|
||||
legend.show = true;
|
||||
|
||||
RemoveData();
|
||||
Pie.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d44276ba809fd92408b296835f6f7658
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/PolarChart", 23)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class PolarChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<PolarCoord>();
|
||||
AddChartComponentWhenNoExist<AngleAxis>();
|
||||
AddChartComponentWhenNoExist<RadiusAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Corss;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
var serie = Line.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
serie.SetCoord<PolarCoord>();
|
||||
serie.ClearData();
|
||||
for (int i = 0; i <= 360; i++)
|
||||
{
|
||||
var t = i / 180f * Mathf.PI;
|
||||
var r = Mathf.Sin(2 * t) * Mathf.Cos(2 * t) * 2;
|
||||
AddData(0, Mathf.Abs(r), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 574bcbd917fc148e8bb8735acda07f77
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/RadarChart", 16)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class RadarChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
RemoveData();
|
||||
RemoveChartComponents<RadarCoord>();
|
||||
AddChartComponent<RadarCoord>();
|
||||
Radar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d2231a0d3e3a5b043b074f6739be4a86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/RingChart", 20)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class RingChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
GetChartComponent<Tooltip>().type = Tooltip.Type.Line;
|
||||
RemoveData();
|
||||
Ring.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ad8949f652ee4376a4a4fe5cb32029f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/ScatterChart", 17)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class ScatterChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf16aac0bd6c24a8da75846c34c5193e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/SimplifiedBarChart", 27)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class SimplifiedBarChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SimplifiedBar.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa86c3bbf8877409c9d45716fbaf92f4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/SimplifiedCandlestickChart", 28)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class SimplifiedCandlestickChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SimplifiedCandlestick.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dcc9bd1ca8344d938f386e6b32e8946
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,29 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[AddComponentMenu("XCharts/SimplifiedLineChart", 26)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class SimplifiedLineChart : BaseChart
|
||||
{
|
||||
protected override void DefaultChart()
|
||||
{
|
||||
AddChartComponentWhenNoExist<GridCoord>();
|
||||
AddChartComponentWhenNoExist<XAxis>();
|
||||
AddChartComponentWhenNoExist<YAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Line;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
SimplifiedLine.AddDefaultSerie(this, GenerateDefaultSerieName());
|
||||
for (int i = 0; i < GetSerie(0).dataCount; i++)
|
||||
{
|
||||
AddXAxisData("x" + (i + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a8233997c1b324ecd875a03af4d90972
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3be5f1d3b129a47dd8e41cffe3b8e428
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f827513754e8436bbc63e64c5b5e6c3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,630 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public enum AnimationType
|
||||
{
|
||||
/// <summary>
|
||||
/// he default. An animation playback mode will be selected according to the actual situation.
|
||||
/// |默认。内部会根据实际情况选择一种动画播放方式。
|
||||
/// </summary>
|
||||
Default,
|
||||
/// <summary>
|
||||
/// Play the animation from left to right.
|
||||
/// |从左往右播放动画。
|
||||
/// </summary>
|
||||
LeftToRight,
|
||||
/// <summary>
|
||||
/// Play the animation from bottom to top.
|
||||
/// |从下往上播放动画。
|
||||
/// </summary>
|
||||
BottomToTop,
|
||||
/// <summary>
|
||||
/// Play animations from the inside out.
|
||||
/// |由内到外播放动画。
|
||||
/// </summary>
|
||||
InsideOut,
|
||||
/// <summary>
|
||||
/// Play the animation along the path.
|
||||
/// |沿着路径播放动画。
|
||||
/// </summary>
|
||||
AlongPath,
|
||||
/// <summary>
|
||||
/// Play the animation clockwise.
|
||||
/// |顺时针播放动画。
|
||||
/// </summary>
|
||||
Clockwise,
|
||||
}
|
||||
|
||||
public enum AnimationEasing
|
||||
{
|
||||
Linear,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the animation of serie.
|
||||
/// |动画表现。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AnimationStyle : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Enable = true;
|
||||
[SerializeField] private AnimationType m_Type;
|
||||
[SerializeField] private AnimationEasing m_Easting;
|
||||
[SerializeField] private int m_Threshold = 2000;
|
||||
[SerializeField] private float m_FadeInDuration = 1000;
|
||||
[SerializeField] private float m_FadeInDelay = 0;
|
||||
[SerializeField] private float m_FadeOutDuration = 1000f;
|
||||
[SerializeField] private float m_FadeOutDelay = 0;
|
||||
[SerializeField] private bool m_DataChangeEnable = true;
|
||||
[SerializeField] private float m_DataChangeDuration = 500;
|
||||
[SerializeField] private float m_ActualDuration;
|
||||
/// <summary>
|
||||
/// 自定义渐入动画延时函数。返回ms值。
|
||||
/// </summary>
|
||||
public AnimationDelayFunction fadeInDelayFunction;
|
||||
/// <summary>
|
||||
/// 自定义渐入动画时长函数。返回ms值。
|
||||
/// </summary>
|
||||
public AnimationDurationFunction fadeInDurationFunction;
|
||||
/// <summary>
|
||||
/// 自定义渐出动画延时函数。返回ms值。
|
||||
/// </summary>
|
||||
public AnimationDelayFunction fadeOutDelayFunction;
|
||||
/// <summary>
|
||||
/// 自定义渐出动画时长函数。返回ms值。
|
||||
/// </summary>
|
||||
public AnimationDurationFunction fadeOutDurationFunction;
|
||||
public AnimationStyleContext context = new AnimationStyleContext();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable animation.
|
||||
/// |是否开启动画效果。
|
||||
/// </summary>
|
||||
public bool enable { get { return m_Enable; } set { m_Enable = value; } }
|
||||
/// <summary>
|
||||
/// The type of animation.
|
||||
/// |动画类型。
|
||||
/// </summary>
|
||||
public AnimationType type { get { return m_Type; } set { m_Type = value; } }
|
||||
/// <summary>
|
||||
/// Easing method used for the first animation.
|
||||
/// |动画的缓动效果。
|
||||
/// </summary>
|
||||
//public Easing easting { get { return m_Easting; } set { m_Easting = value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds duration of the fadeIn animation.
|
||||
/// |设定的渐入动画时长(毫秒)。如果要设置单个数据项的渐入时长,可以用代码定制:customFadeInDuration。
|
||||
/// </summary>
|
||||
public float fadeInDuration { get { return m_FadeInDuration; } set { m_FadeInDuration = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds duration of the fadeOut animation.
|
||||
/// |设定的渐出动画时长(毫秒)。如果要设置单个数据项的渐出时长,可以用代码定制:customFadeOutDuration。
|
||||
/// </summary>
|
||||
public float fadeOutDuration { get { return m_FadeOutDuration; } set { m_FadeOutDuration = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds actual duration of the first animation.
|
||||
/// |实际的动画时长(毫秒)。
|
||||
/// </summary>
|
||||
public float actualDuration { get { return m_ActualDuration; } }
|
||||
/// <summary>
|
||||
/// Whether to set graphic number threshold to animation. Animation will be disabled when graphic number is larger than threshold.
|
||||
/// |是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。
|
||||
/// </summary>
|
||||
public int threshold { get { return m_Threshold; } set { m_Threshold = value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds delay before updating the first animation.
|
||||
/// |渐入动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeInDelay。
|
||||
/// </summary>
|
||||
public float fadeInDelay { get { return m_FadeInDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// 渐出动画延时(毫秒)。如果要设置单个数据项的延时,可以用代码定制:customFadeOutDelay。
|
||||
/// </summary>
|
||||
public float fadeOutDelay { get { return m_FadeOutDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// 是否开启数据变更动画。
|
||||
/// </summary>
|
||||
public bool dataChangeEnable { get { return m_DataChangeEnable; } set { m_DataChangeEnable = value; } }
|
||||
/// <summary>
|
||||
/// The milliseconds duration of the data change animation.
|
||||
/// |数据变更的动画时长(毫秒)。
|
||||
/// </summary>
|
||||
public float dataChangeDuration { get { return m_DataChangeDuration; } set { m_DataChangeDuration = value < 0 ? 0 : value; } }
|
||||
/// <summary>
|
||||
/// 渐入动画完成回调
|
||||
/// </summary>
|
||||
public Action fadeInFinishCallback { get; set; }
|
||||
/// <summary>
|
||||
/// 渐出动画完成回调
|
||||
/// </summary>
|
||||
public Action fadeOutFinishCallback { get; set; }
|
||||
private Dictionary<int, float> m_ItemCurrProgress = new Dictionary<int, float>();
|
||||
private Dictionary<int, float> m_ItemDestProgress = new Dictionary<int, float>();
|
||||
private bool m_FadeIn = false;
|
||||
private bool m_IsEnd = true;
|
||||
private bool m_IsPause = false;
|
||||
private bool m_FadeOut = false;
|
||||
private bool m_FadeOuted = false;
|
||||
private bool m_IsInit = false;
|
||||
|
||||
private float startTime { get; set; }
|
||||
private float m_CurrDetailProgress;
|
||||
private float m_DestDetailProgress;
|
||||
private float m_TotalDetailProgress;
|
||||
private float m_CurrSymbolProgress;
|
||||
private Vector3 m_LinePathLastPos;
|
||||
|
||||
public void FadeIn()
|
||||
{
|
||||
if (m_FadeOut)
|
||||
return;
|
||||
|
||||
if (m_IsPause)
|
||||
{
|
||||
m_IsPause = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_FadeIn)
|
||||
return;
|
||||
|
||||
startTime = Time.time;
|
||||
m_FadeIn = true;
|
||||
m_IsEnd = false;
|
||||
m_IsInit = false;
|
||||
m_IsPause = false;
|
||||
m_FadeOuted = false;
|
||||
m_CurrDetailProgress = 0;
|
||||
m_DestDetailProgress = 1;
|
||||
m_CurrSymbolProgress = 0;
|
||||
m_ItemCurrProgress.Clear();
|
||||
m_ItemDestProgress.Clear();
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
Reset();
|
||||
FadeIn();
|
||||
}
|
||||
|
||||
public void FadeOut()
|
||||
{
|
||||
if (m_IsPause)
|
||||
{
|
||||
m_IsPause = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_FadeOut = true;
|
||||
startTime = Time.time;
|
||||
m_FadeIn = true;
|
||||
m_IsEnd = false;
|
||||
m_IsInit = false;
|
||||
m_IsPause = false;
|
||||
m_CurrDetailProgress = 0;
|
||||
m_DestDetailProgress = 1;
|
||||
m_CurrSymbolProgress = 0;
|
||||
m_ItemCurrProgress.Clear();
|
||||
m_ItemDestProgress.Clear();
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
{
|
||||
if (!m_IsPause)
|
||||
{
|
||||
m_IsPause = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Resume()
|
||||
{
|
||||
if (m_IsPause)
|
||||
{
|
||||
m_IsPause = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void End()
|
||||
{
|
||||
if (m_IsEnd)
|
||||
return;
|
||||
|
||||
m_ActualDuration = (int) ((Time.time - startTime) * 1000) - (m_FadeOut ? fadeOutDelay : fadeInDelay);
|
||||
m_IsEnd = true;
|
||||
m_IsInit = false;
|
||||
|
||||
if (m_FadeIn)
|
||||
{
|
||||
m_FadeIn = false;
|
||||
if (fadeInFinishCallback != null)
|
||||
{
|
||||
fadeInFinishCallback();
|
||||
}
|
||||
}
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_FadeOut = false;
|
||||
m_FadeOuted = true;
|
||||
if (fadeOutFinishCallback != null)
|
||||
{
|
||||
fadeOutFinishCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_FadeIn = false;
|
||||
m_IsEnd = true;
|
||||
m_IsInit = false;
|
||||
m_IsPause = false;
|
||||
m_FadeOut = false;
|
||||
m_FadeOuted = false;
|
||||
m_ItemCurrProgress.Clear();
|
||||
}
|
||||
|
||||
public void InitProgress(float curr, float dest)
|
||||
{
|
||||
if (m_IsInit || m_IsEnd)
|
||||
return;
|
||||
if (curr > dest)
|
||||
return;
|
||||
|
||||
m_IsInit = true;
|
||||
m_TotalDetailProgress = dest - curr;
|
||||
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_CurrDetailProgress = dest;
|
||||
m_DestDetailProgress = curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrDetailProgress = curr;
|
||||
m_DestDetailProgress = dest;
|
||||
}
|
||||
}
|
||||
|
||||
public void InitProgress(List<Vector3> paths, bool isY)
|
||||
{
|
||||
if (paths.Count < 1) return;
|
||||
var sp = paths[0];
|
||||
var ep = paths[paths.Count - 1];
|
||||
var currDetailProgress = isY ? sp.y : sp.x;
|
||||
var totalDetailProgress = isY ? ep.y : ep.x;
|
||||
if (context.type == AnimationType.AlongPath)
|
||||
{
|
||||
currDetailProgress = 0;
|
||||
totalDetailProgress = 0;
|
||||
var lp = sp;
|
||||
for (int i = 1; i < paths.Count; i++)
|
||||
{
|
||||
var np = paths[i];
|
||||
totalDetailProgress += Vector3.Distance(np, lp);
|
||||
lp = np;
|
||||
}
|
||||
m_LinePathLastPos = sp;
|
||||
context.currentPathDistance = 0;
|
||||
}
|
||||
InitProgress(currDetailProgress, totalDetailProgress);
|
||||
}
|
||||
|
||||
private void SetDataCurrProgress(int index, float state)
|
||||
{
|
||||
m_ItemCurrProgress[index] = state;
|
||||
}
|
||||
|
||||
private float GetDataCurrProgress(int index, float initValue, float destValue, ref bool isBarEnd)
|
||||
{
|
||||
if (IsInDelay())
|
||||
{
|
||||
isBarEnd = false;
|
||||
return initValue;
|
||||
}
|
||||
var c1 = !m_ItemCurrProgress.ContainsKey(index);
|
||||
var c2 = !m_ItemDestProgress.ContainsKey(index);
|
||||
if (c1 || c2)
|
||||
{
|
||||
if (c1)
|
||||
m_ItemCurrProgress.Add(index, initValue);
|
||||
|
||||
if (c2)
|
||||
m_ItemDestProgress.Add(index, destValue);
|
||||
|
||||
isBarEnd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isBarEnd = m_ItemCurrProgress[index] == m_ItemDestProgress[index];
|
||||
}
|
||||
return m_ItemCurrProgress[index];
|
||||
}
|
||||
|
||||
public bool IsFinish()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return true;
|
||||
#endif
|
||||
if (!m_Enable || m_IsEnd)
|
||||
return true;
|
||||
|
||||
if (IsIndexAnimation())
|
||||
return m_CurrDetailProgress > m_DestDetailProgress;
|
||||
if (IsItemAnimation())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInFadeOut()
|
||||
{
|
||||
return m_FadeOut;
|
||||
}
|
||||
|
||||
public bool IsInDelay()
|
||||
{
|
||||
if (m_FadeOut)
|
||||
return (fadeOutDelay > 0 && Time.time - startTime < fadeOutDelay / 1000);
|
||||
else
|
||||
return (fadeInDelay > 0 && Time.time - startTime < fadeInDelay / 1000);
|
||||
}
|
||||
|
||||
public bool IsItemAnimation()
|
||||
{
|
||||
return context.type == AnimationType.BottomToTop || context.type == AnimationType.InsideOut;
|
||||
}
|
||||
|
||||
public bool IsIndexAnimation()
|
||||
{
|
||||
return context.type == AnimationType.LeftToRight ||
|
||||
context.type == AnimationType.Clockwise ||
|
||||
context.type == AnimationType.AlongPath;
|
||||
}
|
||||
|
||||
public float GetIndexDelay(int dataIndex)
|
||||
{
|
||||
if (m_FadeOut && fadeOutDelayFunction != null)
|
||||
return fadeOutDelayFunction(dataIndex);
|
||||
else if (m_FadeIn && fadeInDelayFunction != null)
|
||||
return fadeInDelayFunction(dataIndex);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool IsInIndexDelay(int dataIndex)
|
||||
{
|
||||
return Time.time - startTime < GetIndexDelay(dataIndex) / 1000f;
|
||||
}
|
||||
|
||||
public bool IsAllOutDelay(int dataCount)
|
||||
{
|
||||
var nowTime = Time.time - startTime;
|
||||
for (int i = 0; i < dataCount; i++)
|
||||
{
|
||||
if (nowTime < GetIndexDelay(i) / 1000)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckDetailBreak(float detail)
|
||||
{
|
||||
if (!IsIndexAnimation())
|
||||
return false;
|
||||
return !IsFinish() && detail > m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public bool CheckDetailBreak(Vector3 pos, bool isYAxis)
|
||||
{
|
||||
if (!IsIndexAnimation())
|
||||
return false;
|
||||
|
||||
if (IsFinish())
|
||||
return false;
|
||||
|
||||
if (context.type == AnimationType.AlongPath)
|
||||
{
|
||||
context.currentPathDistance += Vector3.Distance(pos, m_LinePathLastPos);
|
||||
m_LinePathLastPos = pos;
|
||||
return CheckDetailBreak(context.currentPathDistance);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isYAxis)
|
||||
return pos.y > m_CurrDetailProgress;
|
||||
else
|
||||
return pos.x > m_CurrDetailProgress;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckProgress()
|
||||
{
|
||||
if (IsItemAnimation() && context.isAllItemAnimationEnd)
|
||||
{
|
||||
End();
|
||||
return;
|
||||
}
|
||||
CheckProgress(m_TotalDetailProgress);
|
||||
}
|
||||
|
||||
public void CheckProgress(double total)
|
||||
{
|
||||
if (IsFinish())
|
||||
return;
|
||||
|
||||
if (!m_IsInit || m_IsPause || m_IsEnd)
|
||||
return;
|
||||
|
||||
if (IsInDelay())
|
||||
return;
|
||||
|
||||
m_ActualDuration = (int) ((Time.time - startTime) * 1000) - fadeInDelay;
|
||||
var duration = GetCurrAnimationDuration();
|
||||
var delta = (float) (total / duration * Time.deltaTime);
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_CurrDetailProgress -= delta;
|
||||
if (m_CurrDetailProgress <= m_DestDetailProgress)
|
||||
{
|
||||
m_CurrDetailProgress = m_DestDetailProgress;
|
||||
End();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrDetailProgress += delta;
|
||||
if (m_CurrDetailProgress >= m_DestDetailProgress)
|
||||
{
|
||||
m_CurrDetailProgress = m_DestDetailProgress;
|
||||
End();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal float GetCurrAnimationDuration(int dataIndex = -1)
|
||||
{
|
||||
if (dataIndex >= 0)
|
||||
{
|
||||
if (m_FadeOut && fadeOutDurationFunction != null)
|
||||
return fadeOutDurationFunction(dataIndex) / 1000f;
|
||||
if (m_FadeIn && fadeInDurationFunction != null)
|
||||
return fadeInDurationFunction(dataIndex) / 1000f;
|
||||
}
|
||||
|
||||
if (m_FadeOut)
|
||||
return m_FadeOutDuration > 0 ? m_FadeOutDuration / 1000 : 1f;
|
||||
else
|
||||
return m_FadeInDuration > 0 ? m_FadeInDuration / 1000 : 1f;
|
||||
}
|
||||
|
||||
internal float CheckItemProgress(int dataIndex, float destProgress, ref bool isEnd, float startProgress = 0)
|
||||
{
|
||||
isEnd = false;
|
||||
var initHig = m_FadeOut ? destProgress : startProgress;
|
||||
var destHig = m_FadeOut ? startProgress : destProgress;
|
||||
var currHig = GetDataCurrProgress(dataIndex, initHig, destHig, ref isEnd);
|
||||
if (isEnd || IsFinish())
|
||||
{
|
||||
return m_FadeOuted ? startProgress : destProgress;
|
||||
}
|
||||
else if (IsInDelay() || IsInIndexDelay(dataIndex))
|
||||
{
|
||||
return m_FadeOut ? destProgress : startProgress;
|
||||
}
|
||||
else if (m_IsPause)
|
||||
{
|
||||
return currHig;
|
||||
}
|
||||
else
|
||||
{
|
||||
var duration = GetCurrAnimationDuration(dataIndex);
|
||||
var delta = (destProgress - startProgress) / duration * Time.deltaTime;
|
||||
currHig = currHig + (m_FadeOut ? -delta : delta);
|
||||
if (m_FadeOut)
|
||||
{
|
||||
if ((initHig > 0 && currHig <= 0) || (initHig < 0 && currHig >= 0))
|
||||
{
|
||||
currHig = 0;
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((destProgress - startProgress > 0 && currHig > destProgress) ||
|
||||
(destProgress - startProgress < 0 && currHig < destProgress))
|
||||
{
|
||||
currHig = destProgress;
|
||||
isEnd = true;
|
||||
}
|
||||
}
|
||||
SetDataCurrProgress(dataIndex, currHig);
|
||||
return currHig;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckSymbol(float dest)
|
||||
{
|
||||
if (!enable || m_IsEnd || m_IsPause || !m_IsInit)
|
||||
return;
|
||||
|
||||
if (IsInDelay())
|
||||
return;
|
||||
|
||||
var duration = GetCurrAnimationDuration();
|
||||
var delta = dest / duration * Time.deltaTime;
|
||||
if (m_FadeOut)
|
||||
{
|
||||
m_CurrSymbolProgress -= delta;
|
||||
if (m_CurrSymbolProgress < 0)
|
||||
m_CurrSymbolProgress = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_CurrSymbolProgress += delta;
|
||||
if (m_CurrSymbolProgress > dest)
|
||||
m_CurrSymbolProgress = dest;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetSysmbolSize(float dest)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return dest;
|
||||
#endif
|
||||
if (!enable)
|
||||
return dest;
|
||||
|
||||
if (m_IsEnd)
|
||||
return m_FadeOut ? 0 : dest;
|
||||
|
||||
return m_CurrSymbolProgress;
|
||||
}
|
||||
|
||||
public float GetCurrDetail()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return m_DestDetailProgress;
|
||||
#endif
|
||||
return m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public float GetCurrRate()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return 1;
|
||||
#endif
|
||||
if (!enable || m_IsEnd)
|
||||
return 1;
|
||||
return m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public int GetCurrIndex()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return -1;
|
||||
#endif
|
||||
if (!enable || m_IsEnd)
|
||||
return -1;
|
||||
return (int) m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
public float GetUpdateAnimationDuration()
|
||||
{
|
||||
if (m_Enable && m_DataChangeEnable && IsFinish())
|
||||
return m_DataChangeDuration;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool HasFadeOut()
|
||||
{
|
||||
return enable && m_FadeOuted && m_IsEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e31c30f2ef61c48718a626f93307ce92
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public struct AnimationStyleContext
|
||||
{
|
||||
public AnimationType type;
|
||||
public float currentPathDistance;
|
||||
public bool isAllItemAnimationEnd;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3dc504960589413fa6a76267067775c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
using UnityEngine;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class AnimationStyleHelper
|
||||
{
|
||||
public static float CheckDataAnimation(BaseChart chart, Serie serie, int dataIndex, float destProgress, float startPorgress = 0)
|
||||
{
|
||||
if (!serie.animation.IsItemAnimation())
|
||||
{
|
||||
serie.animation.context.isAllItemAnimationEnd = false;
|
||||
return destProgress;
|
||||
}
|
||||
if (serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.context.isAllItemAnimationEnd = false;
|
||||
return destProgress;
|
||||
}
|
||||
var isDataAnimationEnd = true;
|
||||
var currHig = serie.animation.CheckItemProgress(dataIndex, destProgress, ref isDataAnimationEnd, startPorgress);
|
||||
if (!isDataAnimationEnd)
|
||||
{
|
||||
serie.animation.context.isAllItemAnimationEnd = false;
|
||||
}
|
||||
return currHig;
|
||||
}
|
||||
|
||||
public static void UpdateSerieAnimation(Serie serie)
|
||||
{
|
||||
var serieType = serie.GetType();
|
||||
var animationType = AnimationType.LeftToRight;
|
||||
if (serieType.IsDefined(typeof(DefaultAnimationAttribute), false))
|
||||
{
|
||||
animationType = serieType.GetAttribute<DefaultAnimationAttribute>().type;
|
||||
}
|
||||
UpdateAnimationType(serie.animation, animationType);
|
||||
}
|
||||
|
||||
public static void UpdateAnimationType(AnimationStyle animation, AnimationType defaultType)
|
||||
{
|
||||
animation.context.type = animation.type == AnimationType.Default ?
|
||||
defaultType :
|
||||
animation.type;
|
||||
}
|
||||
|
||||
public static bool GetAnimationPosition(AnimationStyle animation, bool isY, Vector3 lp, Vector3 cp, float progress, ref Vector3 ip)
|
||||
{
|
||||
if (animation.context.type == AnimationType.AlongPath)
|
||||
{
|
||||
var dist = Vector3.Distance(lp, cp);
|
||||
var rate = (dist - animation.context.currentPathDistance + animation.GetCurrDetail()) / dist;
|
||||
ip = Vector3.Lerp(lp, cp, rate);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var startPos = isY ? new Vector3(-10000, progress) : new Vector3(progress, -10000);
|
||||
var endPos = isY ? new Vector3(10000, progress) : new Vector3(progress, 10000);
|
||||
|
||||
return UGLHelper.GetIntersection(lp, cp, startPos, endPos, ref ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 54cadaee0856b4f7085787fd450eec37
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 194a62edf7ec2484fa2eebbf5bde3e95
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28b88ca3453f04fbdb23a53b5bcb4bf7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Angle axis of Polar Coordinate.
|
||||
/// |极坐标系的角度轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(PolarCoord))]
|
||||
[ComponentHandler(typeof(AngleAxisHandler), true)]
|
||||
public class AngleAxis : Axis
|
||||
{
|
||||
[SerializeField] private float m_StartAngle = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Starting angle of axis. 0 degrees by default, standing for right position of center.
|
||||
/// |起始刻度的角度,默认为 0 度,即圆心的正右方。
|
||||
/// </summary>
|
||||
public float startAngle
|
||||
{
|
||||
get { return m_StartAngle; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_StartAngle, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public float GetValueAngle(float value)
|
||||
{
|
||||
return (value + context.startAngle + 360) % 360;
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
m_SplitNumber = 12;
|
||||
m_StartAngle = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 787015be923a74e1da4000c7abc2dcdf
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+164
@@ -0,0 +1,164 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class AngleAxisHandler : AxisHandler<AngleAxis>
|
||||
{
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitAngleAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
component.context.startAngle = 90 - component.startAngle;
|
||||
UpdateAxisMinMaxValue(component);
|
||||
UpdatePointerValue(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)
|
||||
{
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.offset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
UpdateAxisTickValueList(axis);
|
||||
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisLabelText(AngleAxis axis)
|
||||
{
|
||||
var runtimeWidth = 360;
|
||||
if (axis.context.labelObjectList.Count <= 0)
|
||||
InitAngleAxis(axis);
|
||||
else
|
||||
axis.UpdateLabelText(runtimeWidth, null, false);
|
||||
}
|
||||
|
||||
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();
|
||||
axis.context.startAngle = 90 - axis.startAngle;
|
||||
|
||||
string objName = component.GetType().Name + 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.context.startAngle;
|
||||
var total = 360;
|
||||
var cenPos = polar.context.center;
|
||||
var txtHig = axis.axisLabel.textStyle.GetFontSize(chart.theme.axis) + 2;
|
||||
var margin = axis.axisLabel.distance + axis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
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 + 1, 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(scaleAngle, txtHig), axis,
|
||||
chart.theme.axis, labelName, Color.clear);
|
||||
label.text.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.text, 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.context.startAngle;
|
||||
var tickWidth = angleAxis.axisTick.GetWidth(chart.theme.axis.tickWidth);
|
||||
var tickLength = angleAxis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
var tickColor = angleAxis.axisTick.GetColor(chart.theme.axis.lineColor);
|
||||
var lineColor = angleAxis.axisLine.GetColor(chart.theme.axis.lineColor);
|
||||
var splitLineColor = angleAxis.splitLine.GetColor(chart.theme.axis.splitLineColor);
|
||||
for (int i = 1; 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 lineWidth = angleAxis.splitLine.GetWidth(chart.theme.axis.splitLineWidth);
|
||||
UGL.DrawLine(vh, cenPos, pos, lineWidth, splitLineColor);
|
||||
}
|
||||
if (angleAxis.show && angleAxis.axisTick.show)
|
||||
{
|
||||
if ((i == 1 && angleAxis.axisTick.showStartTick) ||
|
||||
(i == size - 1 && angleAxis.axisTick.showEndTick) ||
|
||||
(i > 1 && i < size - 1))
|
||||
{
|
||||
var tickY = radius + tickLength;
|
||||
var tickPos = ChartHelper.GetPos(cenPos, tickY, currAngle, true);
|
||||
UGL.DrawLine(vh, pos, tickPos, tickWidth, tickColor);
|
||||
}
|
||||
}
|
||||
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, lineColor, Color.clear);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void UpdatePointerValue(Axis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
if (polar == null)
|
||||
return;
|
||||
|
||||
if (!polar.context.isPointerEnter)
|
||||
{
|
||||
axis.context.pointerValue = double.PositiveInfinity;
|
||||
return;
|
||||
}
|
||||
|
||||
var dir = (chart.pointerPos - new Vector2(polar.context.center.x, polar.context.center.y)).normalized;
|
||||
var angle = ChartHelper.GetAngle360(Vector2.up, dir);
|
||||
axis.context.pointerValue = (angle - component.context.startAngle + 360) % 360;
|
||||
axis.context.pointerLabelPosition = polar.context.center + new Vector3(dir.x, dir.y) * (polar.context.radius + 25);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 83f228c42435c4619943a2f187c98e7b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,791 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// The axis in rectangular coordinate.
|
||||
/// |直角坐标系的坐标轴组件。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class Axis : MainComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// the type of axis.
|
||||
/// |坐标轴类型。
|
||||
/// </summary>
|
||||
public enum AxisType
|
||||
{
|
||||
/// <summary>
|
||||
/// Numerical axis, suitable for continuous data.
|
||||
/// ||数值轴。适用于连续数据。
|
||||
/// </summary>
|
||||
Value,
|
||||
/// <summary>
|
||||
/// Category axis, suitable for discrete category data. Data should only be set via data for this type.
|
||||
/// ||类目轴。适用于离散的类目数据,为该类型时必须通过 data 设置类目数据。
|
||||
/// </summary>
|
||||
Category,
|
||||
/// <summary>
|
||||
/// Log axis, suitable for log data.
|
||||
/// |对数轴。适用于对数数据。
|
||||
/// </summary>
|
||||
Log,
|
||||
/// <summary>
|
||||
/// Time axis, suitable for continuous time series data.
|
||||
/// |时间轴。适用于连续的时序数据。
|
||||
/// </summary>
|
||||
Time
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the type of axis min and max value.
|
||||
/// |坐标轴最大最小刻度显示类型。
|
||||
/// </summary>
|
||||
public enum AxisMinMaxType
|
||||
{
|
||||
/// <summary>
|
||||
/// 0 - maximum.
|
||||
/// |0-最大值。
|
||||
/// </summary>
|
||||
Default,
|
||||
/// <summary>
|
||||
/// minimum - maximum.
|
||||
/// |最小值-最大值。
|
||||
/// </summary>
|
||||
MinMax,
|
||||
/// <summary>
|
||||
/// Customize the minimum and maximum.
|
||||
/// |自定义最小值最大值。
|
||||
/// </summary>
|
||||
Custom
|
||||
}
|
||||
/// <summary>
|
||||
/// the position of axis in grid.
|
||||
/// |坐标轴在Grid中的位置
|
||||
/// </summary>
|
||||
public enum AxisPosition
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Bottom,
|
||||
Top
|
||||
}
|
||||
|
||||
[SerializeField] protected bool m_Show = true;
|
||||
[SerializeField] protected AxisType m_Type;
|
||||
[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 double m_Min;
|
||||
[SerializeField] protected double m_Max;
|
||||
[SerializeField] protected int m_SplitNumber = 0;
|
||||
[SerializeField] protected double m_Interval = 0;
|
||||
[SerializeField] protected bool m_BoundaryGap = true;
|
||||
[SerializeField] protected int m_MaxCache = 0;
|
||||
[SerializeField] protected float m_LogBase = 10;
|
||||
[SerializeField] protected bool m_LogBaseE = false;
|
||||
[SerializeField] protected int m_CeilRate = 0;
|
||||
[SerializeField] protected bool m_Inverse = false;
|
||||
[SerializeField] private bool m_Clockwise = true;
|
||||
[SerializeField] private bool m_InsertDataToHead;
|
||||
[SerializeField] protected List<Sprite> m_Icons = new List<Sprite>();
|
||||
[SerializeField] protected List<string> m_Data = new List<string>();
|
||||
[SerializeField] protected AxisLine m_AxisLine = AxisLine.defaultAxisLine;
|
||||
[SerializeField] protected AxisName m_AxisName = AxisName.defaultAxisName;
|
||||
[SerializeField] protected AxisTick m_AxisTick = AxisTick.defaultTick;
|
||||
[SerializeField] protected AxisLabel m_AxisLabel = AxisLabel.defaultAxisLabel;
|
||||
[SerializeField] protected AxisSplitLine m_SplitLine = AxisSplitLine.defaultSplitLine;
|
||||
[SerializeField] protected AxisSplitArea m_SplitArea = AxisSplitArea.defaultSplitArea;
|
||||
|
||||
public AxisContext context = new AxisContext();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show axis.
|
||||
/// |是否显示坐标轴。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the type of axis.
|
||||
/// |坐标轴类型。
|
||||
/// </summary>
|
||||
public AxisType type
|
||||
{
|
||||
get { return m_Type; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Type, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the type of axis minmax.
|
||||
/// |坐标轴刻度最大最小值显示类型。
|
||||
/// </summary>
|
||||
public AxisMinMaxType minMaxType
|
||||
{
|
||||
get { return m_MinMaxType; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_MinMaxType, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The index of the grid on which the axis are located, by default, is in the first grid.
|
||||
/// |坐标轴所在的 grid 的索引,默认位于第一个 grid。
|
||||
/// </summary>
|
||||
public int gridIndex
|
||||
{
|
||||
get { return m_GridIndex; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_GridIndex, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The index of the polar on which the axis are located, by default, is in the first polar.
|
||||
/// |坐标轴所在的 ploar 的索引,默认位于第一个 polar。
|
||||
/// </summary>
|
||||
public int polarIndex
|
||||
{
|
||||
get { return m_PolarIndex; }
|
||||
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>
|
||||
public AxisPosition position
|
||||
{
|
||||
get { return m_Position; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Position, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the offset of axis from the default position. Useful when the same position has multiple axes.
|
||||
/// |坐标轴相对默认位置的偏移。在相同position有多个坐标轴时有用。
|
||||
/// </summary>
|
||||
public float offset
|
||||
{
|
||||
get { return m_Offset; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The minimun value of axis.Valid when `minMaxType` is `Custom`
|
||||
/// |设定的坐标轴刻度最小值,当minMaxType为Custom时有效。
|
||||
/// </summary>
|
||||
public double min
|
||||
{
|
||||
get { return m_Min; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Min, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The maximum value of axis.Valid when `minMaxType` is `Custom`
|
||||
/// |设定的坐标轴刻度最大值,当minMaxType为Custom时有效。
|
||||
/// </summary>
|
||||
public double max
|
||||
{
|
||||
get { return m_Max; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Max, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Number of segments that the axis is split into.
|
||||
/// |坐标轴的期望的分割段数。默认为0表示自动分割。
|
||||
/// </summary>
|
||||
public int splitNumber
|
||||
{
|
||||
get { return m_SplitNumber; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Compulsively set segmentation interval for axis.This is unavailable for category axis.
|
||||
/// |强制设置坐标轴分割间隔。无法在类目轴中使用。
|
||||
/// </summary>
|
||||
public double interval
|
||||
{
|
||||
get { return m_Interval; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The boundary gap on both sides of a coordinate axis, which is valid only for category axis with type: 'Category'.
|
||||
/// |坐标轴两边是否留白。只对类目轴有效。
|
||||
/// </summary>
|
||||
public bool boundaryGap
|
||||
{
|
||||
get { return IsCategory() ? m_BoundaryGap : false; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_BoundaryGap, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Base of logarithm, which is valid only for numeric axes with type: 'Log'.
|
||||
/// |对数轴的底数,只在对数轴(type:'Log')中有效。
|
||||
/// </summary>
|
||||
public float logBase
|
||||
{
|
||||
get { return m_LogBase; }
|
||||
set
|
||||
{
|
||||
if (value <= 0 || value == 1) value = 10;
|
||||
if (PropertyUtil.SetStruct(ref m_LogBase, value)) SetAllDirty();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// On the log axis, if base e is the natural number, and is true, logBase fails.
|
||||
/// |对数轴是否以自然数 e 为底数,为 true 时 logBase 失效。
|
||||
/// </summary>
|
||||
public bool logBaseE
|
||||
{
|
||||
get { return m_LogBaseE; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_LogBaseE, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The max number of axis data cache.
|
||||
/// |The first data will be remove when the size of axis data is larger then maxCache.
|
||||
/// |可缓存的最大数据量。默认为0没有限制,大于0时超过指定值会移除旧数据再插入新数据。
|
||||
/// </summary>
|
||||
public int maxCache
|
||||
{
|
||||
get { return m_MaxCache; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_MaxCache, value < 0 ? 0 : value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The ratio of maximum and minimum values rounded upward. The default is 0, which is automatically calculated.
|
||||
/// |最大最小值向上取整的倍率。默认为0时自动计算。
|
||||
/// </summary>
|
||||
public int ceilRate
|
||||
{
|
||||
get { return m_CeilRate; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_CeilRate, value < 0 ? 0 : value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether the axis are reversed or not. Invalid in `Category` axis.
|
||||
/// |是否反向坐标轴。在类目轴中无效。
|
||||
/// </summary>
|
||||
public bool inverse
|
||||
{
|
||||
get { return m_Inverse; }
|
||||
set { if (m_Type == AxisType.Value && PropertyUtil.SetStruct(ref m_Inverse, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether the positive position of axis is in clockwise. True for clockwise by default.
|
||||
/// |刻度增长是否按顺时针,默认顺时针。
|
||||
/// </summary>
|
||||
public bool clockwise
|
||||
{
|
||||
get { return m_Clockwise; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Clockwise, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Category data, available in type: 'Category' axis.
|
||||
/// |类目数据,在类目轴(type: 'category')中有效。
|
||||
/// </summary>
|
||||
public List<string> data
|
||||
{
|
||||
get { return m_Data; }
|
||||
set { if (value != null) { m_Data = value; SetAllDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// 类目数据对应的图标。
|
||||
/// </summary>
|
||||
public List<Sprite> icons
|
||||
{
|
||||
get { return m_Icons; }
|
||||
set { if (value != null) { m_Icons = value; SetAllDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// axis Line.
|
||||
/// |坐标轴轴线。
|
||||
/// </summary>
|
||||
public AxisLine axisLine
|
||||
{
|
||||
get { return m_AxisLine; }
|
||||
set { if (value != null) { m_AxisLine = value; SetVerticesDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// axis name.
|
||||
/// |坐标轴名称。
|
||||
/// </summary>
|
||||
public AxisName axisName
|
||||
{
|
||||
get { return m_AxisName; }
|
||||
set { if (value != null) { m_AxisName = value; SetComponentDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// axis tick.
|
||||
/// |坐标轴刻度。
|
||||
/// </summary>
|
||||
public AxisTick axisTick
|
||||
{
|
||||
get { return m_AxisTick; }
|
||||
set { if (value != null) { m_AxisTick = value; SetVerticesDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// axis label.
|
||||
/// |坐标轴刻度标签。
|
||||
/// </summary>
|
||||
public AxisLabel axisLabel
|
||||
{
|
||||
get { return m_AxisLabel; }
|
||||
set { if (value != null) { m_AxisLabel = value; SetComponentDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// axis split line.
|
||||
/// |坐标轴分割线。
|
||||
/// </summary>
|
||||
public AxisSplitLine splitLine
|
||||
{
|
||||
get { return m_SplitLine; }
|
||||
set { if (value != null) { m_SplitLine = value; SetVerticesDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// axis split area.
|
||||
/// |坐标轴分割区域。
|
||||
/// </summary>
|
||||
public AxisSplitArea splitArea
|
||||
{
|
||||
get { return m_SplitArea; }
|
||||
set { if (value != null) { m_SplitArea = value; SetVerticesDirty(); } }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to add new data at the head or at the end of the list.
|
||||
/// |添加新数据时是在列表的头部还是尾部加入。
|
||||
/// </summary>
|
||||
public bool insertDataToHead
|
||||
{
|
||||
get { return m_InsertDataToHead; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_InsertDataToHead, value)) SetAllDirty(); }
|
||||
}
|
||||
|
||||
public override bool vertsDirty
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_VertsDirty ||
|
||||
axisLine.anyDirty ||
|
||||
axisTick.anyDirty ||
|
||||
splitLine.anyDirty ||
|
||||
splitArea.anyDirty;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool componentDirty
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_ComponentDirty ||
|
||||
axisName.anyDirty ||
|
||||
axisLabel.anyDirty;
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
axisName.ClearComponentDirty();
|
||||
axisLabel.ClearComponentDirty();
|
||||
}
|
||||
|
||||
public override void ClearVerticesDirty()
|
||||
{
|
||||
base.ClearVerticesDirty();
|
||||
axisLine.ClearVerticesDirty();
|
||||
axisTick.ClearVerticesDirty();
|
||||
splitLine.ClearVerticesDirty();
|
||||
splitArea.ClearVerticesDirty();
|
||||
}
|
||||
|
||||
public override void SetComponentDirty()
|
||||
{
|
||||
context.isNeedUpdateFilterData = true;
|
||||
base.SetComponentDirty();
|
||||
}
|
||||
|
||||
public Axis Clone()
|
||||
{
|
||||
var axis = new Axis();
|
||||
axis.show = show;
|
||||
axis.type = type;
|
||||
axis.gridIndex = 0;
|
||||
axis.minMaxType = minMaxType;
|
||||
axis.min = min;
|
||||
axis.max = max;
|
||||
axis.splitNumber = splitNumber;
|
||||
axis.interval = interval;
|
||||
axis.boundaryGap = boundaryGap;
|
||||
axis.maxCache = maxCache;
|
||||
axis.logBase = logBase;
|
||||
axis.logBaseE = logBaseE;
|
||||
axis.ceilRate = ceilRate;
|
||||
axis.insertDataToHead = insertDataToHead;
|
||||
axis.axisLine = axisLine.Clone();
|
||||
axis.axisName = axisName.Clone();
|
||||
axis.axisTick = axisTick.Clone();
|
||||
axis.axisLabel = axisLabel.Clone();
|
||||
axis.splitLine = splitLine.Clone();
|
||||
axis.splitArea = splitArea.Clone();
|
||||
axis.icons = new List<Sprite>();
|
||||
axis.data = new List<string>();
|
||||
ChartHelper.CopyList(axis.data, data);
|
||||
return axis;
|
||||
}
|
||||
|
||||
public void Copy(Axis axis)
|
||||
{
|
||||
show = axis.show;
|
||||
type = axis.type;
|
||||
minMaxType = axis.minMaxType;
|
||||
gridIndex = axis.gridIndex;
|
||||
min = axis.min;
|
||||
max = axis.max;
|
||||
splitNumber = axis.splitNumber;
|
||||
interval = axis.interval;
|
||||
boundaryGap = axis.boundaryGap;
|
||||
maxCache = axis.maxCache;
|
||||
logBase = axis.logBase;
|
||||
logBaseE = axis.logBaseE;
|
||||
ceilRate = axis.ceilRate;
|
||||
insertDataToHead = axis.insertDataToHead;
|
||||
axisLine.Copy(axis.axisLine);
|
||||
axisName.Copy(axis.axisName);
|
||||
axisTick.Copy(axis.axisTick);
|
||||
axisLabel.Copy(axis.axisLabel);
|
||||
splitLine.Copy(axis.splitLine);
|
||||
splitArea.Copy(axis.splitArea);
|
||||
ChartHelper.CopyList(data, axis.data);
|
||||
ChartHelper.CopyList<Sprite>(icons, axis.icons);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空类目数据
|
||||
/// </summary>
|
||||
public override void ClearData()
|
||||
{
|
||||
m_Data.Clear();
|
||||
m_Icons.Clear();
|
||||
context.Clear();
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为类目轴。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsCategory()
|
||||
{
|
||||
return m_Type == AxisType.Category;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为数值轴。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsValue()
|
||||
{
|
||||
return m_Type == AxisType.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为对数轴。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool IsLog()
|
||||
{
|
||||
return m_Type == AxisType.Log;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为时间轴。
|
||||
/// </summary>
|
||||
public bool IsTime()
|
||||
{
|
||||
return m_Type == AxisType.Time;
|
||||
}
|
||||
|
||||
public bool IsLeft()
|
||||
{
|
||||
return m_Position == AxisPosition.Left;
|
||||
}
|
||||
|
||||
public bool IsRight()
|
||||
{
|
||||
return m_Position == AxisPosition.Right;
|
||||
}
|
||||
|
||||
public bool IsTop()
|
||||
{
|
||||
return m_Position == AxisPosition.Top;
|
||||
}
|
||||
|
||||
public bool IsBottom()
|
||||
{
|
||||
return m_Position == AxisPosition.Bottom;
|
||||
}
|
||||
|
||||
public void SetNeedUpdateFilterData()
|
||||
{
|
||||
context.isNeedUpdateFilterData = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加一个类目到类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="category"></param>
|
||||
public void AddData(string category)
|
||||
{
|
||||
if (maxCache > 0)
|
||||
{
|
||||
while (m_Data.Count >= maxCache)
|
||||
{
|
||||
RemoveData(m_InsertDataToHead ? m_Data.Count - 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_InsertDataToHead)
|
||||
m_Data.Insert(0, category);
|
||||
else
|
||||
m_Data.Add(category);
|
||||
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
public void RemoveData(int dataIndex)
|
||||
{
|
||||
context.isNeedUpdateFilterData = true;
|
||||
m_Data.RemoveAt(dataIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新类目数据
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="category"></param>
|
||||
public void UpdateData(int index, string category)
|
||||
{
|
||||
if (index >= 0 && index < m_Data.Count)
|
||||
{
|
||||
m_Data[index] = category;
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加图标
|
||||
/// </summary>
|
||||
/// <param name="icon"></param>
|
||||
public void AddIcon(Sprite icon)
|
||||
{
|
||||
if (maxCache > 0)
|
||||
{
|
||||
while (m_Icons.Count > maxCache)
|
||||
{
|
||||
m_Icons.RemoveAt(m_InsertDataToHead ? m_Icons.Count - 1 : 0);
|
||||
}
|
||||
}
|
||||
if (m_InsertDataToHead) m_Icons.Insert(0, icon);
|
||||
else m_Icons.Add(icon);
|
||||
SetAllDirty();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新图标
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="icon"></param>
|
||||
public void UpdateIcon(int index, Sprite icon)
|
||||
{
|
||||
if (index >= 0 && index < m_Icons.Count)
|
||||
{
|
||||
m_Icons[index] = icon;
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定索引的类目数据
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public string GetData(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_Data.Count)
|
||||
return m_Data[index];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得在dataZoom范围内指定索引的类目数据
|
||||
/// </summary>
|
||||
/// <param name="index">类目数据索引</param>
|
||||
/// <param name="dataZoom">区域缩放</param>
|
||||
/// <returns></returns>
|
||||
public string GetData(int index, DataZoom dataZoom)
|
||||
{
|
||||
var showData = GetDataList(dataZoom);
|
||||
if (index >= 0 && index < showData.Count)
|
||||
return showData[index];
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public Sprite GetIcon(int index)
|
||||
{
|
||||
if (index >= 0 && index < m_Icons.Count)
|
||||
return m_Icons[index];
|
||||
else
|
||||
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;
|
||||
|
||||
if (IsCategory() && boundaryGap)
|
||||
{
|
||||
var each = axisLength / data.Count;
|
||||
return (float) (each * (value + 0.5f));
|
||||
}
|
||||
else
|
||||
{
|
||||
return axisLength * (float) ((value - context.minValue) / context.minMaxRange);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定区域缩放的类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="dataZoom">区域缩放</param>
|
||||
/// <returns></returns>
|
||||
internal List<string> GetDataList(DataZoom dataZoom)
|
||||
{
|
||||
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
|
||||
{
|
||||
UpdateFilterData(dataZoom);
|
||||
return context.filterData;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Data.Count > 0 ? m_Data : context.runtimeData;
|
||||
}
|
||||
}
|
||||
|
||||
internal List<string> GetDataList()
|
||||
{
|
||||
return m_Data.Count > 0 ? m_Data : context.runtimeData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateFilterData(DataZoom dataZoom)
|
||||
{
|
||||
if (dataZoom != null && dataZoom.enable && dataZoom.IsContainsAxis(this))
|
||||
{
|
||||
var data = GetDataList();
|
||||
context.UpdateFilterData(data, dataZoom);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得类目数据个数
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
internal int GetDataCount(DataZoom dataZoom)
|
||||
{
|
||||
return IsCategory() ? GetDataList(dataZoom).Count : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新刻度标签文字
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent)
|
||||
{
|
||||
for (int i = 0; i < context.labelObjectList.Count; i++)
|
||||
{
|
||||
if (context.labelObjectList[i] != null)
|
||||
{
|
||||
var text = AxisHelper.GetLabelName(this, coordinateWidth, i, context.minValue, context.maxValue, dataZoom, forcePercent);
|
||||
context.labelObjectList[i].SetText(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal Vector3 GetLabelObjectPosition(int index)
|
||||
{
|
||||
if (context.labelObjectList != null && index < context.labelObjectList.Count)
|
||||
return context.labelObjectList[index].GetPosition();
|
||||
else
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
internal void UpdateMinMaxValue(double minValue, double maxValue)
|
||||
{
|
||||
context.minValue = minValue;
|
||||
context.maxValue = maxValue;
|
||||
double tempRange = maxValue - minValue;
|
||||
if (context.minMaxRange != tempRange)
|
||||
{
|
||||
context.minMaxRange = tempRange;
|
||||
if (type == Axis.AxisType.Value && interval > 0)
|
||||
{
|
||||
SetComponentDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetLogValue(double value)
|
||||
{
|
||||
if (value <= 0 || value == 1)
|
||||
return 0;
|
||||
else
|
||||
return logBaseE ? (float) Math.Log(value) : (float) Math.Log(value, logBase);
|
||||
}
|
||||
|
||||
public int GetLogMinIndex()
|
||||
{
|
||||
return logBaseE ?
|
||||
(int) Math.Log(context.minValue) :
|
||||
(int) Math.Log(context.minValue, logBase);
|
||||
}
|
||||
|
||||
public int GetLogMaxIndex()
|
||||
{
|
||||
return logBaseE ?
|
||||
(int) Math.Log(context.maxValue) :
|
||||
(int) Math.Log(context.maxValue, logBase);
|
||||
}
|
||||
|
||||
public double GetLabelValue(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return context.minValue;
|
||||
else if (index > context.labelValueList.Count - 1)
|
||||
return context.maxValue;
|
||||
else
|
||||
return context.labelValueList[index];
|
||||
}
|
||||
|
||||
public double GetLastLabelValue()
|
||||
{
|
||||
if (context.labelValueList.Count > 0)
|
||||
return context.labelValueList[context.labelValueList.Count - 1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d5c29555575e04db98ee243c3b17f0ed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public class AxisContext : MainComponentContext
|
||||
{
|
||||
public Orient orient;
|
||||
public float x;
|
||||
public float y;
|
||||
public float zeroX;
|
||||
public float zeroY;
|
||||
public float width;
|
||||
public float height;
|
||||
public Vector3 position;
|
||||
public float left;
|
||||
public float right;
|
||||
public float bottom;
|
||||
public float top;
|
||||
/// <summary>
|
||||
/// the current minimun value.
|
||||
/// |当前最小值。
|
||||
/// </summary>
|
||||
public double minValue;
|
||||
/// <summary>
|
||||
/// the current maximum value.
|
||||
/// |当前最大值。
|
||||
/// </summary>
|
||||
public double maxValue;
|
||||
/// <summary>
|
||||
/// the offset of zero position.
|
||||
/// |坐标轴原点在坐标轴的偏移。
|
||||
/// </summary>
|
||||
public float offset;
|
||||
public double minMaxRange;
|
||||
public float scaleWidth;
|
||||
public float startAngle;
|
||||
public double pointerValue;
|
||||
public Vector3 pointerLabelPosition;
|
||||
public double axisTooltipValue;
|
||||
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;
|
||||
internal bool isNeedUpdateFilterData;
|
||||
|
||||
private int filterStart;
|
||||
private int filterEnd;
|
||||
private int filterMinShow;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
if (range > data.Count - start - 1)
|
||||
start = data.Count - range - 1;
|
||||
if (start >= 0)
|
||||
filterData = data.GetRange(start, range);
|
||||
else
|
||||
filterData = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
filterData = data;
|
||||
}
|
||||
}
|
||||
else if (end == 0)
|
||||
{
|
||||
filterData = m_EmptyFliter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6525f065fa5d04663ab7026a3467f56e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,782 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XCharts.Runtime;
|
||||
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 float GetAxisLineXOrY()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected virtual Orient orient { get; set; }
|
||||
|
||||
protected virtual void UpdatePointerValue(Axis axis)
|
||||
{
|
||||
var grid = chart.GetChartComponent<GridCoord>(axis.gridIndex);
|
||||
if (grid == null)
|
||||
return;
|
||||
if (!grid.context.isPointerEnter)
|
||||
{
|
||||
axis.context.pointerValue = double.PositiveInfinity;
|
||||
}
|
||||
else
|
||||
{
|
||||
var lastPointerValue = axis.context.pointerValue;
|
||||
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;
|
||||
if (axis is YAxis)
|
||||
{
|
||||
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.height, dataCount, dataZoom);
|
||||
for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
|
||||
{
|
||||
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);
|
||||
if (j != lastPointerValue)
|
||||
{
|
||||
if (chart.onAxisPointerValueChanged != null)
|
||||
chart.onAxisPointerValueChanged(axis, j);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float splitWid = AxisHelper.GetDataWidth(axis, grid.context.width, dataCount, dataZoom);
|
||||
for (int j = 0; j < axis.GetDataCount(dataZoom); j++)
|
||||
{
|
||||
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);
|
||||
if (j != lastPointerValue)
|
||||
{
|
||||
if (chart.onAxisPointerValueChanged != null)
|
||||
chart.onAxisPointerValueChanged(axis, 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.offset);
|
||||
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);
|
||||
if (yValue != lastPointerValue)
|
||||
{
|
||||
if (chart.onAxisPointerValueChanged != null)
|
||||
chart.onAxisPointerValueChanged(axis, yValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var xRate = axis.context.minMaxRange / grid.context.width;
|
||||
var xValue = xRate * (chart.pointerPos.x - grid.context.x - axis.context.offset);
|
||||
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);
|
||||
if (xValue != lastPointerValue)
|
||||
{
|
||||
if (chart.onAxisPointerValueChanged != null)
|
||||
chart.onAxisPointerValueChanged(axis, xValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.offset = 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.offset = 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))))
|
||||
);
|
||||
axis.context.x = grid.context.x;
|
||||
axis.context.y = GetAxisLineXOrY();
|
||||
axis.context.zeroY = grid.context.y;
|
||||
axis.context.zeroX = grid.context.x - (float) (axis.context.minValue * grid.context.width / axis.context.minMaxRange);
|
||||
}
|
||||
if (grid != null && axis is YAxis && axis.IsValue())
|
||||
{
|
||||
axis.context.offset = 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))))
|
||||
);
|
||||
axis.context.x = GetAxisLineXOrY();
|
||||
axis.context.y = grid.context.y;
|
||||
axis.context.zeroX = grid.context.x;
|
||||
axis.context.zeroY = grid.context.y - (float) (axis.context.minValue * grid.context.height / axis.context.minMaxRange);
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (max <= 1) return max / 5;
|
||||
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.show || !axis.axisLabel.show)
|
||||
{
|
||||
label.SetTextActive(false);
|
||||
return;
|
||||
}
|
||||
if (axis.IsValue())
|
||||
{
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var dist = GetLabelPosition(0, 1).x - pos.x;
|
||||
label.SetTextActive(dist > label.text.GetPreferredWidth());
|
||||
}
|
||||
else if (i == axis.context.labelValueList.Count - 1)
|
||||
{
|
||||
var dist = pos.x - GetLabelPosition(0, i - 1).x;
|
||||
label.SetTextActive(dist > label.text.GetPreferredWidth());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
var dist = GetLabelPosition(0, 1).y - pos.y;
|
||||
label.SetTextActive(dist > label.text.GetPreferredHeight());
|
||||
}
|
||||
else if (i == axis.context.labelValueList.Count - 1)
|
||||
{
|
||||
var dist = pos.y - GetLabelPosition(0, i - 1).y;
|
||||
label.SetTextActive(dist > label.text.GetPreferredHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void InitAxis(Axis relativedAxis, Orient orient,
|
||||
float axisStartX, float axisStartY, float axisLength, float relativedLength)
|
||||
{
|
||||
Axis axis = component;
|
||||
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;
|
||||
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
var inside = axis.axisLabel.inside;
|
||||
var defaultAlignment = orient == Orient.Horizonal ? TextAnchor.MiddleCenter :
|
||||
((inside && axis.IsLeft()) || (!inside && axis.IsRight()) ?
|
||||
TextAnchor.MiddleLeft :
|
||||
TextAnchor.MiddleRight);
|
||||
|
||||
if (axis.IsCategory() && axis.boundaryGap)
|
||||
splitNumber -= 1;
|
||||
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
var labelWidth = AxisHelper.GetScaleWidth(axis, axisLength, i + 1, dataZoom);
|
||||
var labelName = AxisHelper.GetLabelName(axis, axisLength, i,
|
||||
axis.context.minValue,
|
||||
axis.context.maxValue,
|
||||
dataZoom, isPercentStack);
|
||||
|
||||
var label = ChartHelper.AddAxisLabelObject(splitNumber, i,
|
||||
ChartCached.GetAxisLabelName(i),
|
||||
axisObj.transform,
|
||||
new Vector2(textWidth, textHeight),
|
||||
axis, chart.theme.axis, labelName,
|
||||
Color.clear,
|
||||
defaultAlignment);
|
||||
|
||||
if (i == 0)
|
||||
axis.axisLabel.SetRelatedText(label.text, labelWidth);
|
||||
|
||||
var pos = GetLabelPosition(totalWidth + gapWidth, i);
|
||||
label.SetPosition(pos);
|
||||
CheckValueLabelActive(axis, i, label, pos);
|
||||
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalWidth += labelWidth;
|
||||
}
|
||||
if (axis.axisName.show)
|
||||
{
|
||||
ChartLabel label = null;
|
||||
var relativedDist = (relativedAxis == null ? 0 : relativedAxis.context.offset);
|
||||
var zeroPos = new Vector3(axisStartX, axisStartY + relativedDist);
|
||||
var offset = axis.axisName.labelStyle.offset;
|
||||
var autoColor = axis.axisLine.GetColor(chart.theme.axis.lineColor);
|
||||
if (orient == Orient.Horizonal)
|
||||
{
|
||||
var posY = GetAxisLineXOrY() + offset.y;
|
||||
switch (axis.axisName.labelStyle.position)
|
||||
{
|
||||
case LabelStyle.Position.Start:
|
||||
|
||||
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
|
||||
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleRight);
|
||||
label.SetActive(axis.axisName.labelStyle.show);
|
||||
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
|
||||
new Vector2(zeroPos.x - offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
|
||||
new Vector2(zeroPos.x - offset.x, posY));
|
||||
break;
|
||||
|
||||
case LabelStyle.Position.Middle:
|
||||
|
||||
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
|
||||
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
|
||||
label.SetActive(axis.axisName.labelStyle.show);
|
||||
label.SetPosition(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, posY));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
|
||||
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleLeft);
|
||||
label.SetActive(axis.axisName.labelStyle.show);
|
||||
label.SetPosition(axis.position == Axis.AxisPosition.Top ?
|
||||
new Vector2(axisStartX + axisLength + offset.x, axisStartY + relativedLength + offset.y + axis.offset) :
|
||||
new Vector2(axisStartX + axisLength + offset.x, posY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var posX = GetAxisLineXOrY() + offset.x;
|
||||
switch (axis.axisName.labelStyle.position)
|
||||
{
|
||||
case LabelStyle.Position.Start:
|
||||
|
||||
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
|
||||
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
|
||||
label.SetActive(axis.axisName.labelStyle.show);
|
||||
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY - offset.y) :
|
||||
new Vector2(posX, axisStartY - offset.y));
|
||||
break;
|
||||
|
||||
case LabelStyle.Position.Middle:
|
||||
|
||||
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
|
||||
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
|
||||
label.SetActive(axis.axisName.labelStyle.show);
|
||||
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength - offset.x + axis.offset, axisStartY + axisLength / 2 + offset.y) :
|
||||
new Vector2(posX, axisStartY + axisLength / 2 + offset.y));
|
||||
break;
|
||||
|
||||
default:
|
||||
//LabelStyle.Position
|
||||
label = ChartHelper.AddChartLabel(s_DefaultAxisName, axisObj.transform, axis.axisName.labelStyle,
|
||||
chart.theme.axis, axis.axisName.name, autoColor, TextAnchor.MiddleCenter);
|
||||
label.SetActive(axis.axisName.labelStyle.show);
|
||||
label.SetPosition(axis.position == Axis.AxisPosition.Right ?
|
||||
new Vector2(axisStartX + relativedLength + offset.x + axis.offset, axisStartY + axisLength + offset.y) :
|
||||
new Vector2(posX, axisStartY + axisLength + offset.y));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.offset;
|
||||
|
||||
if (axis.IsTop())
|
||||
axisStartY += relativedLength;
|
||||
|
||||
if ((inside && axis.IsBottom()) || (!inside && axis.IsTop()))
|
||||
current += axisStartY + axis.axisLabel.distance + fontSize / 2;
|
||||
else
|
||||
current += axisStartY - axis.axisLabel.distance - fontSize / 2;
|
||||
|
||||
return new Vector3(axisStartX + scaleWid, current) + axis.axisLabel.offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.axisLabel.onZero && relativedAxis != null)
|
||||
axisStartX += relativedAxis.context.offset;
|
||||
|
||||
if (axis.IsRight())
|
||||
axisStartX += relativedLength;
|
||||
|
||||
if ((inside && axis.IsLeft()) || (!inside && axis.IsRight()))
|
||||
current += axisStartX + axis.axisLabel.distance;
|
||||
else
|
||||
current += axisStartX - axis.axisLabel.distance;
|
||||
|
||||
return new Vector3(current, axisStartY + scaleWid) + axis.axisLabel.offset;
|
||||
}
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawAxisSplit(VertexHelper vh, AxisTheme theme, DataZoom dataZoom,
|
||||
Orient orient, float startX, float startY, float axisLength, float splitLength, Axis relativedAxis = null)
|
||||
{
|
||||
Axis axis = component;
|
||||
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)
|
||||
{
|
||||
if (relativedAxis == null || !MathUtil.Approximately(current, GetAxisLineXOrY()))
|
||||
ChartDrawer.DrawLineStyle(vh,
|
||||
lineType,
|
||||
lineWidth,
|
||||
new Vector3(current, startY),
|
||||
new Vector3(current, startY + splitLength),
|
||||
lineColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (relativedAxis == null || !MathUtil.Approximately(current, GetAxisLineXOrY()))
|
||||
ChartDrawer.DrawLineStyle(vh,
|
||||
lineType,
|
||||
lineWidth,
|
||||
new Vector3(startX, current),
|
||||
new Vector3(startX + splitLength, current),
|
||||
lineColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
current += scaleWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0babef8a2708b4745bbb0a0648913a35
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,561 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
public static class AxisHelper
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 包含箭头偏移的轴线长度
|
||||
/// </summary>
|
||||
/// <param name="axis"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetAxisLineArrowOffset(Axis axis)
|
||||
{
|
||||
if (axis.axisLine.show && axis.axisLine.showArrow && axis.axisLine.arrow.offset > 0)
|
||||
{
|
||||
return axis.axisLine.arrow.offset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得分割段数
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)
|
||||
{
|
||||
if (axis.type == Axis.AxisType.Value)
|
||||
{
|
||||
return axis.context.labelValueList.Count - 1;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
return axis.context.labelValueList.Count;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
return axis.splitNumber > 0 ? axis.splitNumber : 4;
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Category)
|
||||
{
|
||||
int dataCount = axis.GetDataList(dataZoom).Count;
|
||||
if (!axis.boundaryGap)
|
||||
dataCount -= 1;
|
||||
if (dataCount <= 0)
|
||||
dataCount = 1;
|
||||
|
||||
if (axis.splitNumber <= 0)
|
||||
{
|
||||
if (dataCount <= 10) return dataCount;
|
||||
else
|
||||
{
|
||||
for (int i = 4; i < 6; i++)
|
||||
{
|
||||
if (dataCount % i == 0) return i;
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.splitNumber <= 0 || axis.splitNumber > dataCount)
|
||||
return dataCount;
|
||||
if (dataCount >= axis.splitNumber * 2)
|
||||
return axis.splitNumber;
|
||||
else
|
||||
return dataCount;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得一个类目数据在坐标系中代表的宽度
|
||||
/// </summary>
|
||||
/// <param name="coordinateWidth"></param>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)
|
||||
{
|
||||
if (dataCount < 1)
|
||||
dataCount = 1;
|
||||
if (axis.IsValue())
|
||||
return dataCount > 1 ? coordinateWidth / (dataCount - 1) : coordinateWidth;
|
||||
var categoryCount = axis.GetDataCount(dataZoom);
|
||||
int segment = (axis.boundaryGap ? categoryCount : categoryCount - 1);
|
||||
segment = segment <= 0 ? dataCount : segment;
|
||||
if (segment <= 0)
|
||||
segment = 1;
|
||||
|
||||
return coordinateWidth / segment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得标签显示的名称
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="minValue"></param>
|
||||
/// <param name="maxValue"></param>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetLabelName(Axis axis, float coordinateWidth, int index, double minValue, double maxValue,
|
||||
DataZoom dataZoom, bool forcePercent)
|
||||
{
|
||||
int split = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (axis.type == Axis.AxisType.Value)
|
||||
{
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
maxValue = axis.max != 0 ? axis.max : 1;
|
||||
double value = 0;
|
||||
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);
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
double value = axis.logBaseE ?
|
||||
System.Math.Exp(axis.GetLogMinIndex() + index) :
|
||||
System.Math.Pow(axis.logBase, axis.GetLogMinIndex() + index);
|
||||
if (axis.inverse)
|
||||
{
|
||||
value = -value;
|
||||
minValue = -minValue;
|
||||
maxValue = -maxValue;
|
||||
}
|
||||
return axis.axisLabel.GetFormatterContent(index, value, minValue, maxValue, true);
|
||||
}
|
||||
else if (axis.type == Axis.AxisType.Time)
|
||||
{
|
||||
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 "";
|
||||
int rate = axis.boundaryGap ? (dataCount / split) : (dataCount - 1) / split;
|
||||
if (rate == 0) rate = 1;
|
||||
if (axis.insertDataToHead)
|
||||
{
|
||||
if (index > 0)
|
||||
{
|
||||
var residue = (dataCount - 1) - split * rate;
|
||||
var newIndex = residue + (index - 1) * rate;
|
||||
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]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int newIndex = index * rate;
|
||||
if (newIndex < dataCount)
|
||||
{
|
||||
return axis.axisLabel.GetFormatterContent(newIndex, showData[newIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (axis.boundaryGap && coordinateWidth / dataCount > 5)
|
||||
return string.Empty;
|
||||
else
|
||||
return axis.axisLabel.GetFormatterContent(dataCount - 1, showData[dataCount - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得分割线条数
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
|
||||
{
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (splitNum == 0)
|
||||
return 0;
|
||||
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
var dataCount = axis.GetDataList(dataZoom).Count;
|
||||
var scaleNum = 0;
|
||||
|
||||
if (axis.boundaryGap)
|
||||
{
|
||||
scaleNum = dataCount > 2 && dataCount % splitNum == 0 ?
|
||||
splitNum + 1 :
|
||||
splitNum + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dataCount < splitNum) scaleNum = splitNum;
|
||||
else scaleNum = dataCount > 2 && dataCount % splitNum == 0 ?
|
||||
splitNum :
|
||||
splitNum + 1;
|
||||
}
|
||||
return scaleNum;
|
||||
}
|
||||
else if (axis.IsTime())
|
||||
return splitNum;
|
||||
else
|
||||
return splitNum + 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得分割段宽度
|
||||
/// </summary>
|
||||
/// <param name="coordinateWidth"></param>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)
|
||||
{
|
||||
if (index < 0)
|
||||
return 0;
|
||||
|
||||
int num = GetScaleNumber(axis, coordinateWidth, dataZoom);
|
||||
int splitNum = GetSplitNumber(axis, coordinateWidth, dataZoom);
|
||||
if (num <= 0)
|
||||
num = 1;
|
||||
|
||||
if (axis.IsTime() || axis.IsValue())
|
||||
{
|
||||
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
|
||||
{
|
||||
var data = axis.GetDataList(dataZoom);
|
||||
if (axis.IsCategory() && data.Count > 0)
|
||||
{
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
int tick = count / splitNum;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (count < splitNum)
|
||||
return each;
|
||||
else
|
||||
return each * (count / splitNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var max = axis.boundaryGap ? num - 1 : num;
|
||||
if (index >= max)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (splitNum <= 0)
|
||||
return 0;
|
||||
else
|
||||
return coordinateWidth / splitNum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)
|
||||
{
|
||||
var data = axis.GetDataList(dataZoom);
|
||||
if (data.Count > 0)
|
||||
{
|
||||
var count = axis.boundaryGap ? data.Count : data.Count - 1;
|
||||
return count > 0 ? coordinateWidth / count : coordinateWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
int num = GetScaleNumber(axis, coordinateWidth, dataZoom) - 1;
|
||||
return num > 0 ? coordinateWidth / num : coordinateWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 调整最大最小值
|
||||
/// </summary>
|
||||
/// <param name="minValue"></param>
|
||||
/// <param name="maxValue"></param>
|
||||
public static void AdjustMinMaxValue(Axis axis, ref double minValue, ref double maxValue, bool needFormat, int ceilRate = 0)
|
||||
{
|
||||
if (axis.type == Axis.AxisType.Log)
|
||||
{
|
||||
int minSplit = 0;
|
||||
int maxSplit = 0;
|
||||
maxValue = ChartHelper.GetMaxLogValue(maxValue, axis.logBase, axis.logBaseE, out maxSplit);
|
||||
minValue = ChartHelper.GetMinLogValue(minValue, axis.logBase, axis.logBaseE, out minSplit);
|
||||
axis.splitNumber = (minSplit > 0 && maxSplit > 0) ? (maxSplit + minSplit - 1) : (maxSplit + minSplit);
|
||||
return;
|
||||
}
|
||||
if (axis.type == Axis.AxisType.Time)
|
||||
{ }
|
||||
else if (axis.minMaxType == Axis.AxisMinMaxType.Custom)
|
||||
{
|
||||
if (axis.min != 0 || axis.max != 0)
|
||||
{
|
||||
if (axis.inverse)
|
||||
{
|
||||
minValue = -axis.max;
|
||||
maxValue = -axis.min;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = axis.min;
|
||||
maxValue = axis.max;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ceilRate == 0) ceilRate = axis.ceilRate;
|
||||
switch (axis.minMaxType)
|
||||
{
|
||||
case Axis.AxisMinMaxType.Default:
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
{ }
|
||||
else if (minValue > 0 && maxValue > 0)
|
||||
{
|
||||
minValue = 0;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
else if (minValue < 0 && maxValue < 0)
|
||||
{
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = needFormat ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = needFormat ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
}
|
||||
break;
|
||||
|
||||
case Axis.AxisMinMaxType.MinMax:
|
||||
|
||||
minValue = ceilRate != 0 ? ChartHelper.GetMinDivisibleValue(minValue, ceilRate) : minValue;
|
||||
maxValue = ceilRate != 0 ? ChartHelper.GetMaxDivisibleValue(maxValue, ceilRate) : maxValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool NeedShowSplit(Axis axis)
|
||||
{
|
||||
if (!axis.show)
|
||||
return false;
|
||||
if (axis.IsCategory() && axis.GetDataList().Count <= 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void AdjustCircleLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
|
||||
{
|
||||
var txtWidth = txt.text.GetPreferredWidth();
|
||||
var sizeDelta = new Vector2(txtWidth, txt.text.GetPreferredHeight());
|
||||
txt.text.SetSizeDelta(sizeDelta);
|
||||
var diff = pos.x - cenPos.x;
|
||||
if (diff < -1f) //left
|
||||
{
|
||||
pos = new Vector3(pos.x - txtWidth / 2, pos.y);
|
||||
}
|
||||
else if (diff > 1f) //right
|
||||
{
|
||||
pos = new Vector3(pos.x + txtWidth / 2, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2;
|
||||
pos = new Vector3(pos.x, y);
|
||||
}
|
||||
txt.SetPosition(pos + offset);
|
||||
}
|
||||
|
||||
public static void AdjustRadiusAxisLabelPos(ChartLabel txt, Vector3 pos, Vector3 cenPos, float txtHig, Vector3 offset)
|
||||
{
|
||||
var txtWidth = txt.text.GetPreferredWidth();
|
||||
var sizeDelta = new Vector2(txtWidth, txt.text.GetPreferredHeight());
|
||||
txt.text.SetSizeDelta(sizeDelta);
|
||||
var diff = pos.y - cenPos.y;
|
||||
if (diff > 20f) //left
|
||||
{
|
||||
pos = new Vector3(pos.x - txtWidth / 2, pos.y);
|
||||
}
|
||||
else if (diff < -20f) //right
|
||||
{
|
||||
pos = new Vector3(pos.x + txtWidth / 2, pos.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
float y = pos.y > cenPos.y ? pos.y + txtHig / 2 : pos.y - txtHig / 2;
|
||||
pos = new Vector3(pos.x, y);
|
||||
}
|
||||
txt.SetPosition(pos);
|
||||
}
|
||||
|
||||
public static float GetAxisPosition(GridCoord grid, Axis axis, double value, int dataCount = 0, DataZoom dataZoom = null)
|
||||
{
|
||||
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, gridHeight, dataCount, dataZoom);
|
||||
float startY = gridXY + (axis.boundaryGap ? scaleWid / 2 : 0);
|
||||
return startY + scaleWid * categoryIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
var yDataHig = (axis.context.minMaxRange == 0) ? 0f :
|
||||
(float) ((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
|
||||
return gridXY + yDataHig;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static double GetAxisPositionValue(GridCoord grid, Axis axis, Vector3 pos)
|
||||
{
|
||||
if (axis is YAxis)
|
||||
return GetAxisPositionValue(pos.y, grid.context.height, axis.context.minMaxRange, grid.context.y, axis.context.offset);
|
||||
else if (axis is XAxis)
|
||||
return GetAxisPositionValue(pos.x, grid.context.width, axis.context.minMaxRange, grid.context.x, axis.context.offset);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static double GetAxisPositionValue(float xy, float axisLength, double axisRange, float axisStart, float axisOffset)
|
||||
{
|
||||
var yRate = axisRange / axisLength;
|
||||
return yRate * (xy - axisStart - axisOffset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得数值value在坐标轴上的坐标位置
|
||||
/// </summary>
|
||||
/// <param name="grid"></param>
|
||||
/// <param name="axis"></param>
|
||||
/// <param name="scaleWidth"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)
|
||||
{
|
||||
return GetAxisPositionInternal(grid, axis, scaleWidth, value, true, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得数值value在坐标轴上相对起点的距离
|
||||
/// </summary>
|
||||
/// <param name="grid"></param>
|
||||
/// <param name="axis"></param>
|
||||
/// <param name="scaleWidth"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)
|
||||
{
|
||||
return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得数值value在坐标轴上对应的长度
|
||||
/// </summary>
|
||||
/// <param name="grid"></param>
|
||||
/// <param name="axis"></param>
|
||||
/// <param name="scaleWidth"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)
|
||||
{
|
||||
return GetAxisPositionInternal(grid, axis, scaleWidth, value, false, true);
|
||||
}
|
||||
|
||||
private static float GetAxisPositionInternal(GridCoord grid, Axis axis, float scaleWidth, double value, bool includeGridXY, bool realLength)
|
||||
{
|
||||
var isY = axis is YAxis;
|
||||
var gridHeight = isY ? grid.context.height : grid.context.width;
|
||||
var gridXY = isY ? grid.context.y : grid.context.x;
|
||||
|
||||
if (axis.IsLog())
|
||||
{
|
||||
int minIndex = axis.GetLogMinIndex();
|
||||
float nowIndex = axis.GetLogValue(value);
|
||||
return includeGridXY ?
|
||||
gridXY + (nowIndex - minIndex) / axis.splitNumber * gridHeight :
|
||||
(nowIndex - minIndex) / axis.splitNumber * gridHeight;
|
||||
}
|
||||
else if (axis.IsCategory())
|
||||
{
|
||||
var categoryIndex = (int) value;
|
||||
return includeGridXY ?
|
||||
gridXY + (axis.boundaryGap ? scaleWidth / 2 : 0) + scaleWidth * categoryIndex :
|
||||
(axis.boundaryGap ? scaleWidth / 2 : 0) + scaleWidth * categoryIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
var yDataHig = 0f;
|
||||
if (axis.context.minMaxRange != 0)
|
||||
{
|
||||
if (realLength)
|
||||
yDataHig = (float) (value * gridHeight / axis.context.minMaxRange);
|
||||
else
|
||||
yDataHig = (float) ((value - axis.context.minValue) / axis.context.minMaxRange * gridHeight);
|
||||
}
|
||||
return includeGridXY ?
|
||||
gridXY + yDataHig :
|
||||
yDataHig;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 566e3426780cc4339a1fb92d9604d21f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to axis label.
|
||||
/// |坐标轴刻度标签的相关设置。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisLabel : LabelStyle
|
||||
{
|
||||
[SerializeField] private int m_Interval = 0;
|
||||
[SerializeField] private bool m_Inside = false;
|
||||
[SerializeField] private bool m_ShowAsPositiveNumber = false;
|
||||
[SerializeField] private bool m_OnZero = false;
|
||||
[SerializeField] private bool m_ShowStartLabel = true;
|
||||
[SerializeField] private bool m_ShowEndLabel = true;
|
||||
[SerializeField] private TextLimit m_TextLimit = new TextLimit();
|
||||
|
||||
/// <summary>
|
||||
/// The display interval of the axis label.
|
||||
/// |坐标轴刻度标签的显示间隔,在类目轴中有效。0表示显示所有标签,1表示隔一个隔显示一个标签,以此类推。
|
||||
/// </summary>
|
||||
public int interval
|
||||
{
|
||||
get { return m_Interval; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Set this to true so the axis labels face the inside direction.
|
||||
/// |刻度标签是否朝内,默认朝外。
|
||||
/// </summary>
|
||||
public bool inside
|
||||
{
|
||||
get { return m_Inside; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Inside, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Show negative number as positive number.
|
||||
/// |将负数数值显示为正数。一般和`Serie`的`showAsPositiveNumber`配合使用。
|
||||
/// </summary>
|
||||
public bool showAsPositiveNumber
|
||||
{
|
||||
get { return m_ShowAsPositiveNumber; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowAsPositiveNumber, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刻度标签显示在0刻度上。
|
||||
/// </summary>
|
||||
public bool onZero
|
||||
{
|
||||
get { return m_OnZero; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_OnZero, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the first label.
|
||||
/// |是否显示第一个文本。
|
||||
/// </summary>
|
||||
public bool showStartLabel
|
||||
{
|
||||
get { return m_ShowStartLabel; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowStartLabel, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the last label.
|
||||
/// |是否显示最后一个文本。
|
||||
/// </summary>
|
||||
public bool showEndLabel
|
||||
{
|
||||
get { return m_ShowEndLabel; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowEndLabel, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 文本限制。
|
||||
/// </summary>
|
||||
public TextLimit textLimit
|
||||
{
|
||||
get { return m_TextLimit; }
|
||||
set { if (value != null) { m_TextLimit = value; SetComponentDirty(); } }
|
||||
}
|
||||
|
||||
public override bool componentDirty { get { return m_ComponentDirty || m_TextLimit.componentDirty; } }
|
||||
public override void ClearComponentDirty()
|
||||
{
|
||||
base.ClearComponentDirty();
|
||||
textLimit.ClearComponentDirty();
|
||||
}
|
||||
|
||||
public static AxisLabel defaultAxisLabel
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisLabel()
|
||||
{
|
||||
m_Show = true,
|
||||
m_Interval = 0,
|
||||
m_Inside = false,
|
||||
m_Distance = 8,
|
||||
m_TextStyle = new TextStyle(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public new AxisLabel Clone()
|
||||
{
|
||||
var axisLabel = new AxisLabel();
|
||||
axisLabel.show = show;
|
||||
axisLabel.formatter = formatter;
|
||||
axisLabel.interval = interval;
|
||||
axisLabel.inside = inside;
|
||||
axisLabel.distance = distance;
|
||||
axisLabel.numericFormatter = numericFormatter;
|
||||
axisLabel.width = width;
|
||||
axisLabel.height = height;
|
||||
axisLabel.showStartLabel = showStartLabel;
|
||||
axisLabel.showEndLabel = showEndLabel;
|
||||
axisLabel.textLimit = textLimit.Clone();
|
||||
axisLabel.textStyle.Copy(textStyle);
|
||||
return axisLabel;
|
||||
}
|
||||
|
||||
public void Copy(AxisLabel axisLabel)
|
||||
{
|
||||
show = axisLabel.show;
|
||||
formatter = axisLabel.formatter;
|
||||
interval = axisLabel.interval;
|
||||
inside = axisLabel.inside;
|
||||
distance = axisLabel.distance;
|
||||
numericFormatter = axisLabel.numericFormatter;
|
||||
width = axisLabel.width;
|
||||
height = axisLabel.height;
|
||||
showStartLabel = axisLabel.showStartLabel;
|
||||
showEndLabel = axisLabel.showEndLabel;
|
||||
textLimit.Copy(axisLabel.textLimit);
|
||||
textStyle.Copy(axisLabel.textStyle);
|
||||
}
|
||||
|
||||
public void SetRelatedText(ChartText txt, float labelWidth)
|
||||
{
|
||||
m_TextLimit.SetRelatedText(txt, labelWidth);
|
||||
}
|
||||
|
||||
public string GetFormatterContent(int labelIndex, string category)
|
||||
{
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, 0, category);
|
||||
}
|
||||
if (string.IsNullOrEmpty(category))
|
||||
return category;
|
||||
|
||||
if (string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
return m_TextLimit.GetLimitContent(category);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, category);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFormatterContent(int labelIndex, double value, double minValue, double maxValue, bool isLog = false)
|
||||
{
|
||||
if (showAsPositiveNumber && value < 0)
|
||||
{
|
||||
value = Math.Abs(value);
|
||||
}
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, value, null);
|
||||
}
|
||||
if (string.IsNullOrEmpty(m_Formatter))
|
||||
{
|
||||
if (isLog)
|
||||
{
|
||||
return ChartCached.NumberToStr(value, numericFormatter);
|
||||
}
|
||||
if (minValue >= -1 && minValue <= 1 && maxValue >= -1 && maxValue <= 1)
|
||||
{
|
||||
int minAcc = ChartHelper.GetFloatAccuracy(minValue);
|
||||
int maxAcc = ChartHelper.GetFloatAccuracy(maxValue);
|
||||
int curAcc = ChartHelper.GetFloatAccuracy(value);
|
||||
int acc = Mathf.Max(Mathf.Max(minAcc, maxAcc), curAcc);
|
||||
return ChartCached.FloatToStr(value, numericFormatter, acc);
|
||||
}
|
||||
return ChartCached.NumberToStr(value, numericFormatter);
|
||||
}
|
||||
else
|
||||
{
|
||||
var content = m_Formatter;
|
||||
FormatterHelper.ReplaceAxisLabelContent(ref content, numericFormatter, value);
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetFormatterDateTime(int labelIndex, double value, double minValue, double maxValue)
|
||||
{
|
||||
if (m_FormatterFunction != null)
|
||||
{
|
||||
return m_FormatterFunction(labelIndex, value, null);
|
||||
}
|
||||
var timestamp = (int) value;
|
||||
var dateTime = DateTimeUtil.GetDateTime(timestamp);
|
||||
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, dateString);
|
||||
return m_TextLimit.GetLimitContent(content);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_TextLimit.GetLimitContent(dateString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 051f9473d1beb4e0bb35aa1600cb44bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to axis line.
|
||||
/// |坐标轴轴线。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AxisLine : BaseLine
|
||||
{
|
||||
[SerializeField] private bool m_OnZero;
|
||||
[SerializeField] private bool m_ShowArrow;
|
||||
[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.
|
||||
/// |X 轴或者 Y 轴的轴线是否在另一个轴的 0 刻度上,只有在另一个轴为数值轴且包含 0 刻度时有效。
|
||||
/// </summary>
|
||||
public bool onZero
|
||||
{
|
||||
get { return m_OnZero; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_OnZero, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to show the arrow symbol of axis.
|
||||
/// |是否显示箭头。
|
||||
/// </summary>
|
||||
public bool showArrow
|
||||
{
|
||||
get { return m_ShowArrow; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowArrow, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the arrow of line.
|
||||
/// |轴线箭头。
|
||||
/// </summary>
|
||||
public ArrowStyle arrow
|
||||
{
|
||||
get { return m_Arrow; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Arrow, value)) SetVerticesDirty(); }
|
||||
}
|
||||
public static AxisLine defaultAxisLine
|
||||
{
|
||||
get
|
||||
{
|
||||
var axisLine = new AxisLine
|
||||
{
|
||||
m_Show = true,
|
||||
m_OnZero = true,
|
||||
m_ShowArrow = false,
|
||||
m_Arrow = new ArrowStyle(),
|
||||
m_LineStyle = new LineStyle(LineStyle.Type.None),
|
||||
};
|
||||
return axisLine;
|
||||
}
|
||||
}
|
||||
|
||||
public AxisLine Clone()
|
||||
{
|
||||
var axisLine = new AxisLine();
|
||||
axisLine.show = show;
|
||||
axisLine.onZero = onZero;
|
||||
axisLine.showArrow = showArrow;
|
||||
axisLine.arrow = arrow.Clone();
|
||||
return axisLine;
|
||||
}
|
||||
|
||||
public void Copy(AxisLine axisLine)
|
||||
{
|
||||
base.Copy(axisLine);
|
||||
onZero = axisLine.onZero;
|
||||
showArrow = axisLine.showArrow;
|
||||
arrow.Copy(axisLine.arrow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2748c2a8789724709aa76f6056eb708d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// the name of axis.
|
||||
/// |坐标轴名称。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisName : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private string m_Name;
|
||||
[SerializeField] private LabelStyle m_LabelStyle = new LabelStyle();
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show axis name.
|
||||
/// |是否显示坐标名称。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the name of axis.
|
||||
/// |坐标轴名称。
|
||||
/// </summary>
|
||||
public string name
|
||||
{
|
||||
get { return m_Name; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Name, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The text style of axis name.
|
||||
/// |文本样式。
|
||||
/// </summary>
|
||||
public LabelStyle labelStyle
|
||||
{
|
||||
get { return m_LabelStyle; }
|
||||
set { if (PropertyUtil.SetClass(ref m_LabelStyle, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
public static AxisName defaultAxisName
|
||||
{
|
||||
get
|
||||
{
|
||||
var axisName = new AxisName()
|
||||
{
|
||||
m_Show = false,
|
||||
m_Name = "axisName",
|
||||
m_LabelStyle = new LabelStyle()
|
||||
};
|
||||
axisName.labelStyle.position = LabelStyle.Position.End;
|
||||
return axisName;
|
||||
}
|
||||
}
|
||||
|
||||
public AxisName Clone()
|
||||
{
|
||||
var axisName = new AxisName();
|
||||
axisName.show = show;
|
||||
axisName.name = name;
|
||||
axisName.m_LabelStyle.Copy(m_LabelStyle);
|
||||
return axisName;
|
||||
}
|
||||
|
||||
public void Copy(AxisName axisName)
|
||||
{
|
||||
show = axisName.show;
|
||||
name = axisName.name;
|
||||
m_LabelStyle.Copy(axisName.labelStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 878555ba3c6b1479f94f38185700531e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Split area of axis in grid area, not shown by default.
|
||||
/// |坐标轴在 grid 区域中的分隔区域,默认不显示。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisSplitArea : ChildComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private List<Color32> m_Color;
|
||||
|
||||
/// <summary>
|
||||
/// Set this to true to show the splitArea.
|
||||
/// |是否显示分隔区域。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Color of split area. SplitArea color could also be set in color array,
|
||||
/// which the split lines would take as their colors in turns.
|
||||
/// Dark and light colors in turns are used by default.
|
||||
/// |分隔区域颜色。分隔区域会按数组中颜色的顺序依次循环设置颜色。默认是一个深浅的间隔色。
|
||||
/// </summary>
|
||||
public List<Color32> color
|
||||
{
|
||||
get { return m_Color; }
|
||||
set { if (value != null) { m_Color = value; SetVerticesDirty(); } }
|
||||
}
|
||||
|
||||
public static AxisSplitArea defaultSplitArea
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisSplitArea()
|
||||
{
|
||||
m_Show = false,
|
||||
m_Color = new List<Color32>() { }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public AxisSplitArea Clone()
|
||||
{
|
||||
var axisSplitArea = new AxisSplitArea();
|
||||
axisSplitArea.show = show;
|
||||
axisSplitArea.color = new List<Color32>();
|
||||
ChartHelper.CopyList(axisSplitArea.color, color);
|
||||
return axisSplitArea;
|
||||
}
|
||||
|
||||
public void Copy(AxisSplitArea splitArea)
|
||||
{
|
||||
show = splitArea.show;
|
||||
color.Clear();
|
||||
ChartHelper.CopyList(color, splitArea.color);
|
||||
}
|
||||
|
||||
public Color32 GetColor(int index, BaseAxisTheme theme)
|
||||
{
|
||||
if (color.Count > 0)
|
||||
{
|
||||
var i = index % color.Count;
|
||||
return color[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
var i = index % theme.splitAreaColors.Count;
|
||||
return theme.splitAreaColors[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18702fd7797054670af64546b7304bb4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Split line of axis in grid area.
|
||||
/// |坐标轴在 grid 区域中的分隔线。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AxisSplitLine : BaseLine
|
||||
{
|
||||
[SerializeField] private int m_Interval;
|
||||
[SerializeField] private float m_Distance;
|
||||
[SerializeField] private bool m_AutoColor;
|
||||
|
||||
/// <summary>
|
||||
/// The distance between the split line and axis line.
|
||||
/// |刻度线与轴线的距离。
|
||||
/// </summary>
|
||||
public float distance { get { return m_Distance; } set { m_Distance = value; } }
|
||||
/// <summary>
|
||||
/// auto color.
|
||||
/// |自动设置颜色。
|
||||
/// </summary>
|
||||
public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } }
|
||||
/// <summary>
|
||||
/// Interval of Axis splitLine.
|
||||
/// |坐标轴分隔线的显示间隔。
|
||||
/// </summary>
|
||||
public int interval
|
||||
{
|
||||
get { return m_Interval; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Interval, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public override bool vertsDirty { get { return m_VertsDirty || m_LineStyle.anyDirty; } }
|
||||
public override void ClearVerticesDirty()
|
||||
{
|
||||
base.ClearVerticesDirty();
|
||||
m_LineStyle.ClearVerticesDirty();
|
||||
}
|
||||
public static AxisSplitLine defaultSplitLine
|
||||
{
|
||||
get
|
||||
{
|
||||
return new AxisSplitLine()
|
||||
{
|
||||
m_Show = false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public AxisSplitLine Clone()
|
||||
{
|
||||
var axisSplitLine = new AxisSplitLine();
|
||||
axisSplitLine.show = show;
|
||||
axisSplitLine.interval = interval;
|
||||
axisSplitLine.lineStyle = lineStyle.Clone();
|
||||
return axisSplitLine;
|
||||
}
|
||||
|
||||
public void Copy(AxisSplitLine splitLine)
|
||||
{
|
||||
base.Copy(splitLine);
|
||||
interval = splitLine.interval;
|
||||
}
|
||||
|
||||
internal bool NeedShow(int index)
|
||||
{
|
||||
return show && (interval == 0 || index % (interval + 1) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3da942a7a6bea44e2998ed993c0641ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,110 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to axis tick.
|
||||
/// |坐标轴刻度相关设置。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AxisTick : BaseLine
|
||||
{
|
||||
[SerializeField] private bool m_AlignWithLabel;
|
||||
[SerializeField] private bool m_Inside;
|
||||
[SerializeField] private bool m_ShowStartTick;
|
||||
[SerializeField] private bool m_ShowEndTick;
|
||||
[SerializeField] private float m_Distance;
|
||||
[SerializeField] protected int m_SplitNumber = 0;
|
||||
[SerializeField] private bool m_AutoColor;
|
||||
|
||||
/// <summary>
|
||||
/// The distance between the tick line and axis line.
|
||||
/// |刻度线与轴线的距离。
|
||||
/// </summary>
|
||||
public float distance { get { return m_Distance; } set { m_Distance = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// Align axis tick with label, which is available only when boundaryGap is set to be true in category axis.
|
||||
/// |类目轴中在 boundaryGap 为 true 的时候有效,可以保证刻度线和标签对齐。
|
||||
/// </summary>
|
||||
public bool alignWithLabel
|
||||
{
|
||||
get { return m_AlignWithLabel; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_AlignWithLabel, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Set this to true so the axis labels face the inside direction.
|
||||
/// |坐标轴刻度是否朝内,默认朝外。
|
||||
/// </summary>
|
||||
public bool inside
|
||||
{
|
||||
get { return m_Inside; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Inside, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the first tick.
|
||||
/// |是否显示第一个刻度。
|
||||
/// </summary>
|
||||
public bool showStartTick
|
||||
{
|
||||
get { return m_ShowStartTick; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowStartTick, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether to display the last tick.
|
||||
/// |是否显示最后一个刻度。
|
||||
/// </summary>
|
||||
public bool showEndTick
|
||||
{
|
||||
get { return m_ShowEndTick; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ShowEndTick, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Number of segments that the axis is split into.
|
||||
/// |分隔线之间分割的刻度数。
|
||||
/// </summary>
|
||||
public int splitNumber
|
||||
{
|
||||
get { return m_SplitNumber; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_SplitNumber, value)) SetAllDirty(); }
|
||||
}
|
||||
public bool autoColor { get { return m_AutoColor; } set { m_AutoColor = value; } }
|
||||
|
||||
public static AxisTick defaultTick
|
||||
{
|
||||
get
|
||||
{
|
||||
var tick = new AxisTick
|
||||
{
|
||||
m_Show = true,
|
||||
m_AlignWithLabel = false,
|
||||
m_Inside = false,
|
||||
m_ShowStartTick = true,
|
||||
m_ShowEndTick = true
|
||||
};
|
||||
return tick;
|
||||
}
|
||||
}
|
||||
|
||||
public AxisTick Clone()
|
||||
{
|
||||
var axisTick = new AxisTick();
|
||||
axisTick.show = show;
|
||||
axisTick.alignWithLabel = alignWithLabel;
|
||||
axisTick.inside = inside;
|
||||
axisTick.showStartTick = showStartTick;
|
||||
axisTick.showEndTick = showEndTick;
|
||||
axisTick.lineStyle = lineStyle.Clone();
|
||||
return axisTick;
|
||||
}
|
||||
|
||||
public void Copy(AxisTick axisTick)
|
||||
{
|
||||
show = axisTick.show;
|
||||
alignWithLabel = axisTick.alignWithLabel;
|
||||
inside = axisTick.inside;
|
||||
showStartTick = axisTick.showStartTick;
|
||||
showEndTick = axisTick.showEndTick;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60278762ed892450d85e27b7df8f997e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24693180b2a2e41b2ab4025b2bbebf01
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(ParallelCoord))]
|
||||
[ComponentHandler(typeof(ParallelAxisHander), true)]
|
||||
public class ParallelAxis : Axis
|
||||
{
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Value;
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7bc01c54f4d6485389fd57c37810c74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class ParallelAxisHander : AxisHandler<ParallelAxis>
|
||||
{
|
||||
private Orient m_Orient;
|
||||
private ParallelCoord m_Parallel;
|
||||
|
||||
protected override Orient orient { get { return m_Orient; } }
|
||||
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitParallelAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateContext(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;
|
||||
m_Parallel = parallel;
|
||||
var axisCount = chart.GetChartComponentNum<ParallelAxis>();
|
||||
|
||||
if (m_Orient == Orient.Horizonal)
|
||||
{
|
||||
var each = axisCount > 1 ? parallel.context.height / (axisCount - 1) : 0;
|
||||
axis.context.x = parallel.context.x;
|
||||
axis.context.y = parallel.context.y + (axis.index) * each;
|
||||
axis.context.width = parallel.context.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
var each = axisCount > 1 ? parallel.context.width / (axisCount - 1) : 0;
|
||||
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(null,
|
||||
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 (m_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 (m_Parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
DrawAxisSplit(vh, 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 (m_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 (m_Parallel == null)
|
||||
return;
|
||||
|
||||
DrawAxisLine(vh, axis,
|
||||
chart.theme.axis,
|
||||
m_Orient,
|
||||
axis.context.x,
|
||||
axis.context.y,
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
protected override float GetAxisLineXOrY()
|
||||
{
|
||||
return component.context.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 26ab25bf702c54ad38461c91ba1451af
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c8971958a94d47e68f7ebdff5872b71
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Radial axis of polar coordinate.
|
||||
/// |极坐标系的径向轴。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
[RequireChartComponent(typeof(PolarCoord))]
|
||||
[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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f6429398a27934726ba49d387d681728
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class RadiusAxisHandler : AxisHandler<RadiusAxis>
|
||||
{
|
||||
public override void InitComponent()
|
||||
{
|
||||
InitRadiusAxis(component);
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
UpdateAxisMinMaxValue(component);
|
||||
UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
DrawRadiusAxis(vh, component);
|
||||
}
|
||||
|
||||
protected override void UpdatePointerValue(Axis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
if (polar == null)
|
||||
return;
|
||||
|
||||
if (!polar.context.isPointerEnter)
|
||||
{
|
||||
axis.context.pointerValue = double.PositiveInfinity;
|
||||
return;
|
||||
}
|
||||
|
||||
var angleAxis = ComponentHelper.GetAngleAxis(chart.components, polar.index);
|
||||
if (angleAxis == null)
|
||||
return;
|
||||
|
||||
var dist = Vector3.Distance(chart.pointerPos, polar.context.center);
|
||||
axis.context.pointerValue = axis.context.minValue + (dist / polar.context.radius) * axis.context.minMaxRange;
|
||||
axis.context.pointerLabelPosition = GetLabelPosition(polar, axis, angleAxis.context.startAngle, dist);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.offset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
UpdateAxisTickValueList(axis);
|
||||
|
||||
if (updateChart)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void UpdateAxisLabelText(RadiusAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
if (axis.context.labelObjectList.Count <= 0)
|
||||
InitRadiusAxis(axis);
|
||||
else
|
||||
axis.UpdateLabelText(polar.context.radius, null, false);
|
||||
}
|
||||
|
||||
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 = component.GetType().Name + 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.GetScaleNumber(axis, radius, null);
|
||||
var totalWidth = 0f;
|
||||
var txtHig = textStyle.GetFontSize(chart.theme.axis) + 2;
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
var labelWidth = AxisHelper.GetScaleWidth(axis, radius, i + 1, 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(labelWidth, txtHig), axis, chart.theme.axis, labelName, Color.clear);
|
||||
|
||||
if (i == 0)
|
||||
axis.axisLabel.SetRelatedText(label.text, labelWidth);
|
||||
|
||||
label.text.SetAlignment(textStyle.GetAlignment(TextAnchor.MiddleCenter));
|
||||
label.SetText(labelName);
|
||||
label.SetPosition(GetLabelPosition(polar, axis, angleAxis.context.startAngle, totalWidth));
|
||||
label.SetActive(true);
|
||||
label.SetTextActive(true);
|
||||
|
||||
axis.context.labelObjectList.Add(label);
|
||||
|
||||
totalWidth += labelWidth;
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetLabelPosition(PolarCoord polar, Axis axis, float startAngle, float totalWidth)
|
||||
{
|
||||
var cenPos = polar.context.center;
|
||||
var dire = ChartHelper.GetDire(startAngle, true).normalized;
|
||||
var tickLength = axis.axisTick.GetLength(chart.theme.axis.tickLength);
|
||||
var tickVector = ChartHelper.GetVertialDire(dire) *
|
||||
(tickLength + axis.axisLabel.distance);
|
||||
return ChartHelper.GetPos(cenPos, totalWidth, startAngle, true) + tickVector;
|
||||
}
|
||||
|
||||
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.context.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.GetWidth(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; i++)
|
||||
{
|
||||
var scaleWidth = AxisHelper.GetScaleWidth(radiusAxis, radius, i);
|
||||
var pos = ChartHelper.GetPos(cenPos, totalWidth + tickWidth, 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)
|
||||
{
|
||||
if ((i == 0 && radiusAxis.axisTick.showStartTick) ||
|
||||
(i == size && radiusAxis.axisTick.showEndTick) ||
|
||||
(i > 0 && i < size))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f2cb79bfe30c4f14a3117f9f30ed3bd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17498717d39c14b43a91c67401407410
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,152 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <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;
|
||||
|
||||
/// <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(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// width of axis.
|
||||
/// |坐标轴宽。
|
||||
/// </summary>
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// height of axis.
|
||||
/// |坐标轴高。
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aeb871d6555744e609bd651306c601a8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[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(null,
|
||||
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, 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)
|
||||
{
|
||||
DrawAxisLine(vh, axis,
|
||||
chart.theme.axis,
|
||||
axis.orient,
|
||||
axis.context.x,
|
||||
GetAxisLineXOrY(),
|
||||
axis.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
protected override float GetAxisLineXOrY()
|
||||
{
|
||||
return component.context.y + component.offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 50b3514e3079543ea9000d21d809cad3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5e50f8f0f8bb406b99fb32d6b5c7769
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate.
|
||||
/// |直角坐标系 grid 中的 x 轴。
|
||||
/// </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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a71be0d36b9745c2894e598b3d9188a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,152 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[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(yAxis,
|
||||
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 relativedAxis = chart.GetChartComponent<YAxis>(xAxis.gridIndex);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(xAxis);
|
||||
|
||||
DrawAxisSplit(vh, chart.theme.axis, dataZoom,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.width,
|
||||
grid.context.height,
|
||||
relativedAxis);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
DrawAxisTick(vh, xAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
GetAxisLineXOrY(),
|
||||
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;
|
||||
|
||||
DrawAxisLine(vh, xAxis, chart.theme.axis,
|
||||
Orient.Horizonal,
|
||||
grid.context.x,
|
||||
GetAxisLineXOrY(),
|
||||
grid.context.width);
|
||||
}
|
||||
}
|
||||
|
||||
protected override float GetAxisLineXOrY()
|
||||
{
|
||||
var xAxis = component;
|
||||
var grid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
|
||||
var startY = grid.context.y + xAxis.offset;
|
||||
if (xAxis.IsTop())
|
||||
startY += grid.context.height;
|
||||
else
|
||||
startY += ComponentHelper.GetXAxisOnZeroOffset(chart.components, xAxis);
|
||||
return startY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7818e1175663412196de53f19b5ac08
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69f8ba8fcc7d84b12b42f837f9f2b94b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// The x axis in cartesian(rectangular) coordinate.
|
||||
/// |直角坐标系 grid 中的 y 轴。
|
||||
/// </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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ac60b8329f7a45c3898c7539d78f091
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,149 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[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(xAxis,
|
||||
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 relativedAxis = chart.GetChartComponent<XAxis>(yAxis.gridIndex);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(yAxis);
|
||||
DrawAxisSplit(vh, chart.theme.axis, dataZoom,
|
||||
Orient.Vertical,
|
||||
grid.context.x,
|
||||
grid.context.y,
|
||||
grid.context.height,
|
||||
grid.context.width,
|
||||
relativedAxis);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
DrawAxisTick(vh, yAxis, chart.theme.axis, dataZoom,
|
||||
Orient.Vertical,
|
||||
GetAxisLineXOrY(),
|
||||
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;
|
||||
|
||||
DrawAxisLine(vh, yAxis, chart.theme.axis,
|
||||
Orient.Vertical,
|
||||
GetAxisLineXOrY(),
|
||||
grid.context.y,
|
||||
grid.context.height);
|
||||
}
|
||||
}
|
||||
|
||||
protected override float GetAxisLineXOrY()
|
||||
{
|
||||
var yAxis = component;
|
||||
var grid = chart.GetChartComponent<GridCoord>(yAxis.gridIndex);
|
||||
var startX = grid.context.x + yAxis.offset;
|
||||
if (yAxis.IsRight())
|
||||
startX += grid.context.width;
|
||||
else
|
||||
startX += ComponentHelper.GetYAxisOnZeroOffset(chart.components, yAxis);
|
||||
return startX;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f09b5dcb5fcc54583bcd7946f18dfa48
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7db6fdcbbbfd148f58ff7a1f1a569d51
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Background component.
|
||||
/// |
|
||||
/// 背景组件。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DisallowMultipleComponent]
|
||||
[ComponentHandler(typeof(BackgroundHandler), false)]
|
||||
public class Background : MainComponent
|
||||
{
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private Sprite m_Image;
|
||||
[SerializeField] private Image.Type m_ImageType;
|
||||
[SerializeField] private Color m_ImageColor = Color.white;
|
||||
[SerializeField] private bool m_AutoColor = true;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to enable the background component.
|
||||
/// |是否启用背景组件。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
internal set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetComponentDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the image of background.
|
||||
/// |背景图。
|
||||
/// </summary>
|
||||
public Sprite image
|
||||
{
|
||||
get { return m_Image; }
|
||||
set { if (PropertyUtil.SetClass(ref m_Image, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the fill type of background image.
|
||||
/// |背景图填充类型。
|
||||
/// </summary>
|
||||
public Image.Type imageType
|
||||
{
|
||||
get { return m_ImageType; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_ImageType, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 背景图颜色。
|
||||
/// </summary>
|
||||
public Color imageColor
|
||||
{
|
||||
get { return m_ImageColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_ImageColor, value)) SetComponentDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to use theme background color for component color when the background component is on.
|
||||
/// |当background组件开启时,是否自动使用主题背景色作为backgrounnd组件的颜色。当设置为false时,用imageColor作为颜色。
|
||||
/// </summary>
|
||||
public bool autoColor
|
||||
{
|
||||
get { return m_AutoColor; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_AutoColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Image = null;
|
||||
m_ImageType = Image.Type.Sliced;
|
||||
m_ImageColor = Color.white;
|
||||
m_AutoColor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 524f7df5241cc4379ae241a73d5b2ff2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[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 = chart.theme.GetBackgroundColor(component);
|
||||
|
||||
backgroundObj.transform.SetSiblingIndex(0);
|
||||
backgroundObj.SetActive(component.show);
|
||||
};
|
||||
component.refreshComponent();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
if (component.gameObject != null && component.gameObject.transform.GetSiblingIndex() != 0)
|
||||
component.gameObject.transform.SetSiblingIndex(0);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
{
|
||||
if (!component.show)
|
||||
return;
|
||||
if (component.image != null)
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1cb3d1a2aa224bbe84eef2681cf3df4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 20d31ade0390641698e6b846b4294b74
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,131 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// The style of area.
|
||||
/// |区域填充样式。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class AreaStyle : ChildComponent, ISerieExtraComponent, ISerieDataComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Origin position of area.
|
||||
/// |图形区域的起始位置。默认情况下,图形会从坐标轴轴线到数据间进行填充。如果需要填充的区域是坐标轴最大值到数据间,或者坐标轴最小值到数据间,则可以通过这个配置项进行设置。
|
||||
/// </summary>
|
||||
public enum AreaOrigin
|
||||
{
|
||||
/// <summary>
|
||||
/// to fill between axis line to data.
|
||||
/// |填充坐标轴轴线到数据间的区域。
|
||||
/// </summary>
|
||||
Auto,
|
||||
/// <summary>
|
||||
/// to fill between min axis value (when not inverse) to data.
|
||||
/// |填充坐标轴底部到数据间的区域。
|
||||
/// </summary>
|
||||
Start,
|
||||
/// <summary>
|
||||
/// to fill between max axis value (when not inverse) to data.
|
||||
/// |填充坐标轴顶部到数据间的区域。
|
||||
/// </summary>
|
||||
End
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private AreaOrigin m_Origin;
|
||||
[SerializeField] private Color32 m_Color;
|
||||
[SerializeField] private Color32 m_ToColor;
|
||||
[SerializeField][Range(0, 1)] private float m_Opacity = 0.6f;
|
||||
[SerializeField] private Color32 m_HighlightColor;
|
||||
[SerializeField] private Color32 m_HighlightToColor;
|
||||
|
||||
/// <summary>
|
||||
/// Set this to false to prevent the areafrom showing.
|
||||
/// |是否显示区域填充。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the origin of area.
|
||||
/// |区域填充的起始位置。
|
||||
/// </summary>
|
||||
public AreaOrigin origin
|
||||
{
|
||||
get { return m_Origin; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Origin, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the color of area,default use serie color.
|
||||
/// |区域填充的颜色,如果toColor不是默认值,则表示渐变色的起点颜色。
|
||||
/// </summary>
|
||||
public Color32 color
|
||||
{
|
||||
get { return m_Color; }
|
||||
set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gradient color, start color to toColor.
|
||||
/// |渐变色的终点颜色。
|
||||
/// </summary>
|
||||
public Color32 toColor
|
||||
{
|
||||
get { return m_ToColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_ToColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Opacity of the component. Supports value from 0 to 1, and the component will not be drawn when set to 0.
|
||||
/// |图形透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。
|
||||
/// </summary>
|
||||
public float opacity
|
||||
{
|
||||
get { return m_Opacity; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Opacity, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// the color of area,default use serie color.
|
||||
/// |高亮时区域填充的颜色,如果highlightToColor不是默认值,则表示渐变色的起点颜色。
|
||||
/// </summary>
|
||||
public Color32 highlightColor
|
||||
{
|
||||
get { return m_HighlightColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_HighlightColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gradient color, start highlightColor to highlightToColor.
|
||||
/// |高亮时渐变色的终点颜色。
|
||||
/// </summary>
|
||||
public Color32 highlightToColor
|
||||
{
|
||||
get { return m_HighlightToColor; }
|
||||
set { if (PropertyUtil.SetColor(ref m_HighlightToColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public Color32 GetColor()
|
||||
{
|
||||
if (m_Opacity == 1)
|
||||
return m_Color;
|
||||
|
||||
var color = m_Color;
|
||||
color.a = (byte) (color.a * m_Opacity);
|
||||
return color;
|
||||
}
|
||||
|
||||
public Color32 GetColor(Color32 themeColor)
|
||||
{
|
||||
if (!ChartHelper.IsClearColor(color))
|
||||
{
|
||||
return GetColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
var color = themeColor;
|
||||
color.a = (byte) (color.a * opacity);
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec0d95a9298bb4c159dcae36020beec9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ArrowStyle : ChildComponent
|
||||
{
|
||||
[SerializeField] private float m_Width = 10;
|
||||
[SerializeField] private float m_Height = 15;
|
||||
[SerializeField] private float m_Offset = 0;
|
||||
[SerializeField] private float m_Dent = 3;
|
||||
[SerializeField] private Color32 m_Color = Color.clear;
|
||||
|
||||
/// <summary>
|
||||
/// The widht of arrow.
|
||||
/// |箭头宽。
|
||||
/// </summary>
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The height of arrow.
|
||||
/// |箭头高。
|
||||
/// </summary>
|
||||
public float height
|
||||
{
|
||||
get { return m_Height; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The offset of arrow.
|
||||
/// |箭头偏移。
|
||||
/// </summary>
|
||||
public float offset
|
||||
{
|
||||
get { return m_Offset; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Offset, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The dent of arrow.
|
||||
/// |箭头的凹度。
|
||||
/// </summary>
|
||||
public float dent
|
||||
{
|
||||
get { return m_Dent; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Dent, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// the color of arrow.
|
||||
/// |箭头颜色。
|
||||
/// </summary>
|
||||
public Color32 color
|
||||
{
|
||||
get { return m_Color; }
|
||||
set { if (PropertyUtil.SetColor(ref m_Color, value)) SetVerticesDirty(); }
|
||||
}
|
||||
|
||||
public ArrowStyle Clone()
|
||||
{
|
||||
var arrow = new ArrowStyle();
|
||||
arrow.width = width;
|
||||
arrow.height = height;
|
||||
arrow.offset = offset;
|
||||
arrow.dent = dent;
|
||||
arrow.color = color;
|
||||
return arrow;
|
||||
}
|
||||
|
||||
public void Copy(ArrowStyle arrow)
|
||||
{
|
||||
width = arrow.width;
|
||||
height = arrow.height;
|
||||
offset = arrow.offset;
|
||||
dent = arrow.dent;
|
||||
color = arrow.color;
|
||||
}
|
||||
|
||||
public Color32 GetColor(Color32 defaultColor)
|
||||
{
|
||||
if (ChartHelper.IsClearColor(color))
|
||||
return defaultColor;
|
||||
else
|
||||
return color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2232b812c68f042d29c44863e38d0417
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Settings related to base line.
|
||||
/// |线条基础配置。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class BaseLine : ChildComponent
|
||||
{
|
||||
[SerializeField] protected bool m_Show;
|
||||
[SerializeField] protected LineStyle m_LineStyle = new LineStyle();
|
||||
|
||||
/// <summary>
|
||||
/// Set this to false to prevent the axis line from showing.
|
||||
/// |是否显示坐标轴轴线。
|
||||
/// </summary>
|
||||
public bool show
|
||||
{
|
||||
get { return m_Show; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// 线条样式
|
||||
/// </summary>
|
||||
public LineStyle lineStyle
|
||||
{
|
||||
get { return m_LineStyle; }
|
||||
set { if (value != null) { m_LineStyle = value; SetVerticesDirty(); } }
|
||||
}
|
||||
|
||||
public static BaseLine defaultBaseLine
|
||||
{
|
||||
get
|
||||
{
|
||||
var axisLine = new BaseLine
|
||||
{
|
||||
m_Show = true,
|
||||
m_LineStyle = new LineStyle()
|
||||
};
|
||||
return axisLine;
|
||||
}
|
||||
}
|
||||
|
||||
public BaseLine()
|
||||
{
|
||||
lineStyle = new LineStyle();
|
||||
}
|
||||
|
||||
public BaseLine(bool show) : base()
|
||||
{
|
||||
m_Show = show;
|
||||
}
|
||||
|
||||
public void Copy(BaseLine axisLine)
|
||||
{
|
||||
show = axisLine.show;
|
||||
lineStyle.Copy(axisLine.lineStyle);
|
||||
}
|
||||
|
||||
public LineStyle.Type GetType(LineStyle.Type themeType)
|
||||
{
|
||||
return lineStyle.GetType(themeType);
|
||||
}
|
||||
|
||||
public float GetWidth(float themeWidth)
|
||||
{
|
||||
return lineStyle.GetWidth(themeWidth);
|
||||
}
|
||||
|
||||
public float GetLength(float themeLength)
|
||||
{
|
||||
return lineStyle.GetLength(themeLength);
|
||||
}
|
||||
|
||||
public Color32 GetColor(Color32 themeColor)
|
||||
{
|
||||
return lineStyle.GetColor(themeColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c431b00ccffe4db4b61179b6df06eb2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,118 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts.Runtime
|
||||
{
|
||||
[System.Serializable]
|
||||
public class IconStyle : ChildComponent
|
||||
{
|
||||
public enum Layer
|
||||
{
|
||||
/// <summary>
|
||||
/// The icon is display under the label text.
|
||||
/// 图标在标签文字下
|
||||
/// </summary>
|
||||
UnderText,
|
||||
/// <summary>
|
||||
/// The icon is display above the label text.
|
||||
/// 图标在标签文字上
|
||||
/// </summary>
|
||||
AboveText
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_Show = false;
|
||||
[SerializeField] private Layer m_Layer;
|
||||
[SerializeField] private Align m_Align = Align.Left;
|
||||
[SerializeField] private Sprite m_Sprite;
|
||||
[SerializeField] private Image.Type m_Type;
|
||||
[SerializeField] private Color m_Color = Color.white;
|
||||
[SerializeField] private float m_Width = 20;
|
||||
[SerializeField] private float m_Height = 20;
|
||||
[SerializeField] private Vector3 m_Offset;
|
||||
[SerializeField] private bool m_AutoHideWhenLabelEmpty = false;
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
m_Show = false;
|
||||
m_Layer = Layer.UnderText;
|
||||
m_Sprite = null;
|
||||
m_Color = Color.white;
|
||||
m_Width = 20;
|
||||
m_Height = 20;
|
||||
m_Offset = Vector3.zero;
|
||||
m_AutoHideWhenLabelEmpty = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Whether the data icon is show.
|
||||
/// |是否显示图标。
|
||||
/// </summary>
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
/// <summary>
|
||||
/// 显示在上层还是在下层。
|
||||
/// </summary>
|
||||
public Layer layer { get { return m_Layer; } set { m_Layer = value; } }
|
||||
/// <summary>
|
||||
/// The image of icon.
|
||||
/// |图标的图片。
|
||||
/// </summary>
|
||||
public Sprite sprite { get { return m_Sprite; } set { m_Sprite = value; } }
|
||||
/// <summary>
|
||||
/// How to display the icon.
|
||||
/// |图片的显示类型。
|
||||
/// </summary>
|
||||
public Image.Type type { get { return m_Type; } set { m_Type = value; } }
|
||||
/// <summary>
|
||||
/// 图标颜色。
|
||||
/// </summary>
|
||||
public Color color { get { return m_Color; } set { m_Color = value; } }
|
||||
/// <summary>
|
||||
/// 图标宽。
|
||||
/// </summary>
|
||||
public float width { get { return m_Width; } set { m_Width = value; } }
|
||||
/// <summary>
|
||||
/// 图标高。
|
||||
/// </summary>
|
||||
public float height { get { return m_Height; } set { m_Height = value; } }
|
||||
/// <summary>
|
||||
/// 图标偏移。
|
||||
/// </summary>
|
||||
public Vector3 offset { get { return m_Offset; } set { m_Offset = value; } }
|
||||
/// <summary>
|
||||
/// 水平方向对齐方式。
|
||||
/// </summary>
|
||||
public Align align { get { return m_Align; } set { m_Align = value; } }
|
||||
/// <summary>
|
||||
/// 当label内容为空时是否自动隐藏图标
|
||||
/// </summary>
|
||||
public bool autoHideWhenLabelEmpty { get { return m_AutoHideWhenLabelEmpty; } set { m_AutoHideWhenLabelEmpty = value; } }
|
||||
public IconStyle Clone()
|
||||
{
|
||||
var iconStyle = new IconStyle();
|
||||
iconStyle.show = show;
|
||||
iconStyle.layer = layer;
|
||||
iconStyle.sprite = sprite;
|
||||
iconStyle.type = type;
|
||||
iconStyle.color = color;
|
||||
iconStyle.width = width;
|
||||
iconStyle.height = height;
|
||||
iconStyle.offset = offset;
|
||||
iconStyle.align = align;
|
||||
iconStyle.autoHideWhenLabelEmpty = autoHideWhenLabelEmpty;
|
||||
return iconStyle;
|
||||
}
|
||||
|
||||
public void Copy(IconStyle iconStyle)
|
||||
{
|
||||
show = iconStyle.show;
|
||||
layer = iconStyle.layer;
|
||||
sprite = iconStyle.sprite;
|
||||
type = iconStyle.type;
|
||||
color = iconStyle.color;
|
||||
width = iconStyle.width;
|
||||
height = iconStyle.height;
|
||||
offset = iconStyle.offset;
|
||||
align = iconStyle.align;
|
||||
autoHideWhenLabelEmpty = iconStyle.autoHideWhenLabelEmpty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 82c4d360f7b5b4ee7845e9bbe611c8a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user