diff --git a/Documentation~/en/configuration.md b/Documentation~/en/configuration.md index e2804809..1e5c6e26 100644 --- a/Documentation~/en/configuration.md +++ b/Documentation~/en/configuration.md @@ -1387,6 +1387,9 @@ The style of line. |width|0||the width of line. |length|0||the length of line. |opacity|1||Opacity of the line. Supports value from 0 to 1, and the line will not be drawn when set to 0. +|dashLength|4|v3.8.1|the length of dash line. default value is 0, which means the length of dash line is 12 times of line width. Represents a multiple of the number of segments in a line chart. +|dotLength|2|v3.8.1|the length of dot line. default value is 0, which means the length of dot line is 2 times of line width. Represents a multiple of the number of segments in a line chart. +|gapLength|2|v3.8.1|the length of gap line. default value is 0, which means the length of gap line is 3 times of line width. Represents a multiple of the number of segments in a line chart. ```mdx-code-block diff --git a/Documentation~/zh/changelog.md b/Documentation~/zh/changelog.md index 80f4b359..b697b87f 100644 --- a/Documentation~/zh/changelog.md +++ b/Documentation~/zh/changelog.md @@ -68,6 +68,7 @@ slug: /changelog ## master +* (2023.09.22) 增加`Line`的平滑曲线对`Dash`虚线的支持 * (2023.09.16) 修复`Tooltip`在类目轴无数据时异常报错的问题 (#279) * (2023.09.16) 修复`Pie`无数据时绘制异常的问题 (#278) * (2023.09.12) 增加`Pie`的`radiusGradient`可设置半径方向的渐变效果 diff --git a/Documentation~/zh/configuration.md b/Documentation~/zh/configuration.md index bb57fb03..4ef05de9 100644 --- a/Documentation~/zh/configuration.md +++ b/Documentation~/zh/configuration.md @@ -1387,6 +1387,9 @@ Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart |width|0||线宽。 |length|0||线长。 |opacity|1||线的透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。 +|dashLength|4|v3.8.1|虚线的长度。默认0时为线条宽度的12倍。在折线图中代表分割段数的倍数。 +|dotLength|2|v3.8.1|点线的长度。默认0时为线条宽度的3倍。在折线图中代表分割段数的倍数。 +|gapLength|2|v3.8.1|点线的长度。默认0时为线条宽度的3倍。在折线图中代表分割段数的倍数。 ```mdx-code-block diff --git a/Editor/ChildComponents/LineStyleDrawer.cs b/Editor/ChildComponents/LineStyleDrawer.cs index 17d6facb..7607c38c 100644 --- a/Editor/ChildComponents/LineStyleDrawer.cs +++ b/Editor/ChildComponents/LineStyleDrawer.cs @@ -21,6 +21,9 @@ namespace XCharts.Editor PropertyField(prop, "m_Width"); PropertyField(prop, "m_Length"); PropertyField(prop, "m_Opacity"); + PropertyField(prop, "m_DashLength"); + PropertyField(prop, "m_DotLength"); + PropertyField(prop, "m_GapLength"); --EditorGUI.indentLevel; } } diff --git a/Runtime/Component/Child/LineStyle.cs b/Runtime/Component/Child/LineStyle.cs index d8909a6a..23f868d4 100644 --- a/Runtime/Component/Child/LineStyle.cs +++ b/Runtime/Component/Child/LineStyle.cs @@ -47,6 +47,9 @@ namespace XCharts.Runtime [SerializeField] private float m_Width = 0; [SerializeField] private float m_Length = 0; [SerializeField][Range(0, 1)] private float m_Opacity = 1; + [SerializeField][Since("v3.8.1")] private float m_DashLength = 4; + [SerializeField][Since("v3.8.1")] private float m_DotLength = 2; + [SerializeField][Since("v3.8.1")] private float m_GapLength = 2; /// /// Whether show line. @@ -121,6 +124,39 @@ namespace XCharts.Runtime set { if (PropertyUtil.SetStruct(ref m_Opacity, value)) SetVerticesDirty(); } } + /// + /// the length of dash line. default value is 0, which means the length of dash line is 12 times of line width. + /// Represents a multiple of the number of segments in a line chart. + /// |虚线的长度。默认0时为线条宽度的12倍。在折线图中代表分割段数的倍数。 + /// + public float dashLength + { + get { return m_DashLength; } + set { if (PropertyUtil.SetStruct(ref m_DashLength, value)) SetVerticesDirty(); } + } + + /// + /// the length of dot line. default value is 0, which means the length of dot line is 2 times of line width. + /// Represents a multiple of the number of segments in a line chart. + /// |点线的长度。默认0时为线条宽度的3倍。在折线图中代表分割段数的倍数。 + /// + public float dotLength + { + get { return m_DotLength; } + set { if (PropertyUtil.SetStruct(ref m_DotLength, value)) SetVerticesDirty(); } + } + + /// + /// the length of gap line. default value is 0, which means the length of gap line is 3 times of line width. + /// Represents a multiple of the number of segments in a line chart. + /// |点线的长度。默认0时为线条宽度的3倍。在折线图中代表分割段数的倍数。 + /// + public float gapLength + { + get { return m_GapLength; } + set { if (PropertyUtil.SetStruct(ref m_GapLength, value)) SetVerticesDirty(); } + } + public LineStyle() { } @@ -150,6 +186,9 @@ namespace XCharts.Runtime lineStyle.toColor2 = toColor2; lineStyle.width = width; lineStyle.opacity = opacity; + lineStyle.dashLength = dashLength; + lineStyle.dotLength = dotLength; + lineStyle.gapLength = gapLength; return lineStyle; } @@ -162,6 +201,14 @@ namespace XCharts.Runtime toColor2 = lineStyle.toColor2; width = lineStyle.width; opacity = lineStyle.opacity; + dashLength = lineStyle.dashLength; + dotLength = lineStyle.dotLength; + gapLength = lineStyle.gapLength; + } + + public bool IsNotSolidLine() + { + return type != Type.Solid && type != Type.None; } public Color32 GetColor() @@ -170,7 +217,7 @@ namespace XCharts.Runtime return m_Color; var color = m_Color; - color.a = (byte) (color.a * m_Opacity); + color.a = (byte)(color.a * m_Opacity); return color; } @@ -201,7 +248,7 @@ namespace XCharts.Runtime } if (m_Opacity != 1) { - color.a = (byte) (color.a * m_Opacity); + color.a = (byte)(color.a * m_Opacity); } return color; } @@ -230,7 +277,7 @@ namespace XCharts.Runtime else { var color = themeColor; - color.a = (byte) (color.a * opacity); + color.a = (byte)(color.a * opacity); return color; } } diff --git a/Runtime/Serie/Line/LineHelper.cs b/Runtime/Serie/Line/LineHelper.cs index d188a0d8..d53eb7a2 100644 --- a/Runtime/Serie/Line/LineHelper.cs +++ b/Runtime/Serie/Line/LineHelper.cs @@ -285,8 +285,11 @@ namespace XCharts.Runtime var lineColor = SerieHelper.GetLineColor(serie, null, theme, serie.context.colorIndex); var lastDataIsIgnore = datas[0].isIgnoreBreak; - var smooth = serie.lineType == LineType.Smooth; var firstInGridPointIndex = serie.clip ? -1 : 1; + var segmentCount = 0; + var dashLength = serie.lineStyle.dashLength; + var gapLength = serie.lineStyle.gapLength; + var dotLength = serie.lineStyle.dotLength; for (int i = 1; i < dataCount; i++) { var cdata = datas[i]; @@ -315,31 +318,45 @@ namespace XCharts.Runtime firstInGridPointIndex = i; if (isClip) isIgnore = true; } - if (!smooth) + if (serie.lineStyle.type == LineStyle.Type.None) { + handled = true; + break; + } + { + segmentCount++; + var index = 0f; switch (serie.lineStyle.type) { case LineStyle.Type.Dashed: - UGL.DrawDashLine(vh, lp, cp, lineWidth, lineColor, lineColor, 0, 0); - handled = true; + index = segmentCount % (dashLength + gapLength); + if (index >= dashLength) + isIgnore = true; break; case LineStyle.Type.Dotted: - UGL.DrawDotLine(vh, lp, cp, lineWidth, lineColor, lineColor, 0, 0); - handled = true; + index = segmentCount % (dotLength + gapLength); + if (index >= dotLength) + isIgnore = true; break; case LineStyle.Type.DashDot: - UGL.DrawDashDotLine(vh, lp, cp, lineWidth, lineColor, 0, 0, 0); - handled = true; + index = segmentCount % (dashLength + dotLength + 2 * gapLength); + if (index >= dashLength && index < dashLength + gapLength) + isIgnore = true; + else if (index >= dashLength + gapLength + dotLength) + isIgnore = true; break; case LineStyle.Type.DashDotDot: - UGL.DrawDashDotDotLine(vh, lp, cp, lineWidth, lineColor, 0, 0, 0); - handled = true; - break; - case LineStyle.Type.None: - handled = true; + index = segmentCount % (dashLength + 2 * dotLength + 3 * gapLength); + if (index >= dashLength && index < dashLength + gapLength) + isIgnore = true; + else if (index >= dashLength + gapLength + dotLength && index < dashLength + dotLength + 2 * gapLength) + isIgnore = true; + else if (index >= dashLength + 2 * gapLength + 2 * dotLength) + isIgnore = true; break; } } + if (handled) { lastDataIsIgnore = isIgnore; @@ -476,7 +493,7 @@ namespace XCharts.Runtime private static void UpdateNormalLineDrawPoints(Serie serie, Settings setting, VisualMap visualMap) { var isVisualMapGradient = VisualMapHelper.IsNeedGradient(visualMap); - if (isVisualMapGradient || serie.clip) + if (isVisualMapGradient || serie.clip || (serie.lineStyle.IsNotSolidLine())) { var dataPoints = serie.context.dataPoints; if (dataPoints.Count > 1)