mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-20 23:40:10 +00:00
增加LiquidChart的方形水位图支持
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
|
||||
## Latest
|
||||
|
||||
* (2021.05.08) Added `Liquidchart` support for `Rect` shape
|
||||
* (2021.05.07) Improved the `Axis` scale performance #135
|
||||
* (2021.05.01) Added `Settings` parameters for painter's material #140
|
||||
* (2021.05.01) Fixed an issue where some super large or super small values could not be properly represented
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
## Latest
|
||||
|
||||
* (2021.05.08) 增加`LiquidChart`的方形水位图支持
|
||||
* (2021.05.07) 优化`Axis`的刻度表现 #135
|
||||
* (2021.05.01) 增加`Settings`中关于关于材质球设置的参数 #140
|
||||
* (2021.05.01) 修复无法正确表示部分超大或超小数值的问题
|
||||
|
||||
@@ -260,11 +260,14 @@
|
||||
* `shapeWidth`:容器的厚度。
|
||||
* `gap`:间隙。容器和液体的间隙。
|
||||
* `center`:中心点。数组的第一项是横坐标,第二项是纵坐标。当值为0-1之间时表示百分比,设置成百分比时表示图表宽高最小值的百分比。
|
||||
* `radius`:半径。
|
||||
* `smoothness`:开启或关闭缩放区域功能。
|
||||
* `backgroundColor`:背景色,默认透明。
|
||||
* `color`:容器颜色。当`autoColor`为`false`时生效。
|
||||
* `autoColor`:是否自动颜色。默认`true`。为`true`时颜色会和`serie`一致。
|
||||
* `radius`:半径。
|
||||
* `smoothness`:开启或关闭缩放区域功能。
|
||||
* `width`:容器的宽。shape为Rect时有效。
|
||||
* `height`:容器的高。shape为Rect时有效。
|
||||
* `cornerRadius`: 容器的圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。shape为Rect时有效。
|
||||
|
||||
## `DataZoom`
|
||||
|
||||
|
||||
@@ -266,6 +266,9 @@ Vessel component for liquid chart. There can be multiple vessels in a Chart, whi
|
||||
* `backgroundColor`: Background color of polar, which is transparent by default. [default: `Color.clear`]
|
||||
* `color`: Vessel color. The default is consistent with Serie. [default: `Color32(70, 70, 240, 255)`]
|
||||
* `autoColor`: Whether automatic color. If true, the color matches serie. [default: `true`]
|
||||
* `width`:The width of vessel. This value is valid when `shape` is `Rect`.
|
||||
* `height`:The height of vessel. This value is valid when `shape` is `Rect`.
|
||||
* `cornerRadius`: The radius of rounded corner. This value is valid when `shape` is `Rect`.
|
||||
|
||||
## `DataZoom`
|
||||
|
||||
|
||||
@@ -20,15 +20,26 @@ namespace XCharts
|
||||
if (MakeFoldout(prop, "m_Show"))
|
||||
{
|
||||
++EditorGUI.indentLevel;
|
||||
var shape = (Vessel.Shape)prop.FindPropertyRelative("m_Shape").intValue;
|
||||
PropertyField(prop, "m_Shape");
|
||||
PropertyField(prop, "m_ShapeWidth");
|
||||
PropertyField(prop, "m_Gap");
|
||||
PropertyTwoFiled(prop, "m_Center");
|
||||
PropertyField(prop, "m_Radius");
|
||||
PropertyField(prop, "m_BackgroundColor");
|
||||
PropertyField(prop, "m_Color");
|
||||
PropertyField(prop, "m_AutoColor");
|
||||
PropertyField(prop, "m_Smoothness");
|
||||
switch (shape)
|
||||
{
|
||||
case Vessel.Shape.Circle:
|
||||
PropertyField(prop, "m_Radius");
|
||||
PropertyField(prop, "m_Smoothness");
|
||||
break;
|
||||
case Vessel.Shape.Rect:
|
||||
PropertyField(prop, "m_Width");
|
||||
PropertyField(prop, "m_Height");
|
||||
PropertyField(prop, "m_CornerRadius");
|
||||
break;
|
||||
}
|
||||
--EditorGUI.indentLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,13 +46,16 @@ namespace XCharts
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private Shape m_Shape = Shape.Circle;
|
||||
[SerializeField] private float m_ShapeWidth = 5f;
|
||||
[SerializeField] private float m_Gap = 10f;
|
||||
[SerializeField] private float m_Gap = 5f;
|
||||
[SerializeField] private Color32 m_Color;
|
||||
[SerializeField] private Color32 m_BackgroundColor;
|
||||
[SerializeField] private bool m_AutoColor = true;
|
||||
[SerializeField] private float[] m_Center = new float[2] { 0.5f, 0.5f };
|
||||
[SerializeField] private float m_Radius = 0.5f;
|
||||
[SerializeField] private float m_Radius = 0.35f;
|
||||
[SerializeField] [Range(0.5f, 10f)] private float m_Smoothness = 1f;
|
||||
[SerializeField] private float m_Width = 0.5f;
|
||||
[SerializeField] private float m_Height = 0.7f;
|
||||
[SerializeField] private float[] m_CornerRadius = new float[] { 0, 0, 0, 0 };
|
||||
|
||||
/// <summary>
|
||||
/// Whether to show the vessel.
|
||||
@@ -108,7 +111,7 @@ namespace XCharts
|
||||
}
|
||||
/// <summary>
|
||||
/// The radius of vessel.
|
||||
/// When value between 0 and 1 represents a percentage relative to the chart.
|
||||
/// When value between 0 and 1 represents a percentage relative to the chart.
|
||||
/// 半径。
|
||||
/// [default: 0.35f]
|
||||
/// </summary>
|
||||
@@ -118,6 +121,28 @@ namespace XCharts
|
||||
set { if (PropertyUtil.SetStruct(ref m_Radius, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The width of vessel.
|
||||
/// When value between 0 and 1 represents a percentage relative to the chart.
|
||||
/// 容器的宽。shape为Rect时有效。
|
||||
/// [default: 0.35f]
|
||||
/// </summary>
|
||||
public float width
|
||||
{
|
||||
get { return m_Width; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Width, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The height of vessel.
|
||||
/// When value between 0 and 1 represents a percentage relative to the chart.
|
||||
/// 容器的高。shape为Rect时有效。
|
||||
/// [default: 0.35f]
|
||||
/// </summary>
|
||||
public float height
|
||||
{
|
||||
get { return m_Height; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_Height, value)) SetAllDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The smoothness of wave.
|
||||
/// 水波平滑度。
|
||||
/// [default: 1f]
|
||||
@@ -156,6 +181,15 @@ namespace XCharts
|
||||
get { return m_AutoColor; }
|
||||
set { if (PropertyUtil.SetStruct(ref m_AutoColor, value)) SetVerticesDirty(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// The radius of rounded corner. Its unit is px. Use array to respectively specify the 4 corner radiuses((clockwise upper left, upper right, bottom right and bottom left)).
|
||||
/// 容器的圆角半径。用数组分别指定4个圆角半径(顺时针左上,右上,右下,左下)。shape为Rect时有效。
|
||||
/// </summary>
|
||||
public float[] cornerRadius
|
||||
{
|
||||
get { return m_CornerRadius; }
|
||||
set { if (PropertyUtil.SetClass(ref m_CornerRadius, value, true)) SetVerticesDirty(); }
|
||||
}
|
||||
public int index { get; internal set; }
|
||||
/// <summary>
|
||||
/// the runtime center position of vessel.
|
||||
@@ -172,6 +206,8 @@ namespace XCharts
|
||||
/// 运行时内半径。扣除厚度和间隙后的实际半径。
|
||||
/// </summary>
|
||||
public float runtimeInnerRadius { get; internal set; }
|
||||
public float runtimeWidth { get; set; }
|
||||
public float runtimeHeight { get; set; }
|
||||
public static Vessel defaultVessel
|
||||
{
|
||||
get
|
||||
@@ -181,8 +217,10 @@ namespace XCharts
|
||||
m_Show = true,
|
||||
m_Shape = Shape.Circle,
|
||||
m_ShapeWidth = 5,
|
||||
m_Gap = 10,
|
||||
m_Gap = 5,
|
||||
m_Radius = 0.35f,
|
||||
m_Width = 0.5f,
|
||||
m_Height = 0.7f,
|
||||
m_AutoColor = true,
|
||||
m_Color = new Color32(70, 70, 240, 255),
|
||||
m_Smoothness = 1
|
||||
|
||||
@@ -113,9 +113,24 @@ namespace XCharts
|
||||
{
|
||||
if (vessel.backgroundColor.a != 0)
|
||||
{
|
||||
var cenPos = vessel.runtimeCenterPos;
|
||||
var radius = vessel.runtimeRadius;
|
||||
UGL.DrawCricle(vh, cenPos, vessel.runtimeInnerRadius, vessel.backgroundColor, chart.settings.cicleSmoothness);
|
||||
switch (vessel.shape)
|
||||
{
|
||||
case Vessel.Shape.Circle:
|
||||
var cenPos = vessel.runtimeCenterPos;
|
||||
var radius = vessel.runtimeRadius;
|
||||
UGL.DrawCricle(vh, cenPos, vessel.runtimeInnerRadius + vessel.gap, vessel.backgroundColor,
|
||||
chart.settings.cicleSmoothness);
|
||||
UGL.DrawDoughnut(vh, cenPos, vessel.runtimeInnerRadius, vessel.runtimeInnerRadius + vessel.gap,
|
||||
vessel.backgroundColor, Color.clear, chart.settings.cicleSmoothness);
|
||||
break;
|
||||
case Vessel.Shape.Rect:
|
||||
UGL.DrawRectangle(vh, vessel.runtimeCenterPos, vessel.runtimeWidth / 2, vessel.runtimeHeight / 2,
|
||||
vessel.backgroundColor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,7 +140,18 @@ namespace XCharts
|
||||
var vessel = chart.GetVessel(serie.vesselIndex);
|
||||
if (vessel != null)
|
||||
{
|
||||
DrawCirleVessel(vh, vessel);
|
||||
switch (vessel.shape)
|
||||
{
|
||||
case Vessel.Shape.Circle:
|
||||
DrawCirleVessel(vh, vessel);
|
||||
break;
|
||||
case Vessel.Shape.Rect:
|
||||
DrawRectVessel(vh, vessel);
|
||||
break;
|
||||
default:
|
||||
DrawCirleVessel(vh, vessel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +161,26 @@ namespace XCharts
|
||||
var radius = vessel.runtimeRadius;
|
||||
var serie = SeriesHelper.GetSerieByVesselIndex(chart.series, vessel.index);
|
||||
var vesselColor = VesselHelper.GetColor(vessel, serie, chart.theme, chart.m_LegendRealShowName);
|
||||
UGL.DrawDoughnut(vh, cenPos, radius - vessel.shapeWidth, radius, vesselColor, Color.clear, chart.settings.cicleSmoothness);
|
||||
if (vessel.gap != 0)
|
||||
{
|
||||
UGL.DrawDoughnut(vh, cenPos, vessel.runtimeInnerRadius, vessel.runtimeInnerRadius + vessel.gap,
|
||||
vessel.backgroundColor, Color.clear, chart.settings.cicleSmoothness);
|
||||
}
|
||||
UGL.DrawDoughnut(vh, cenPos, radius - vessel.shapeWidth, radius, vesselColor, Color.clear,
|
||||
chart.settings.cicleSmoothness);
|
||||
}
|
||||
|
||||
private void DrawRectVessel(VertexHelper vh, Vessel vessel)
|
||||
{
|
||||
var serie = SeriesHelper.GetSerieByVesselIndex(chart.series, vessel.index);
|
||||
var vesselColor = VesselHelper.GetColor(vessel, serie, chart.theme, chart.m_LegendRealShowName);
|
||||
if (vessel.gap != 0)
|
||||
{
|
||||
UGL.DrawBorder(vh, vessel.runtimeCenterPos, vessel.runtimeWidth,
|
||||
vessel.runtimeHeight, vessel.gap, vessel.backgroundColor, 0, vessel.cornerRadius);
|
||||
}
|
||||
UGL.DrawBorder(vh, vessel.runtimeCenterPos, vessel.runtimeWidth + 2 * vessel.gap,
|
||||
vessel.runtimeHeight + 2 * vessel.gap, vessel.shapeWidth, vesselColor, 0, vessel.cornerRadius);
|
||||
}
|
||||
|
||||
private void DrawLiquid(VertexHelper vh, Serie serie)
|
||||
@@ -144,6 +189,22 @@ namespace XCharts
|
||||
if (serie.animation.HasFadeOut()) return;
|
||||
var vessel = chart.GetVessel(serie.vesselIndex);
|
||||
if (vessel == null) return;
|
||||
switch (vessel.shape)
|
||||
{
|
||||
case Vessel.Shape.Circle:
|
||||
DrawCirleLiquid(vh, serie, vessel);
|
||||
break;
|
||||
case Vessel.Shape.Rect:
|
||||
DrawRectLiquid(vh, serie, vessel);
|
||||
break;
|
||||
default:
|
||||
DrawCirleLiquid(vh, serie, vessel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCirleLiquid(VertexHelper vh, Serie serie, Vessel vessel)
|
||||
{
|
||||
var cenPos = vessel.runtimeCenterPos;
|
||||
var radius = vessel.runtimeInnerRadius;
|
||||
var serieData = serie.GetSerieData(0);
|
||||
@@ -160,7 +221,7 @@ namespace XCharts
|
||||
serieData.labelPosition = cenPos;
|
||||
m_UpdateLabelText = true;
|
||||
}
|
||||
if (value == 0) return;
|
||||
if (value <= 0) return;
|
||||
var colorIndex = chart.m_LegendRealShowName.IndexOf(serie.name);
|
||||
|
||||
var realHig = (value - serie.min) / (serie.max - serie.min) * radius * 2;
|
||||
@@ -255,5 +316,120 @@ namespace XCharts
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawRectLiquid(VertexHelper vh, Serie serie, Vessel vessel)
|
||||
{
|
||||
var cenPos = vessel.runtimeCenterPos;
|
||||
var serieData = serie.GetSerieData(0);
|
||||
if (serieData == null) return;
|
||||
var dataChangeDuration = serie.animation.GetUpdateAnimationDuration();
|
||||
var value = serieData.GetCurrData(1, dataChangeDuration);
|
||||
if (serie.runtimeCheckValue != value)
|
||||
{
|
||||
serie.runtimeCheckValue = value;
|
||||
m_UpdateLabelText = true;
|
||||
}
|
||||
if (serieData.labelPosition != cenPos)
|
||||
{
|
||||
serieData.labelPosition = cenPos;
|
||||
m_UpdateLabelText = true;
|
||||
}
|
||||
if (value <= 0) return;
|
||||
var colorIndex = chart.m_LegendRealShowName.IndexOf(serie.name);
|
||||
|
||||
var realHig = (value - serie.min) / (serie.max - serie.min) * vessel.runtimeHeight;
|
||||
serie.animation.InitProgress(1, 0, realHig);
|
||||
var hig = serie.animation.IsFinish() ? realHig : serie.animation.GetCurrDetail();
|
||||
var color = SerieHelper.GetItemColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
var toColor = SerieHelper.GetItemToColor(serie, serieData, chart.theme, colorIndex, false);
|
||||
var isNeedGradient = !ChartHelper.IsValueEqualsColor(color, toColor);
|
||||
var isFull = hig >= vessel.runtimeHeight;
|
||||
if (hig >= vessel.runtimeHeight) hig = vessel.runtimeHeight;
|
||||
if (isFull && !isNeedGradient)
|
||||
{
|
||||
UGL.DrawRectangle(vh, cenPos, vessel.runtimeWidth / 2, vessel.runtimeHeight / 2, toColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
var startY = cenPos.y - vessel.runtimeHeight / 2 + hig;
|
||||
var waveStartPos = new Vector3(cenPos.x - vessel.runtimeWidth / 2, startY);
|
||||
var waveEndPos = new Vector3(cenPos.x + vessel.runtimeWidth / 2, startY);
|
||||
var startX = waveStartPos.x;
|
||||
var endX = waveEndPos.x;
|
||||
|
||||
var step = vessel.smoothness;
|
||||
if (step < 0.5f) step = 0.5f;
|
||||
var lup = waveStartPos;
|
||||
var ldp = new Vector3(startX, vessel.runtimeCenterPos.y - vessel.runtimeHeight / 2);
|
||||
var nup = Vector3.zero;
|
||||
var ndp = Vector3.zero;
|
||||
var angle = 0f;
|
||||
var isStarted = false;
|
||||
var isEnded = false;
|
||||
var waveHeight = isFull ? 0 : serie.waveHeight;
|
||||
serie.runtimeWaveSpeed += serie.waveSpeed * Time.deltaTime;
|
||||
while (startX < endX)
|
||||
{
|
||||
startX += step;
|
||||
if (startX > endX) startX = endX;
|
||||
if (startX > waveStartPos.x && !isStarted)
|
||||
{
|
||||
startX = waveStartPos.x;
|
||||
isStarted = true;
|
||||
}
|
||||
if (startX > waveEndPos.x && !isEnded)
|
||||
{
|
||||
startX = waveEndPos.x;
|
||||
isEnded = true;
|
||||
}
|
||||
var py = Mathf.Sqrt(Mathf.Pow(vessel.runtimeHeight, 2) - Mathf.Pow(Mathf.Abs(cenPos.x - startX), 2));
|
||||
if (startX < waveStartPos.x || startX > waveEndPos.x)
|
||||
{
|
||||
nup = new Vector3(startX, cenPos.y + py);
|
||||
}
|
||||
else
|
||||
{
|
||||
var py2 = waveHeight * Mathf.Sin(1 / serie.waveLength * angle + serie.runtimeWaveSpeed + serie.waveOffset);
|
||||
var nupY = waveStartPos.y + py2;
|
||||
nup = new Vector3(startX, nupY);
|
||||
angle += step;
|
||||
}
|
||||
|
||||
ndp = new Vector3(startX, cenPos.y - vessel.runtimeHeight / 2);
|
||||
if (nup.y > cenPos.y + vessel.runtimeHeight / 2)
|
||||
{
|
||||
nup.y = cenPos.y + vessel.runtimeHeight / 2;
|
||||
}
|
||||
if (nup.y < cenPos.y - vessel.runtimeHeight / 2)
|
||||
{
|
||||
nup.y = cenPos.y - vessel.runtimeHeight / 2;
|
||||
}
|
||||
if (!ChartHelper.IsValueEqualsColor(color, toColor))
|
||||
{
|
||||
var colorMin = cenPos.y - vessel.runtimeHeight;
|
||||
var colorMax = startY + serie.waveHeight;
|
||||
var tcolor1 = Color32.Lerp(color, toColor, 1 - (lup.y - colorMin) / (colorMax - colorMin));
|
||||
var tcolor2 = Color32.Lerp(color, toColor, 1 - (ldp.y - colorMin) / (colorMax - colorMin));
|
||||
UGL.DrawQuadrilateral(vh, lup, nup, ndp, ldp, tcolor1, tcolor2);
|
||||
}
|
||||
else
|
||||
{
|
||||
UGL.DrawQuadrilateral(vh, lup, nup, ndp, ldp, color);
|
||||
}
|
||||
lup = nup;
|
||||
ldp = ndp;
|
||||
}
|
||||
}
|
||||
if (serie.waveSpeed != 0 && Application.isPlaying && !isFull)
|
||||
{
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
if (!serie.animation.IsFinish())
|
||||
{
|
||||
serie.animation.CheckProgress(realHig);
|
||||
chart.m_IsPlayingAnimation = true;
|
||||
chart.RefreshPainter(serie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ namespace XCharts
|
||||
vessel.runtimeCenterPos = chartPosition + new Vector3(centerX, centerY);
|
||||
vessel.runtimeRadius = ChartHelper.GetRuntimeRelativeOrAbsoluteValue(vessel.radius, checkWidth);
|
||||
vessel.runtimeInnerRadius = vessel.runtimeRadius - vessel.shapeWidth - vessel.gap;
|
||||
vessel.runtimeWidth = ChartHelper.GetRuntimeRelativeOrAbsoluteValue(vessel.width, checkWidth) - 2 * vessel.gap;
|
||||
vessel.runtimeHeight = ChartHelper.GetRuntimeRelativeOrAbsoluteValue(vessel.height, chartHeight) - 2 * vessel.gap;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user