mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-18 06:20:15 +00:00
3.0 - ParallelChart
This commit is contained in:
@@ -153,6 +153,13 @@ namespace XCharts
|
||||
AddChart<CandlestickChart>("CandlestickChart");
|
||||
}
|
||||
|
||||
[MenuItem("XCharts/ParallelChart", priority = 55)]
|
||||
[MenuItem("GameObject/XCharts/ParallelChart", priority = 55)]
|
||||
public static void ParallelChart()
|
||||
{
|
||||
AddChart<ParallelChart>("ParallelChart");
|
||||
}
|
||||
|
||||
[MenuItem("XCharts/Themes Reload")]
|
||||
public static void ReloadTheme()
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
@@ -19,19 +20,20 @@ namespace XCharts
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
AddChartComponentWhenNoExist<ParallelCoord>();
|
||||
AddChartComponentWhenNoExist<ParallelAxis>();
|
||||
|
||||
var tooltip = GetChartComponent<Tooltip>();
|
||||
tooltip.type = Tooltip.Type.Shadow;
|
||||
tooltip.trigger = Tooltip.Trigger.Axis;
|
||||
|
||||
RemoveData();
|
||||
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());
|
||||
// for (int i = 0; i < 5; i++)
|
||||
// {
|
||||
// AddXAxisData("x" + (i + 1));
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@ namespace XCharts
|
||||
if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue)
|
||||
{
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
@@ -53,7 +52,7 @@ namespace XCharts
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation)
|
||||
if (!chart.m_IsPlayingAnimation)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
@@ -63,7 +62,7 @@ namespace XCharts
|
||||
internal void UpdateAxisLabelText(AngleAxis axis)
|
||||
{
|
||||
var runtimeWidth = 360;
|
||||
axis.UpdateLabelText(runtimeWidth, null, false, 500);
|
||||
axis.UpdateLabelText(runtimeWidth, null, false);
|
||||
}
|
||||
|
||||
private void InitAngleAxis(AngleAxis axis)
|
||||
|
||||
@@ -664,8 +664,16 @@ namespace XCharts
|
||||
{
|
||||
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>
|
||||
@@ -718,15 +726,13 @@ namespace XCharts
|
||||
/// 更新刻度标签文字
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent, float duration)
|
||||
internal void UpdateLabelText(float coordinateWidth, DataZoom dataZoom, bool forcePercent)
|
||||
{
|
||||
var minValue = GetCurrMinValue(duration);
|
||||
var maxValue = GetCurrMaxValue(duration);
|
||||
for (int i = 0; i < context.labelObjectList.Count; i++)
|
||||
{
|
||||
if (context.labelObjectList[i] != null)
|
||||
{
|
||||
var text = AxisHelper.GetLabelName(this, coordinateWidth, i, minValue, maxValue, dataZoom, forcePercent);
|
||||
var text = AxisHelper.GetLabelName(this, coordinateWidth, i, context.minValue, context.maxValue, dataZoom, forcePercent);
|
||||
context.labelObjectList[i].SetText(text);
|
||||
}
|
||||
}
|
||||
@@ -740,20 +746,10 @@ namespace XCharts
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
internal bool UpdateMinValue(double value, bool check)
|
||||
internal void UpdateMinMaxValue(double minValue, double maxValue)
|
||||
{
|
||||
return context.UpdateMinValue(value, check);
|
||||
}
|
||||
|
||||
internal bool UpdateMaxValue(double value, bool check)
|
||||
{
|
||||
return context.UpdateMaxValue(value, check);
|
||||
}
|
||||
|
||||
internal void UpdateMinMaxValue(double minValue, double maxValue, bool check)
|
||||
{
|
||||
UpdateMinValue(minValue, check);
|
||||
UpdateMaxValue(maxValue, check);
|
||||
context.minValue = minValue;
|
||||
context.maxValue = maxValue;
|
||||
double tempRange = maxValue - minValue;
|
||||
if (context.minMaxRange != tempRange)
|
||||
{
|
||||
@@ -765,32 +761,6 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
public double GetCurrMinValue(float duration)
|
||||
{
|
||||
return context.GetCurrMinValue(duration);
|
||||
}
|
||||
|
||||
public double GetCurrMaxValue(float duration)
|
||||
{
|
||||
return context.GetCurrMaxValue(duration);
|
||||
}
|
||||
|
||||
public bool IsValueChanging(float duration)
|
||||
{
|
||||
if (!Application.isPlaying)
|
||||
return false;
|
||||
|
||||
if (GetCurrMinValue(duration) != context.minValue
|
||||
|| GetCurrMaxValue(duration) != context.maxValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetLogValue(double value)
|
||||
{
|
||||
if (value <= 0 || value == 1)
|
||||
|
||||
@@ -13,36 +13,26 @@ namespace XCharts
|
||||
{
|
||||
public class AxisContext : MainComponentContext
|
||||
{
|
||||
internal Orient orient { get; set; }
|
||||
public float x { get; internal set; }
|
||||
public float y { get; internal set; }
|
||||
public float width { get; internal set; }
|
||||
public float height { get; internal set; }
|
||||
public Vector3 position { get; internal set; }
|
||||
public float left { get; internal set; }
|
||||
public float right { get; internal set; }
|
||||
public float bottom { get; internal set; }
|
||||
public float top { get; internal set; }
|
||||
/// <summary>
|
||||
/// the current minimun value.
|
||||
/// 当前最小值。
|
||||
/// </summary>
|
||||
public double minValue
|
||||
{
|
||||
get { return m_RuntimeMinValue; }
|
||||
internal set
|
||||
{
|
||||
m_RuntimeMinValue = value;
|
||||
m_RuntimeLastMinValue = value;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
}
|
||||
}
|
||||
public double minValue { get; internal set; }
|
||||
/// <summary>
|
||||
/// the current maximum value.
|
||||
/// 当前最大值。
|
||||
/// </summary>
|
||||
public double maxValue
|
||||
{
|
||||
get { return m_RuntimeMaxValue; }
|
||||
internal set
|
||||
{
|
||||
m_RuntimeMaxValue = value;
|
||||
m_RuntimeLastMaxValue = value;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
}
|
||||
}
|
||||
public double maxValue { get; internal set; }
|
||||
/// <summary>
|
||||
/// the x offset of zero position.
|
||||
/// 坐标轴原点在X轴的偏移。
|
||||
@@ -70,16 +60,6 @@ namespace XCharts
|
||||
private int filterStart;
|
||||
private int filterEnd;
|
||||
private int filterMinShow;
|
||||
private double m_RuntimeMinValue;
|
||||
private double m_RuntimeLastMinValue;
|
||||
private bool m_RuntimeMinValueChanged;
|
||||
private float m_RuntimeMinValueUpdateTime;
|
||||
private double m_RuntimeMaxValue;
|
||||
private double m_RuntimeLastMaxValue;
|
||||
private bool m_RuntimeMaxValueChanged;
|
||||
private float m_RuntimeMaxValueUpdateTime;
|
||||
private bool m_RuntimeMinValueFirstChanged = true;
|
||||
private bool m_RuntimeMaxValueFirstChanged = true;
|
||||
|
||||
private List<ChartLabel> m_AxisLabelList = new List<ChartLabel>();
|
||||
private List<double> m_LabelValueList = new List<double>();
|
||||
@@ -91,123 +71,6 @@ namespace XCharts
|
||||
m_RuntimeData.Clear();
|
||||
}
|
||||
|
||||
internal bool UpdateMinValue(double value, bool check)
|
||||
{
|
||||
if (value != maxValue)
|
||||
{
|
||||
if (check && Application.isPlaying)
|
||||
{
|
||||
if (m_RuntimeMinValueFirstChanged)
|
||||
{
|
||||
m_RuntimeMinValueFirstChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeLastMinValue = minValue;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
}
|
||||
minValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
minValue = value;
|
||||
m_RuntimeLastMinValue = value;
|
||||
m_RuntimeMinValueUpdateTime = Time.time;
|
||||
m_RuntimeMinValueChanged = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal bool UpdateMaxValue(double value, bool check)
|
||||
{
|
||||
if (value != maxValue)
|
||||
{
|
||||
if (check && Application.isPlaying)
|
||||
{
|
||||
if (m_RuntimeMaxValueFirstChanged)
|
||||
{
|
||||
m_RuntimeMaxValueFirstChanged = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeLastMaxValue = maxValue;
|
||||
m_RuntimeMaxValueChanged = true;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
}
|
||||
maxValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
maxValue = value;
|
||||
m_RuntimeLastMaxValue = value;
|
||||
m_RuntimeMaxValueUpdateTime = Time.time;
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public double GetCurrMinValue(float duration)
|
||||
{
|
||||
if (!Application.isPlaying || !m_RuntimeMinValueChanged)
|
||||
return minValue;
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
return 0;
|
||||
|
||||
var time = Time.time - m_RuntimeMinValueUpdateTime;
|
||||
if (time == 0)
|
||||
return minValue;
|
||||
|
||||
var total = duration / 1000;
|
||||
if (duration > 0 && time <= total)
|
||||
{
|
||||
var curr = MathUtil.Lerp(m_RuntimeLastMinValue, minValue, time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMinValueChanged = false;
|
||||
return minValue;
|
||||
}
|
||||
}
|
||||
|
||||
public double GetCurrMaxValue(float duration)
|
||||
{
|
||||
if (!Application.isPlaying || !m_RuntimeMaxValueChanged)
|
||||
return maxValue;
|
||||
|
||||
if (minValue == 0 && maxValue == 0)
|
||||
return 0;
|
||||
|
||||
var time = Time.time - m_RuntimeMaxValueUpdateTime;
|
||||
if (time == 0)
|
||||
return maxValue;
|
||||
|
||||
var total = duration / 1000;
|
||||
if (duration > 0 && time < total)
|
||||
{
|
||||
var curr = MathUtil.Lerp(m_RuntimeLastMaxValue, maxValue, time / total);
|
||||
return curr;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_RuntimeMaxValueChanged = false;
|
||||
return maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> m_EmptyFliter = new List<string>();
|
||||
/// <summary>
|
||||
/// 更新dataZoom对应的类目数据列表
|
||||
|
||||
@@ -134,8 +134,7 @@ namespace XCharts
|
||||
m_LastInterval = axis.interval;
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
@@ -181,7 +180,7 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation)
|
||||
if ( !chart.m_IsPlayingAnimation)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
@@ -198,7 +197,7 @@ namespace XCharts
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series);
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
|
||||
axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack, 500);
|
||||
axis.UpdateLabelText(runtimeWidth, dataZoom, isPercentStack);
|
||||
}
|
||||
|
||||
internal static void UpdateAxisTickValueList(Axis axis)
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace XCharts
|
||||
m_Show = true,
|
||||
m_AlignWithLabel = false,
|
||||
m_Inside = false,
|
||||
m_ShowStartTick = false,
|
||||
m_ShowStartTick = true,
|
||||
m_ShowEndTick = true
|
||||
};
|
||||
return tick;
|
||||
|
||||
@@ -15,12 +15,10 @@ namespace XCharts
|
||||
[ComponentHandler(typeof(ParallelAxisHander), true)]
|
||||
public class ParallelAxis : Axis
|
||||
{
|
||||
public new ParallelAxisContext context = new ParallelAxisContext();
|
||||
|
||||
public override void SetDefaultValue()
|
||||
{
|
||||
m_Show = true;
|
||||
m_Type = AxisType.Category;
|
||||
m_Type = AxisType.Value;
|
||||
m_Min = 0;
|
||||
m_Max = 0;
|
||||
m_SplitNumber = 0;
|
||||
@@ -35,6 +33,6 @@ namespace XCharts
|
||||
iconStyle.show = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class ParallelAxisContext : AxisContext, IRectContext
|
||||
{
|
||||
internal ParallelCoord parallel { get; set; }
|
||||
internal Orient orient { get; set; }
|
||||
public float x { get; internal set; }
|
||||
public float y { get; internal set; }
|
||||
public float width { get; internal set; }
|
||||
public float height { get; internal set; }
|
||||
public Vector3 position { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b92542e13620d417d819e8573b430dc8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -14,6 +14,8 @@ namespace XCharts
|
||||
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()
|
||||
@@ -24,8 +26,6 @@ namespace XCharts
|
||||
public override void Update()
|
||||
{
|
||||
UpdateContext(component);
|
||||
UpdateAxisMinMaxValue(component.index, component);
|
||||
//UpdatePointerValue(component);
|
||||
}
|
||||
|
||||
public override void DrawBase(VertexHelper vh)
|
||||
@@ -43,19 +43,19 @@ namespace XCharts
|
||||
return;
|
||||
|
||||
m_Orient = parallel.orient;
|
||||
axis.context.parallel = parallel;
|
||||
m_Parallel = parallel;
|
||||
var axisCount = chart.GetChartComponentNum<ParallelAxis>();
|
||||
|
||||
if (m_Orient == Orient.Horizonal)
|
||||
{
|
||||
var each = parallel.context.height / (axisCount - 1);
|
||||
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 = parallel.context.width / (axisCount - 1);
|
||||
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;
|
||||
@@ -103,7 +103,7 @@ namespace XCharts
|
||||
|
||||
protected override Vector3 GetLabelPosition(float scaleWid, int i)
|
||||
{
|
||||
if (component.context.parallel == null)
|
||||
if (m_Parallel == null)
|
||||
return Vector3.zero;
|
||||
|
||||
return GetLabelPosition(i, m_Orient, component, null,
|
||||
@@ -119,7 +119,7 @@ namespace XCharts
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
if (axis.context.parallel == null)
|
||||
if (m_Parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
@@ -137,7 +137,7 @@ namespace XCharts
|
||||
{
|
||||
if (AxisHelper.NeedShowSplit(axis))
|
||||
{
|
||||
if (axis.context.parallel == null)
|
||||
if (m_Parallel == null)
|
||||
return;
|
||||
|
||||
var dataZoom = chart.GetDataZoomOfAxis(axis);
|
||||
@@ -154,7 +154,7 @@ namespace XCharts
|
||||
{
|
||||
if (axis.show && axis.axisLine.show)
|
||||
{
|
||||
if (axis.context.parallel == null)
|
||||
if (m_Parallel == null)
|
||||
return;
|
||||
|
||||
DrawAxisLine(vh, axis,
|
||||
|
||||
@@ -41,8 +41,7 @@ namespace XCharts
|
||||
if (tempMinValue != axis.context.minValue || tempMaxValue != axis.context.maxValue)
|
||||
{
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
@@ -53,7 +52,7 @@ namespace XCharts
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
if (axis.IsValueChanging(500) && !chart.m_IsPlayingAnimation)
|
||||
if (!chart.m_IsPlayingAnimation)
|
||||
{
|
||||
UpdateAxisLabelText(axis);
|
||||
chart.RefreshChart();
|
||||
@@ -63,7 +62,7 @@ namespace XCharts
|
||||
internal void UpdateAxisLabelText(RadiusAxis axis)
|
||||
{
|
||||
var polar = chart.GetChartComponent<PolarCoord>(axis.polarIndex);
|
||||
axis.UpdateLabelText(polar.context.radius, null, false, 500);
|
||||
axis.UpdateLabelText(polar.context.radius, null, false);
|
||||
}
|
||||
|
||||
private void InitRadiusAxis(RadiusAxis axis)
|
||||
|
||||
@@ -26,8 +26,6 @@ namespace XCharts
|
||||
[SerializeField] private float m_Width = 0;
|
||||
[SerializeField] private float m_Height = 50;
|
||||
|
||||
public new SingleAxisContext context = new SingleAxisContext();
|
||||
|
||||
/// <summary>
|
||||
/// Orientation of the axis. By default, it's 'Horizontal'. You can set it to be 'Vertical' to make a vertical axis.
|
||||
/// 坐标轴朝向。默认为水平朝向。
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
/************************************************/
|
||||
/* */
|
||||
/* Copyright (c) 2018 - 2021 monitor1394 */
|
||||
/* https://github.com/monitor1394 */
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public class SingleAxisContext : AxisContext, IRectContext
|
||||
{
|
||||
public float x { get; internal set; }
|
||||
public float y { get; internal set; }
|
||||
public float width { get; internal set; }
|
||||
public float height { get; internal set; }
|
||||
public Vector3 position { get; internal set; }
|
||||
public float left { get; internal set; }
|
||||
public float right { get; internal set; }
|
||||
public float bottom { get; internal set; }
|
||||
public float top { get; internal set; }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 435915ad1c7fc41bb8362244d7bae638
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -555,6 +555,10 @@ namespace XCharts
|
||||
|
||||
public float GetCurrDetail()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (!Application.isPlaying)
|
||||
return m_DestDetailProgress;
|
||||
#endif
|
||||
return m_CurrDetailProgress;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
/************************************************/
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
@@ -73,7 +72,7 @@ namespace XCharts
|
||||
s_Sb.Length = 0;
|
||||
s_Sb.AppendFormat("fps : {0:f0} / {1:f0}\n", fps, avgFps);
|
||||
s_Sb.AppendFormat("data : {0}\n", m_Chart.GetAllSerieDataCount());
|
||||
s_Sb.AppendFormat("refresh : {0}", refreshCount);
|
||||
s_Sb.AppendFormat("draw : {0}", refreshCount);
|
||||
m_Label.SetText(s_Sb.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,13 +132,26 @@ namespace XCharts
|
||||
for (int i = 0; i < component.context.parallelAxes.Count; i++)
|
||||
{
|
||||
var axis = component.context.parallelAxes[i];
|
||||
var tempMinValue = m_SerieDimMin[i];
|
||||
var tempMaxValue = m_SerieDimMax[i];
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
m_SerieDimMin[i] = tempMinValue;
|
||||
m_SerieDimMax[i] = tempMaxValue;
|
||||
}
|
||||
if (axis.IsCategory())
|
||||
{
|
||||
m_SerieDimMax[i] = axis.data.Count > 0 ? axis.data.Count - 1 : 0;
|
||||
m_SerieDimMin[i] = 0;
|
||||
}
|
||||
else if (axis.minMaxType == Axis.AxisMinMaxType.Custom)
|
||||
{
|
||||
m_SerieDimMin[i] = axis.min;
|
||||
m_SerieDimMax[i] = axis.max;
|
||||
}
|
||||
else if (m_SerieDimMax.ContainsKey(i))
|
||||
{
|
||||
|
||||
var tempMinValue = m_SerieDimMin[i];
|
||||
var tempMaxValue = m_SerieDimMax[i];
|
||||
AxisHelper.AdjustMinMaxValue(axis, ref tempMinValue, ref tempMaxValue, true);
|
||||
m_SerieDimMin[i] = tempMinValue;
|
||||
m_SerieDimMax[i] = tempMaxValue;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < component.context.parallelAxes.Count; i++)
|
||||
{
|
||||
if (m_SerieDimMax.ContainsKey(i))
|
||||
@@ -156,8 +169,7 @@ namespace XCharts
|
||||
m_LastInterval = axis.interval;
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
|
||||
var needCheck = !chart.m_IsPlayingAnimation && axis.context.lastCheckInverse == axis.inverse;
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue, needCheck);
|
||||
axis.UpdateMinMaxValue(tempMinValue, tempMaxValue);
|
||||
axis.context.xOffset = 0;
|
||||
axis.context.yOffset = 0;
|
||||
axis.context.lastCheckInverse = axis.inverse;
|
||||
|
||||
@@ -138,7 +138,11 @@ namespace XCharts
|
||||
|
||||
GetChartComponent<Title>().text = GetType().Name;
|
||||
|
||||
m_Theme.sharedTheme.CopyTheme(ThemeType.Default);
|
||||
if (m_Theme.sharedTheme != null)
|
||||
m_Theme.sharedTheme.CopyTheme(ThemeType.Default);
|
||||
else
|
||||
m_Theme.sharedTheme = XCThemeMgr.GetTheme(ThemeType.Default);
|
||||
|
||||
m_Settings = null;
|
||||
var sizeDelta = rectTransform.sizeDelta;
|
||||
if (sizeDelta.x < 580 && sizeDelta.y < 300)
|
||||
|
||||
@@ -498,100 +498,6 @@ namespace XCharts
|
||||
posList.Add(ep);
|
||||
}
|
||||
|
||||
public static void GetBezierList(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
|
||||
Vector3 lsp, Vector3 nep, float smoothness = 2f, float k = 2.0f)
|
||||
{
|
||||
float dist = Mathf.Abs(sp.x - ep.x);
|
||||
Vector3 cp1, cp2;
|
||||
var dir = (ep - sp).normalized;
|
||||
var diff = dist / k;
|
||||
if (lsp == sp)
|
||||
{
|
||||
cp1 = sp + dist / k * dir * 1;
|
||||
cp1.y = sp.y;
|
||||
cp1 = sp;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp1 = sp + (ep - lsp).normalized * diff;
|
||||
}
|
||||
if (nep == ep) cp2 = ep;
|
||||
else cp2 = ep - (nep - sp).normalized * diff;
|
||||
dist = Vector3.Distance(sp, ep);
|
||||
int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness));
|
||||
if (segment < 1) segment = (int)(dist / 0.5f);
|
||||
if (segment < 4) segment = 4;
|
||||
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
|
||||
if (posList.Count < 2)
|
||||
{
|
||||
posList.Clear();
|
||||
posList.Add(sp);
|
||||
posList.Add(ep);
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetBezierListVertical(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
|
||||
float smoothness = 2f, float k = 2.0f)
|
||||
{
|
||||
Vector3 dir = (ep - sp).normalized;
|
||||
float dist = Vector3.Distance(sp, ep);
|
||||
Vector3 cp1 = sp + dist / k * dir * 1;
|
||||
Vector3 cp2 = sp + dist / k * dir * (k - 1);
|
||||
cp1.x = sp.x;
|
||||
cp2.x = ep.x;
|
||||
int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness));
|
||||
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
|
||||
if (posList.Count < 2)
|
||||
{
|
||||
posList.Clear();
|
||||
posList.Add(sp);
|
||||
posList.Add(ep);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp)
|
||||
{
|
||||
List<Vector3> list = new List<Vector3>();
|
||||
for (int i = 0; i < segment; i++)
|
||||
{
|
||||
list.Add(GetBezier(i / (float)segment, sp, cp, ep));
|
||||
}
|
||||
list.Add(ep);
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, int segment, Vector3 cp,
|
||||
Vector3 cp2)
|
||||
{
|
||||
posList.Clear();
|
||||
if (posList.Capacity < segment + 1)
|
||||
{
|
||||
posList.Capacity = segment + 1;
|
||||
}
|
||||
for (int i = 0; i < segment; i++)
|
||||
{
|
||||
posList.Add((GetBezier2(i / (float)segment, sp, cp, cp2, ep)));
|
||||
}
|
||||
posList.Add(ep);
|
||||
}
|
||||
|
||||
public static Vector3 GetBezier(float t, Vector3 sp, Vector3 cp, Vector3 ep)
|
||||
{
|
||||
Vector3 aa = sp + (cp - sp) * t;
|
||||
Vector3 bb = cp + (ep - cp) * t;
|
||||
return aa + (bb - aa) * t;
|
||||
}
|
||||
|
||||
public static Vector3 GetBezier2(float t, Vector3 sp, Vector3 p1, Vector3 p2, Vector3 ep)
|
||||
{
|
||||
t = Mathf.Clamp01(t);
|
||||
var oneMinusT = 1f - t;
|
||||
return oneMinusT * oneMinusT * oneMinusT * sp +
|
||||
3f * oneMinusT * oneMinusT * t * p1 +
|
||||
3f * oneMinusT * t * t * p2 +
|
||||
t * t * t * ep;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
|
||||
{
|
||||
return color1.a == color2.a &&
|
||||
@@ -896,70 +802,7 @@ namespace XCharts
|
||||
}
|
||||
|
||||
|
||||
//获取两直线交点
|
||||
public static Vector3 GetIntersection(Vector3 lineAStart, Vector3 lineAEnd, Vector3 lineBStart,
|
||||
Vector3 lineBEnd)
|
||||
{
|
||||
float x1 = lineAStart.x, y1 = lineAStart.y;
|
||||
float x2 = lineAEnd.x, y2 = lineAEnd.y;
|
||||
float x3 = lineBStart.x, y3 = lineBStart.y;
|
||||
float x4 = lineBEnd.x, y4 = lineBEnd.y;
|
||||
if (x1 == x2 && x3 == x4 && x1 == x3)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
if (y1 == y2 && y3 == y4 && y1 == y3)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
if (x1 == x2 && x3 == x4)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
if (y1 == y2 && y3 == y4)
|
||||
{
|
||||
return Vector3.zero;
|
||||
}
|
||||
float x, y;
|
||||
if (x1 == x2)
|
||||
{
|
||||
float m2 = (y4 - y3) / (x4 - x3);
|
||||
float c2 = -m2 * x3 + y3;
|
||||
x = x1;
|
||||
y = c2 + m2 * x1;
|
||||
}
|
||||
else if (x3 == x4)
|
||||
{
|
||||
float m1 = (y2 - y1) / (x2 - x1);
|
||||
float c1 = -m1 * x1 + y1;
|
||||
x = x3;
|
||||
y = c1 + m1 * x3;
|
||||
}
|
||||
else
|
||||
{
|
||||
float m1 = (y2 - y1) / (x2 - x1);
|
||||
float c1 = -m1 * x1 + y1;
|
||||
float m2 = (y4 - y3) / (x4 - x3);
|
||||
float c2 = -m2 * x3 + y3;
|
||||
x = (c1 - c2) / (m2 - m1);
|
||||
y = c2 + m2 * x;
|
||||
}
|
||||
|
||||
if (IsInsideLine(lineAStart, lineAEnd, x, y) &&
|
||||
IsInsideLine(lineBStart, lineBEnd, x, y))
|
||||
{
|
||||
return new Vector3(x, y, 0);
|
||||
}
|
||||
return Vector3.zero;
|
||||
}
|
||||
|
||||
private static bool IsInsideLine(Vector3 start, Vector3 end, float x, float y)
|
||||
{
|
||||
return ((x >= start.x && x <= end.x)
|
||||
|| (x >= end.x && x <= start.x))
|
||||
&& ((y >= start.y && y <= end.y)
|
||||
|| (y >= end.y && y <= start.y));
|
||||
}
|
||||
|
||||
|
||||
public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
|
||||
{
|
||||
|
||||
@@ -124,8 +124,8 @@ namespace XCharts
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series, serie.stack);
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration);
|
||||
double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
double xMinValue = xAxis.context.minValue;
|
||||
double xMaxValue = xAxis.context.maxValue;
|
||||
var isAllBarEnd = true;
|
||||
serie.containerIndex = grid.index;
|
||||
serie.containterInstanceId = grid.instanceId;
|
||||
@@ -266,10 +266,10 @@ namespace XCharts
|
||||
var isPercentStack = SeriesHelper.IsPercentStack<Bar>(chart.series, serie.stack);
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration);
|
||||
double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
double yMinValue = yAxis.GetCurrMinValue(dataChangeDuration);
|
||||
double yMaxValue = yAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
double xMinValue = xAxis.context.minValue;
|
||||
double xMaxValue = xAxis.context.maxValue;
|
||||
double yMinValue = yAxis.context.minValue;
|
||||
double yMaxValue = yAxis.context.maxValue;
|
||||
var isAllBarEnd = true;
|
||||
serie.containerIndex = grid.index;
|
||||
serie.containterInstanceId = grid.instanceId;
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace XCharts
|
||||
|
||||
bool dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double yMinValue = yAxis.GetCurrMinValue(dataChangeDuration);
|
||||
double yMaxValue = yAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
double yMinValue = yAxis.context.minValue;
|
||||
double yMaxValue = yAxis.context.maxValue;
|
||||
var isAllBarEnd = true;
|
||||
var isYAxis = false;
|
||||
serie.containerIndex = grid.index;
|
||||
|
||||
@@ -562,10 +562,10 @@ namespace XCharts
|
||||
return 0;
|
||||
}
|
||||
float xDataHig, yDataHig;
|
||||
double xMinValue = xAxis.GetCurrMinValue(duration);
|
||||
double xMaxValue = xAxis.GetCurrMaxValue(duration);
|
||||
double yMinValue = yAxis.GetCurrMinValue(duration);
|
||||
double yMaxValue = yAxis.GetCurrMaxValue(duration);
|
||||
double xMinValue = xAxis.context.minValue;
|
||||
double xMaxValue = xAxis.context.maxValue;
|
||||
double yMinValue = yAxis.context.minValue;
|
||||
double yMaxValue = yAxis.context.maxValue;
|
||||
if (xAxis.IsValue() || xAxis.IsLog() || xAxis.IsTime())
|
||||
{
|
||||
var axisLineWidth = xAxis.axisLine.GetWidth(chart.theme.axis.lineWidth);
|
||||
@@ -690,8 +690,8 @@ namespace XCharts
|
||||
var rate = LineHelper.GetDataAverageRate(serie, grid, maxCount, true);
|
||||
var dataChanging = false;
|
||||
float dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
double xMinValue = xAxis.GetCurrMinValue(dataChangeDuration);
|
||||
double xMaxValue = xAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
double xMinValue = xAxis.context.minValue;
|
||||
double xMaxValue = xAxis.context.maxValue;
|
||||
|
||||
serie.containerIndex = grid.index;
|
||||
serie.containterInstanceId = grid.instanceId;
|
||||
@@ -1171,7 +1171,8 @@ namespace XCharts
|
||||
var eindex = 0;
|
||||
var sp = LineHelper.GetStartPos(points, ref sindex, serie.ignoreLineBreak);
|
||||
var ep = LineHelper.GetEndPos(points, ref eindex, serie.ignoreLineBreak);
|
||||
var cross = ChartHelper.GetIntersection(lp, np, zeroPos, aep);
|
||||
var cross = Vector3.zero;
|
||||
UGLHelper.GetIntersection(lp, np, zeroPos, aep, ref cross);
|
||||
|
||||
if (cross == Vector3.zero || smoothDownPoints.Count <= 3)
|
||||
{
|
||||
@@ -1194,13 +1195,15 @@ namespace XCharts
|
||||
var axisUpEnd = axisUpStart + (isYAxis ? Vector3.up * grid.context.height : Vector3.right * grid.context.width);
|
||||
var axisDownStart = zeroPos - (isYAxis ? Vector3.right : Vector3.up) * axisLineWidth;
|
||||
var axisDownEnd = axisDownStart + (isYAxis ? Vector3.up * grid.context.height : Vector3.right * grid.context.width);
|
||||
var luPos = ChartHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd);
|
||||
var luPos = Vector3.zero;
|
||||
UGLHelper.GetIntersection(sp1, ep1, axisUpStart, axisUpEnd, ref cross);
|
||||
var ecount = smoothPoints.Count - 2;
|
||||
if (ecount < 0) ecount = 0;
|
||||
|
||||
sp1 = smoothPoints[0];
|
||||
ep1 = smoothPoints[ecount];
|
||||
var rdPos = ChartHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd);
|
||||
var rdPos = Vector3.zero;
|
||||
UGLHelper.GetIntersection(sp1, ep1, axisDownStart, axisDownEnd, ref rdPos);
|
||||
|
||||
if ((isYAxis && lp.x >= zeroPos.x) || (!isYAxis && lp.y >= zeroPos.y))
|
||||
{
|
||||
@@ -1471,9 +1474,9 @@ namespace XCharts
|
||||
}
|
||||
|
||||
if (isYAxis)
|
||||
ChartHelper.GetBezierListVertical(ref bezierPoints, lp, np, settings.lineSmoothness, settings.lineSmoothStyle);
|
||||
UGLHelper.GetBezierListVertical(ref bezierPoints, lp, np, settings.lineSmoothness, settings.lineSmoothStyle);
|
||||
else
|
||||
ChartHelper.GetBezierList(ref bezierPoints, lp, np, llp, nnp, settings.lineSmoothness, settings.lineSmoothStyle);
|
||||
UGLHelper.GetBezierList(ref bezierPoints, lp, np, llp, nnp, settings.lineSmoothness, settings.lineSmoothStyle);
|
||||
|
||||
Vector3 start, to;
|
||||
if (serie.lineType == LineType.SmoothDash)
|
||||
|
||||
@@ -34,9 +34,8 @@ namespace XCharts
|
||||
var startAngle = m_AngleAxis.startAngle;
|
||||
var radius = m_Polar.context.radius;
|
||||
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var min = m_RadiusAxis.GetCurrMinValue(dataChangeDuration);
|
||||
var max = m_RadiusAxis.GetCurrMaxValue(dataChangeDuration);
|
||||
var min = m_RadiusAxis.context.minValue;
|
||||
var max = m_RadiusAxis.context.maxValue;
|
||||
var firstSerieData = datas[0];
|
||||
var startPos = GetPolarPos(m_Polar, m_AngleAxis, firstSerieData, min, max, radius);
|
||||
var nextPos = Vector3.zero;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
@@ -19,13 +20,20 @@ namespace XCharts
|
||||
public static void AddDefaultSerie(BaseChart chart, string serieName)
|
||||
{
|
||||
var serie = chart.AddSerie<Parallel>(serieName);
|
||||
serie.itemStyle.show = true;
|
||||
serie.itemStyle.borderWidth = 1;
|
||||
serie.itemStyle.borderColor = Color.clear;
|
||||
serie.emphasis.show = true;
|
||||
serie.emphasis.itemStyle.show = true;
|
||||
serie.emphasis.itemStyle.borderWidth = 1;
|
||||
serie.emphasis.itemStyle.borderColor = Color.black;
|
||||
serie.lineStyle.width = 0.8f;
|
||||
serie.lineStyle.opacity = 0.6f;
|
||||
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
var data = new List<double>(){
|
||||
Random.Range(0f,50f),
|
||||
Random.Range(0f,100f),
|
||||
Random.Range(0f,1000f),
|
||||
Random.Range(0,5),
|
||||
};
|
||||
serie.AddData(data, "data" + i);
|
||||
}
|
||||
chart.RefreshChart();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
/* */
|
||||
/************************************************/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using XUGL;
|
||||
@@ -14,6 +15,8 @@ namespace XCharts
|
||||
[UnityEngine.Scripting.Preserve]
|
||||
internal sealed class ParallelHandler : SerieHandler<Parallel>
|
||||
{
|
||||
private List<Vector3> m_Points = new List<Vector3>();
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@@ -28,36 +31,11 @@ namespace XCharts
|
||||
|
||||
private void UpdateSerieContext()
|
||||
{
|
||||
if (!chart.isPointerInChart)
|
||||
return;
|
||||
|
||||
var themeSymbolSize = chart.theme.serie.lineSymbolSize;
|
||||
|
||||
serie.context.pointerItemDataIndex = -1;
|
||||
serie.context.pointerEnter = false;
|
||||
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
var dist = Vector3.Distance(chart.pointerPos, serieData.runtimePosition);
|
||||
var symbol = SerieHelper.GetSerieSymbol(serie, serieData);
|
||||
var symbolSize = symbol.GetSize(serieData.data, themeSymbolSize);
|
||||
|
||||
if (dist <= symbolSize)
|
||||
{
|
||||
serie.context.pointerItemDataIndex = serieData.index;
|
||||
serie.context.pointerEnter = true;
|
||||
serieData.highlighted = true;
|
||||
chart.RefreshTopPainter();
|
||||
}
|
||||
else
|
||||
{
|
||||
serieData.highlighted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawParallelSerie(VertexHelper vh, int colorIndex, Parallel serie)
|
||||
{
|
||||
if (!serie.show) return;
|
||||
if (serie.animation.HasFadeOut()) return;
|
||||
|
||||
var parallel = chart.GetChartComponent<ParallelCoord>(serie.parallelIndex);
|
||||
@@ -69,40 +47,90 @@ namespace XCharts
|
||||
return;
|
||||
|
||||
var animationIndex = serie.animation.GetCurrIndex();
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var dataChanging = false;
|
||||
var isHorizonal = parallel.orient == Orient.Horizonal;
|
||||
var lineColor = SerieHelper.GetLineColor(serie, chart.theme, colorIndex, false);
|
||||
var lineWidth = serie.lineStyle.GetWidth(chart.theme.serie.lineWidth);
|
||||
|
||||
float currDetailProgress = parallel.context.x;
|
||||
float totalDetailProgress = parallel.context.x + parallel.context.width;
|
||||
if (serie.animation.alongWithLinePath)
|
||||
{
|
||||
//TODO:
|
||||
}
|
||||
serie.animation.InitProgress(0, currDetailProgress, totalDetailProgress);
|
||||
float currDetailProgress = !isHorizonal
|
||||
? parallel.context.x
|
||||
: parallel.context.y;
|
||||
|
||||
float totalDetailProgress = !isHorizonal
|
||||
? parallel.context.x + parallel.context.width
|
||||
: parallel.context.y + parallel.context.height;
|
||||
|
||||
serie.animation.InitProgress(serie.showDataDimension, currDetailProgress, totalDetailProgress);
|
||||
serie.animation.SetDataFinish(0);
|
||||
|
||||
serie.dataPoints.Clear();
|
||||
serie.containerIndex = parallel.index;
|
||||
serie.containterInstanceId = parallel.instanceId;
|
||||
|
||||
Vector3 sp, np;
|
||||
var currProgress = serie.animation.GetCurrDetail();
|
||||
var isSmooth = serie.lineType == LineType.Smooth;
|
||||
foreach (var serieData in serie.data)
|
||||
{
|
||||
sp = GetPos(parallel, 0, serieData.data[0], isHorizonal);
|
||||
m_Points.Clear();
|
||||
var count = Mathf.Min(axisCount, serieData.data.Count);
|
||||
for (int i = 1; i < count; i++)
|
||||
var lp = Vector3.zero;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
np = GetPos(parallel, i, serieData.data[i], isHorizonal);
|
||||
UGL.DrawLine(vh, sp, np, lineWidth, lineColor);
|
||||
sp = np;
|
||||
if (animationIndex >= 0 && i > animationIndex) continue;
|
||||
var pos = GetPos(parallel, i, serieData.data[i], isHorizonal);
|
||||
if (!isHorizonal)
|
||||
{
|
||||
if (isSmooth)
|
||||
{
|
||||
m_Points.Add(pos);
|
||||
}
|
||||
else if (pos.x <= currProgress)
|
||||
{
|
||||
m_Points.Add(pos);
|
||||
serie.animation.SetDataFinish(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
var currProgressStart = new Vector3(currProgress, parallel.context.y - 50);
|
||||
var currProgressEnd = new Vector3(currProgress, parallel.context.y + parallel.context.height + 50);
|
||||
var intersectionPos = Vector3.zero;
|
||||
|
||||
if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos))
|
||||
m_Points.Add(intersectionPos);
|
||||
else
|
||||
m_Points.Add(pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSmooth)
|
||||
{
|
||||
m_Points.Add(pos);
|
||||
}
|
||||
else if (pos.y <= currProgress)
|
||||
{
|
||||
m_Points.Add(pos);
|
||||
serie.animation.SetDataFinish(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
var currProgressStart = new Vector3(parallel.context.x - 50, currProgress);
|
||||
var currProgressEnd = new Vector3(parallel.context.x + parallel.context.width + 50, currProgress);
|
||||
var intersectionPos = Vector3.zero;
|
||||
|
||||
if (UGLHelper.GetIntersection(lp, pos, currProgressStart, currProgressEnd, ref intersectionPos))
|
||||
m_Points.Add(intersectionPos);
|
||||
else
|
||||
m_Points.Add(pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lp = pos;
|
||||
}
|
||||
}
|
||||
if (dataChanging)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
if (isSmooth)
|
||||
UGL.DrawCurves(vh, m_Points, lineWidth, lineColor, chart.settings.lineSmoothness, currProgress, isHorizonal);
|
||||
else
|
||||
UGL.DrawLine(vh, m_Points, lineWidth, lineColor, isSmooth);
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
|
||||
@@ -126,6 +126,48 @@ namespace XUGL
|
||||
DrawTriangle(vh, dnPos, upPos1, upPos2, color);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DrawLine(VertexHelper vh, List<Vector3> points, float width, Color32 color, bool smooth)
|
||||
{
|
||||
if (points.Count < 2) return;
|
||||
else if (points.Count <= 2)
|
||||
{
|
||||
DrawLine(vh, points[0], points[1], width, color);
|
||||
}
|
||||
else if (smooth)
|
||||
{
|
||||
DrawCurves(vh, points, width, color, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
var lineLT = Vector3.zero;
|
||||
var lineLB = Vector3.zero;
|
||||
var ltp = Vector3.zero;
|
||||
var lbp = Vector3.zero;
|
||||
var ntp = Vector3.zero;
|
||||
var nbp = Vector3.zero;
|
||||
var itp = Vector3.zero;
|
||||
var ibp = Vector3.zero;
|
||||
for (int i = 1; i < points.Count - 1; i++)
|
||||
{
|
||||
UGLHelper.GetLinePoints(points[i - 1], points[i], points[i + 1], width,
|
||||
ref ltp, ref lbp, ref ntp, ref nbp, ref itp, ref ibp);
|
||||
|
||||
if (i == 1)
|
||||
{
|
||||
lineLT = ltp;
|
||||
lineLB = lbp;
|
||||
}
|
||||
|
||||
DrawQuadrilateral(vh, lineLB, ibp, itp, lineLT, color);
|
||||
|
||||
lineLT = itp;
|
||||
lineLB = ibp;
|
||||
}
|
||||
DrawQuadrilateral(vh, lineLB, nbp, ntp, lineLT, color);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Draw a dash line. 画虚线
|
||||
/// </summary>
|
||||
@@ -1619,17 +1661,58 @@ namespace XUGL
|
||||
var dist = Vector3.Distance(sp, ep);
|
||||
var segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness));
|
||||
UGLHelper.GetBezierList2(ref s_CurvesPosList, sp, ep, segment, cp1, cp2);
|
||||
if (s_CurvesPosList.Count > 1)
|
||||
DrawCurvesInternal(vh, s_CurvesPosList, lineWidth, lineColor);
|
||||
}
|
||||
|
||||
public static void DrawCurves(VertexHelper vh, List<Vector3> points, float width, Color32 color,
|
||||
float smoothness, float currProgress = float.PositiveInfinity, bool isYAxis = false)
|
||||
{
|
||||
for (int i = 0; i < points.Count - 1; i++)
|
||||
{
|
||||
var start = s_CurvesPosList[0];
|
||||
var sp = points[i];
|
||||
var ep = points[i + 1];
|
||||
var lsp = i > 0 ? points[i - 1] : sp;
|
||||
var nep = i < points.Count - 2 ? points[i + 2] : ep;
|
||||
if (currProgress != float.PositiveInfinity)
|
||||
{
|
||||
var smoothness2 = 0f;
|
||||
if (isYAxis)
|
||||
smoothness2 = ep.y <= currProgress ? smoothness : smoothness * 0.5f;
|
||||
else
|
||||
smoothness2 = ep.x <= currProgress ? smoothness : smoothness * 0.5f;
|
||||
|
||||
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness2);
|
||||
}
|
||||
else
|
||||
{
|
||||
UGLHelper.GetBezierList(ref s_CurvesPosList, sp, ep, lsp, nep, smoothness);
|
||||
}
|
||||
DrawCurvesInternal(vh, s_CurvesPosList, width, color, currProgress, isYAxis);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawCurvesInternal(VertexHelper vh, List<Vector3> curvesPosList, float lineWidth,
|
||||
Color32 lineColor, float currProgress = float.PositiveInfinity, bool isYAxis = false)
|
||||
{
|
||||
if (curvesPosList.Count > 1)
|
||||
{
|
||||
var start = curvesPosList[0];
|
||||
var to = Vector3.zero;
|
||||
var dir = s_CurvesPosList[1] - start;
|
||||
var dir = curvesPosList[1] - start;
|
||||
var diff = Vector3.Cross(dir, Vector3.forward).normalized * lineWidth;
|
||||
var startUp = start - diff;
|
||||
var startDn = start + diff;
|
||||
for (int i = 1; i < s_CurvesPosList.Count; i++)
|
||||
for (int i = 1; i < curvesPosList.Count; i++)
|
||||
{
|
||||
to = s_CurvesPosList[i];
|
||||
to = curvesPosList[i];
|
||||
if (currProgress != float.PositiveInfinity)
|
||||
{
|
||||
if (isYAxis && to.y > currProgress)
|
||||
break;
|
||||
if (!isYAxis && to.x > currProgress)
|
||||
break;
|
||||
}
|
||||
|
||||
diff = Vector3.Cross(to - start, Vector3.forward).normalized * lineWidth;
|
||||
var toUp = to - diff;
|
||||
var toDn = to + diff;
|
||||
|
||||
@@ -14,53 +14,66 @@ namespace XUGL
|
||||
{
|
||||
public static bool IsValueEqualsColor(Color32 color1, Color32 color2)
|
||||
{
|
||||
return color1.a == color2.a &&
|
||||
color1.b == color2.b &&
|
||||
color1.g == color2.g &&
|
||||
color1.r == color2.r;
|
||||
return color1.a == color2.a
|
||||
&& color1.b == color2.b
|
||||
&& color1.g == color2.g
|
||||
&& color1.r == color2.r;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsColor(Color color1, Color color2)
|
||||
{
|
||||
return color1.a == color2.a &&
|
||||
color1.b == color2.b &&
|
||||
color1.g == color2.g &&
|
||||
color1.r == color2.r;
|
||||
return color1.a == color2.a
|
||||
&& color1.b == color2.b
|
||||
&& color1.g == color2.g
|
||||
&& color1.r == color2.r;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsString(string str1, string str2)
|
||||
{
|
||||
if (str1 == null && str2 == null) return true;
|
||||
else if (str1 != null && str2 != null) return str1.Equals(str2);
|
||||
if (str1 == null && str2 == null)
|
||||
return true;
|
||||
else if (str1 != null && str2 != null)
|
||||
return str1.Equals(str2);
|
||||
else return false;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsVector2(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
return v1.x == v2.x && v1.y == v2.y;
|
||||
return v1.x == v2.x
|
||||
&& v1.y == v2.y;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsVector3(Vector3 v1, Vector3 v2)
|
||||
{
|
||||
return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z;
|
||||
return v1.x == v2.x
|
||||
&& v1.y == v2.y
|
||||
&& v1.z == v2.z;
|
||||
}
|
||||
|
||||
public static bool IsValueEqualsList<T>(List<T> list1, List<T> list2)
|
||||
{
|
||||
if (list1 == null || list2 == null) return false;
|
||||
if (list1.Count != list2.Count) return false;
|
||||
if (list1 == null || list2 == null)
|
||||
return false;
|
||||
|
||||
if (list1.Count != list2.Count)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < list1.Count; i++)
|
||||
{
|
||||
if (list1[i] == null && list2[i] == null) { }
|
||||
if (list1[i] == null && list2[i] == null)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (list1[i] != null)
|
||||
{
|
||||
if (!list1[i].Equals(list2[i])) return false;
|
||||
if (!list1[i].Equals(list2[i]))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!list2[i].Equals(list1[i])) return false;
|
||||
if (!list2[i].Equals(list1[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,17 +82,25 @@ namespace XUGL
|
||||
|
||||
public static bool IsClearColor(Color32 color)
|
||||
{
|
||||
return color.a == 0 && color.b == 0 && color.g == 0 && color.r == 0;
|
||||
return color.a == 0
|
||||
&& color.b == 0
|
||||
&& color.g == 0
|
||||
&& color.r == 0;
|
||||
}
|
||||
|
||||
public static bool IsClearColor(Color color)
|
||||
{
|
||||
return color.a == 0 && color.b == 0 && color.g == 0 && color.r == 0;
|
||||
return color.a == 0
|
||||
&& color.b == 0
|
||||
&& color.g == 0
|
||||
&& color.r == 0;
|
||||
}
|
||||
|
||||
public static bool IsZeroVector(Vector3 pos)
|
||||
{
|
||||
return pos.x == 0 && pos.y == 0 && pos.z == 0;
|
||||
return pos.x == 0
|
||||
&& pos.y == 0
|
||||
&& pos.z == 0;
|
||||
}
|
||||
|
||||
public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
|
||||
@@ -113,6 +134,12 @@ namespace XUGL
|
||||
if (segment < 1) segment = (int)(dist / 0.5f);
|
||||
if (segment < 4) segment = 4;
|
||||
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
|
||||
if (posList.Count < 2)
|
||||
{
|
||||
posList.Clear();
|
||||
posList.Add(sp);
|
||||
posList.Add(ep);
|
||||
}
|
||||
}
|
||||
|
||||
public static void GetBezierListVertical(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
|
||||
@@ -126,6 +153,12 @@ namespace XUGL
|
||||
cp2.x = ep.x;
|
||||
int segment = (int)(dist / (smoothness <= 0 ? 2f : smoothness));
|
||||
GetBezierList2(ref posList, sp, ep, segment, cp1, cp2);
|
||||
if (posList.Count < 2)
|
||||
{
|
||||
posList.Clear();
|
||||
posList.Add(sp);
|
||||
posList.Add(ep);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Vector3> GetBezierList(Vector3 sp, Vector3 ep, int segment, Vector3 cp)
|
||||
@@ -139,8 +172,8 @@ namespace XUGL
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep, int segment, Vector3 cp,
|
||||
Vector3 cp2)
|
||||
public static void GetBezierList2(ref List<Vector3> posList, Vector3 sp, Vector3 ep,
|
||||
int segment, Vector3 cp, Vector3 cp2)
|
||||
{
|
||||
posList.Clear();
|
||||
if (posList.Capacity < segment + 1)
|
||||
@@ -180,17 +213,12 @@ namespace XUGL
|
||||
public static Vector3 GetVertialDire(Vector3 dire)
|
||||
{
|
||||
if (dire.x == 0)
|
||||
{
|
||||
return new Vector3(-1, 0, 0);
|
||||
}
|
||||
|
||||
if (dire.y == 0)
|
||||
{
|
||||
return new Vector3(0, -1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new Vector3(-dire.y / dire.x, 1, 0).normalized;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -213,7 +241,77 @@ namespace XUGL
|
||||
public static Vector3 GetPos(Vector3 center, float radius, float angle, bool isDegree = false)
|
||||
{
|
||||
angle = isDegree ? angle * Mathf.Deg2Rad : angle;
|
||||
return new Vector3(center.x + radius * Mathf.Sin(angle), center.y + radius * Mathf.Cos(angle));
|
||||
return new Vector3(center.x + radius * Mathf.Sin(angle),
|
||||
center.y + radius * Mathf.Cos(angle));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得两直线的交点
|
||||
/// </summary>
|
||||
/// <param name="p1">线段1起点</param>
|
||||
/// <param name="p2">线段1终点</param>
|
||||
/// <param name="p3">线段2起点</param>
|
||||
/// <param name="p4">线段2终点</param>
|
||||
/// <param name="intersection">相交点。当不想交时默认为 Vector3.zero </param>
|
||||
/// <returns>相交则返回 true, 否则返回 false</returns>
|
||||
public static bool GetIntersection(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, ref Vector3 intersection)
|
||||
{
|
||||
intersection = Vector3.zero;
|
||||
|
||||
var d = (p2.x - p1.x) * (p4.y - p3.y) - (p2.y - p1.y) * (p4.x - p3.x);
|
||||
if (d == 0)
|
||||
return false;
|
||||
|
||||
var u = ((p3.x - p1.x) * (p4.y - p3.y) - (p3.y - p1.y) * (p4.x - p3.x)) / d;
|
||||
var v = ((p3.x - p1.x) * (p2.y - p1.y) - (p3.y - p1.y) * (p2.x - p1.x)) / d;
|
||||
if (u < 0 || u > 1 || v < 0 || v > 1)
|
||||
return false;
|
||||
|
||||
intersection.x = p1.x + u * (p2.x - p1.x);
|
||||
intersection.y = p1.y + u * (p2.y - p1.y);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三个点画线段所需要的六个关键点
|
||||
/// </summary>
|
||||
/// <param name="lp">上一个点</param>
|
||||
/// <param name="cp">当前点</param>
|
||||
/// <param name="np">下一个点</param>
|
||||
/// <param name="width">线段宽度</param>
|
||||
/// <param name="ltp">上一个点的上角点</param>
|
||||
/// <param name="lbp">上一个点的下角点</param>
|
||||
/// <param name="ntp">下一个点的上角点</param>
|
||||
/// <param name="nbp">下一个点的下角点</param>
|
||||
/// <param name="itp">交汇点的上角点</param>
|
||||
/// <param name="ibp">交汇点的下角点</param>
|
||||
internal static void GetLinePoints(Vector3 lp, Vector3 cp, Vector3 np, float width,
|
||||
ref Vector3 ltp, ref Vector3 lbp,
|
||||
ref Vector3 ntp, ref Vector3 nbp,
|
||||
ref Vector3 itp, ref Vector3 ibp)
|
||||
{
|
||||
var dir1 = (cp - lp).normalized;
|
||||
var dir2 = (cp - np).normalized;
|
||||
var dir1v = Vector3.Cross(dir1, Vector3.forward).normalized;
|
||||
var dir2v = Vector3.Cross(dir2, Vector3.back).normalized;
|
||||
|
||||
ltp = lp + dir1v * width;
|
||||
lbp = lp - dir1v * width;
|
||||
|
||||
ntp = np + dir2v * width;
|
||||
nbp = np - dir2v * width;
|
||||
|
||||
var ldist = 1.3f * Vector3.Distance(cp, lp) * dir1;
|
||||
var rdist = 1.3f * Vector3.Distance(cp, np) * dir2;
|
||||
|
||||
if (!UGLHelper.GetIntersection(ltp, ltp + ldist, ntp, ntp + rdist, ref itp))
|
||||
{
|
||||
itp = cp + dir1v * width;
|
||||
}
|
||||
if (!UGLHelper.GetIntersection(lbp, lbp + ldist, nbp, nbp + rdist, ref ibp))
|
||||
{
|
||||
ibp = cp - dir1v * width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user