From 0d361555f393e8f56da172bfbd305f61c5bc8f85 Mon Sep 17 00:00:00 2001 From: monitor1394 Date: Sun, 22 Mar 2020 22:50:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0`BarChart`=E9=80=9A=E8=BF=87`?= =?UTF-8?q?barType`=E5=8F=82=E6=95=B0=E8=AE=BE=E7=BD=AE`=E8=83=B6=E5=9B=8A?= =?UTF-8?q?=E6=9F=B1=E7=8A=B6=E5=9B=BE`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/XCharts/CHANGELOG.md | 1 + .../Documentation/XCharts配置项手册.md | 6 +- .../Internal/CoordinateChart_DrawBar.cs | 279 +++++++++++++----- 3 files changed, 213 insertions(+), 73 deletions(-) diff --git a/Assets/XCharts/CHANGELOG.md b/Assets/XCharts/CHANGELOG.md index 8b460da3..3ae7482e 100644 --- a/Assets/XCharts/CHANGELOG.md +++ b/Assets/XCharts/CHANGELOG.md @@ -1,6 +1,7 @@ # 更新日志 +* (2020.03.22) 增加`BarChart`通过`barType`参数设置`胶囊柱状图` * (2020.03.21) 增加`BarChart`和`HeatmapChart`可通过`ignore`参数设置忽略数据的支持 * (2020.03.21) 增加`ItemStyle`的`tooltipFormatter`参数可单独配置`Serie`的`Tooltip`显示 * (2020.03.20) 修复`X Axis 1`和`Y Axis 1`配置变更时不会自动刷新的问题 diff --git a/Assets/XCharts/Documentation/XCharts配置项手册.md b/Assets/XCharts/Documentation/XCharts配置项手册.md index caa9c4c4..0a8ae548 100644 --- a/Assets/XCharts/Documentation/XCharts配置项手册.md +++ b/Assets/XCharts/Documentation/XCharts配置项手册.md @@ -467,7 +467,7 @@ * `sampleAverage`:设定的采样平均值。当 `sampleType` 为 `Peak` 时,用于和过滤数据的平均值做对比是取最大值还是最小值。默认为`0`时会实时计算所有数据的平均值。 * `clip`:是否裁剪超出坐标系部分的图形。 * `ignore`:是否开启忽略数据。当为 `true` 时,数据值为 `ignoreValue` 时不进行绘制。 -* `ignoreValue`:忽略数据的默认值。当 `ignore` 为 `true` 才有效。 +* `ignoreValue`:忽略数据的默认值。默认值默认为0,当 `ignore` 为 `true` 才有效。 * `areaStyle`:区域填充样式 [AreaStyle](#AreaStyle)。 * `symbol`:标记的图形 [SerieSymbol](#SerieSymbol)。 * `lineType`:折线图样式类型。支持以下十种类型: @@ -511,6 +511,8 @@ * `barZebraWidth`:斑马线的粗细。`barType` 为 `Zebra` 时有效。 * `barZebraGap`:斑马线的间距。`barType` 为 `Zebra` 时有效。 * `clip`:是否裁剪超出坐标系部分的图形。 +* `ignore`:是否开启忽略数据。当为 `true` 时,数据值为 `ignoreValue` 时不进行绘制。 +* `ignoreValue`:忽略数据的默认值。默认值默认为0,当 `ignore` 为 `true` 才有效。 * `symbol`:标记的图形 [SerieSymbol](#SerieSymbol)。 * `itemStyle`:柱条样式 [ItemStyle](#ItemStyle)。 * `areaStyle`:区域填充样式 [AreaStyle](#AreaStyle)。 @@ -579,6 +581,8 @@ * `show`:系列是否显示在图表上。 * `type`:`Scatter`。 * `name`:系列名称。用于 `tooltip` 的显示,`legend` 的图例筛选。 +* `ignore`:是否开启忽略数据。当为 `true` 时,数据值为 `ignoreValue` 时不进行绘制。 +* `ignoreValue`:忽略数据的默认值。默认值默认为0,当 `ignore` 为 `true` 才有效。 * `label`:图形上的文本标签 [SerieLabel](#SerieLabel),可用于说明图形的一些数据信息,比如值,名称等。 * `emphasis`:高亮样式 [Emphasis](#Emphasis)。 * `animation`:起始动画 [SerieAnimation](#SerieAnimation)。 diff --git a/Assets/XCharts/Runtime/Internal/CoordinateChart_DrawBar.cs b/Assets/XCharts/Runtime/Internal/CoordinateChart_DrawBar.cs index 6e001358..e5b31f2d 100644 --- a/Assets/XCharts/Runtime/Internal/CoordinateChart_DrawBar.cs +++ b/Assets/XCharts/Runtime/Internal/CoordinateChart_DrawBar.cs @@ -92,40 +92,33 @@ namespace XCharts float currHig = CheckAnimation(serie, i, barHig); - Vector3 p1 = new Vector3(pX + borderWidth, pY + space + barWidth - borderWidth); - Vector3 p2 = new Vector3(pX + currHig - 2 * borderWidth, pY + space + barWidth - borderWidth); - Vector3 p3 = new Vector3(pX + currHig - 2 * borderWidth, pY + space + borderWidth); - Vector3 p4 = new Vector3(pX + borderWidth, pY + space + borderWidth); + Vector3 plt = new Vector3(pX + borderWidth, pY + space + barWidth - borderWidth); + Vector3 prt = new Vector3(pX + currHig - borderWidth, pY + space + barWidth - borderWidth); + Vector3 prb = new Vector3(pX + currHig - borderWidth, pY + space + borderWidth); + Vector3 plb = new Vector3(pX + borderWidth, pY + space + borderWidth); Vector3 top = new Vector3(pX + currHig - borderWidth, pY + space + barWidth / 2); - p1 = ClampInCoordinate(p1); - p2 = ClampInCoordinate(p2); - p3 = ClampInCoordinate(p3); - p4 = ClampInCoordinate(p4); + plt = ClampInCoordinate(plt); + prt = ClampInCoordinate(prt); + prb = ClampInCoordinate(prb); + plb = ClampInCoordinate(plb); top = ClampInCoordinate(top); serie.dataPoints.Add(top); if (serie.show) { - DrawBarBackground(vh, serie, serieData, colorIndex, highlight, pX, pY, space, barWidth, true); - Color areaColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); - Color areaToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); - if (serie.barType == BarType.Zebra) + switch (serie.barType) { - p1 = (p4 + p1) / 2; - p2 = (p2 + p3) / 2; - CheckClipAndDrawZebraLine(vh, p1, p2, barWidth / 2, serie.barZebraWidth, serie.barZebraGap, - areaColor, serie.clip); - } - else - { - CheckClipAndDrawPolygon(vh, p4, p1, p2, p3, areaColor, areaToColor, serie.clip); - if (borderWidth > 0) - { - var borderColor = itemStyle.borderColor; - var itemWidth = Mathf.Abs(p3.x - p1.x); - var itemHeight = Mathf.Abs(p2.y - p4.y); - var center = new Vector3((p1.x + p3.x) / 2, (p2.y + p4.y) / 2); - ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor); - } + case BarType.Normal: + DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth, + pX, pY, plb, plt, prt, prb, true); + break; + case BarType.Zebra: + DrawZebraBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth, + pX, pY, plb, plt, prt, prb, true); + break; + case BarType.Capsule: + DrawCapsuleBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth, + pX, pY, plb, plt, prt, prb, true); + break; } } } @@ -223,43 +216,34 @@ namespace XCharts / valueTotal * coordinateHeight; seriesHig[i] += barHig; } - float currHig = CheckAnimation(serie, i, barHig); - Vector3 p1 = new Vector3(pX + space + borderWidth, pY + borderWidth); - Vector3 p2 = new Vector3(pX + space + borderWidth, pY + currHig - 2 * borderWidth); - Vector3 p3 = new Vector3(pX + space + barWidth, pY + currHig - 2 * borderWidth); - Vector3 p4 = new Vector3(pX + space + barWidth, pY + borderWidth); + Vector3 plb = new Vector3(pX + space + borderWidth, pY + borderWidth); + Vector3 plt = new Vector3(pX + space + borderWidth, pY + currHig - borderWidth); + Vector3 prt = new Vector3(pX + space + barWidth - borderWidth, pY + currHig - borderWidth); + Vector3 prb = new Vector3(pX + space + barWidth - borderWidth, pY + borderWidth); Vector3 top = new Vector3(pX + space + barWidth / 2, pY + currHig - borderWidth); - p1 = ClampInCoordinate(p1); - p2 = ClampInCoordinate(p2); - p3 = ClampInCoordinate(p3); - p4 = ClampInCoordinate(p4); + plb = ClampInCoordinate(plb); + plt = ClampInCoordinate(plt); + prt = ClampInCoordinate(prt); + prb = ClampInCoordinate(prb); top = ClampInCoordinate(top); serie.dataPoints.Add(top); - if (serie.show) { - Color areaColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); - Color areaToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); - DrawBarBackground(vh, serie, serieData, colorIndex, highlight, pX, pY, space, barWidth, false); - if (serie.barType == BarType.Zebra) + switch (serie.barType) { - p1 = (p4 + p1) / 2; - p2 = (p2 + p3) / 2; - CheckClipAndDrawZebraLine(vh, p1, p2, barWidth / 2, serie.barZebraWidth, serie.barZebraGap, - areaColor, serie.clip); - } - else - { - CheckClipAndDrawPolygon(vh, ref p4, ref p1, ref p2, ref p3, areaColor, areaToColor, serie.clip); - if (borderWidth > 0) - { - var borderColor = itemStyle.borderColor; - var itemWidth = Mathf.Abs(p3.x - p1.x); - var itemHeight = Mathf.Abs(p2.y - p4.y); - var center = new Vector3((p1.x + p3.x) / 2, (p2.y + p4.y) / 2); - ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor); - } + case BarType.Normal: + DrawNormalBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth, + pX, pY, plb, plt, prt, prb, false); + break; + case BarType.Zebra: + DrawZebraBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth, + pX, pY, plb, plt, prt, prb, false); + break; + case BarType.Capsule: + DrawCapsuleBar(vh, serie, serieData, itemStyle, colorIndex, highlight, space, barWidth, + pX, pY, plb, plt, prt, prb, false); + break; } } } @@ -273,27 +257,178 @@ namespace XCharts } } - private void DrawBarBackground(VertexHelper vh, Serie serie, SerieData serieData, int colorIndex, bool highlight, - float pX, float pY, float space, float barWidth, bool isYAxis) + private void DrawNormalBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, + bool highlight, float space, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt, + Vector3 prb, bool isYAxis) + { + Color areaColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); + Color areaToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); + DrawBarBackground(vh, serie, serieData, itemStyle, colorIndex, highlight, pX, pY, space, barWidth, isYAxis); + var borderWidth = itemStyle.runtimeBorderWidth; + if (isYAxis) + { + CheckClipAndDrawPolygon(vh, plb, plt, prt, prb, areaColor, areaToColor, serie.clip); + if (borderWidth > 0) + { + var borderColor = itemStyle.borderColor; + var itemWidth = Mathf.Abs(prb.x - plt.x); + var itemHeight = Mathf.Abs(prt.y - plb.y); + var center = new Vector3((plt.x + prb.x) / 2, (prt.y + plb.y) / 2); + ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor); + } + } + else + { + CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, areaColor, areaToColor, serie.clip); + if (borderWidth > 0) + { + var borderColor = itemStyle.borderColor; + var itemWidth = Mathf.Abs(prt.x - plb.x); + var itemHeight = Mathf.Abs(plt.y - prb.y); + var center = new Vector3((plb.x + prt.x) / 2, (plt.y + prb.y) / 2); + ChartDrawer.DrawBorder(vh, center, itemWidth, itemHeight, borderWidth, borderColor); + } + } + } + + private void DrawZebraBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, + bool highlight, float space, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt, + Vector3 prb, bool isYAxis) + { + Color areaColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); + DrawBarBackground(vh, serie, serieData, itemStyle, colorIndex, highlight, pX, pY, space, barWidth, isYAxis); + if (isYAxis) + { + plt = (plb + plt) / 2; + prt = (prt + prb) / 2; + CheckClipAndDrawZebraLine(vh, plt, prt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap, + areaColor, serie.clip); + } + else + { + plb = (prb + plb) / 2; + plt = (plt + prt) / 2; + CheckClipAndDrawZebraLine(vh, plb, plt, barWidth / 2, serie.barZebraWidth, serie.barZebraGap, + areaColor, serie.clip); + } + } + + private void DrawCapsuleBar(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, + bool highlight, float space, float barWidth, float pX, float pY, Vector3 plb, Vector3 plt, Vector3 prt, + Vector3 prb, bool isYAxis) + { + Color areaColor = SerieHelper.GetItemColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); + Color areaToColor = SerieHelper.GetItemToColor(serie, serieData, m_ThemeInfo, colorIndex, highlight); + DrawBarBackground(vh, serie, serieData, itemStyle, colorIndex, highlight, pX, pY, space, barWidth, isYAxis); + var borderWidth = itemStyle.runtimeBorderWidth; + var radius = barWidth / 2 - borderWidth; + if (isYAxis) + { + var diff = Vector3.right * radius; + var pcl = (plt + plb) / 2 + diff; + var pcr = (prt + prb) / 2 - diff; + if (pcr.x > pcl.x) + { + CheckClipAndDrawPolygon(vh, plb + diff, plt + diff, prt - diff, prb - diff, areaColor, areaToColor, serie.clip); + ChartDrawer.DrawSector(vh, pcl, radius, areaColor, 180, 360); + ChartDrawer.DrawSector(vh, pcr, radius, areaToColor, 0, 180); + } + } + else + { + var diff = Vector3.up * radius; + var pct = (plt + prt) / 2 - diff; + var pcb = (plb + prb) / 2 + diff; + if (pct.y > pcb.y) + { + CheckClipAndDrawPolygon(vh, prb + diff, plb + diff, plt - diff, prt - diff, areaColor, areaToColor, serie.clip); + ChartDrawer.DrawSector(vh, pct, radius, areaToColor, 270, 450); + ChartDrawer.DrawSector(vh, pcb, radius, areaColor, 90, 270); + } + } + } + + private void DrawBarBackground(VertexHelper vh, Serie serie, SerieData serieData, ItemStyle itemStyle, int colorIndex, + bool highlight, float pX, float pY, float space, float barWidth, bool isYAxis) { Color color = SerieHelper.GetItemBackgroundColor(serie, serieData, m_ThemeInfo, colorIndex, highlight, false); - if (color != Color.clear) + if (color == Color.clear) return; + if (isYAxis) { - if (isYAxis) + var axis = m_YAxises[serie.axisIndex]; + var axisWidth = axis.axisLine.width; + Vector3 plt = new Vector3(coordinateX + axisWidth, pY + space + barWidth); + Vector3 prt = new Vector3(coordinateX + axisWidth + coordinateWidth, pY + space + barWidth); + Vector3 prb = new Vector3(coordinateX + axisWidth + coordinateWidth, pY + space); + Vector3 plb = new Vector3(coordinateX + axisWidth, pY + space); + if (serie.barType == BarType.Capsule) { - Vector3 p1 = new Vector3(coordinateX, pY + space + barWidth); - Vector3 p2 = new Vector3(coordinateX + coordinateWidth, pY + space + barWidth); - Vector3 p3 = new Vector3(coordinateX + coordinateWidth, pY + space); - Vector3 p4 = new Vector3(coordinateX, pY + space); - CheckClipAndDrawPolygon(vh, ref p4, ref p1, ref p2, ref p3, color, color, serie.clip); + var radius = barWidth / 2; + var diff = Vector3.right * radius; + var pcl = (plt + plb) / 2 + diff; + var pcr = (prt + prb) / 2 - diff; + CheckClipAndDrawPolygon(vh, plb + diff, plt + diff, prt - diff, prb - diff, color, color, serie.clip); + ChartDrawer.DrawSector(vh, pcl, radius, color, 180, 360); + ChartDrawer.DrawSector(vh, pcr, radius, color, 0, 180); + if (itemStyle.NeedShowBorder()) + { + var borderWidth = itemStyle.borderWidth; + var borderColor = itemStyle.borderColor; + var smoothness = m_Settings.cicleSmoothness; + var inRadius = radius - borderWidth; + var outRadius = radius; + var p1 = plb + diff + Vector3.up * borderWidth / 2; + var p2 = prb - diff + Vector3.up * borderWidth / 2; + var p3 = plt + diff - Vector3.up * borderWidth / 2; + var p4 = prt - diff - Vector3.up * borderWidth / 2; + ChartDrawer.DrawLine(vh, p1, p2, borderWidth / 2, borderColor); + ChartDrawer.DrawLine(vh, p3, p4, borderWidth / 2, borderColor); + ChartDrawer.DrawDoughnut(vh, pcl, inRadius, outRadius, borderColor, Color.clear, smoothness, 180, 360); + ChartDrawer.DrawDoughnut(vh, pcr, inRadius, outRadius, borderColor, Color.clear, smoothness, 0, 180); + } } else { - Vector3 p1 = new Vector3(pX + space, coordinateY); - Vector3 p2 = new Vector3(pX + space, coordinateY + coordinateHeight); - Vector3 p3 = new Vector3(pX + space + barWidth, coordinateY + coordinateHeight); - Vector3 p4 = new Vector3(pX + space + barWidth, coordinateY); - CheckClipAndDrawPolygon(vh, ref p4, ref p1, ref p2, ref p3, color, color, serie.clip); + CheckClipAndDrawPolygon(vh, ref plb, ref plt, ref prt, ref prb, color, color, serie.clip); + } + } + else + { + var axis = m_XAxises[serie.axisIndex]; + var axisWidth = axis.axisLine.width; + Vector3 plb = new Vector3(pX + space, coordinateY + axisWidth); + Vector3 plt = new Vector3(pX + space, coordinateY + coordinateHeight + axisWidth); + Vector3 prt = new Vector3(pX + space + barWidth, coordinateY + coordinateHeight + axisWidth); + Vector3 prb = new Vector3(pX + space + barWidth, coordinateY + axisWidth); + if (serie.barType == BarType.Capsule) + { + var radius = barWidth / 2; + var diff = Vector3.up * radius; + var pct = (plt + prt) / 2 - diff; + var pcb = (plb + prb) / 2 + diff; + CheckClipAndDrawPolygon(vh, prb + diff, plb + diff, plt - diff, prt - diff, color, color, serie.clip); + ChartDrawer.DrawSector(vh, pct, radius, color, 270, 450); + ChartDrawer.DrawSector(vh, pcb, radius, color, 90, 270); + if (itemStyle.NeedShowBorder()) + { + var borderWidth = itemStyle.borderWidth; + var borderColor = itemStyle.borderColor; + var smoothness = m_Settings.cicleSmoothness; + var inRadius = radius - borderWidth; + var outRadius = radius; + var p1 = plb + diff + Vector3.right * borderWidth / 2; + var p2 = plt - diff + Vector3.right * borderWidth / 2; + var p3 = prb + diff - Vector3.right * borderWidth / 2; + var p4 = prt - diff - Vector3.right * borderWidth / 2; + ChartDrawer.DrawLine(vh, p1, p2, borderWidth / 2, borderColor); + ChartDrawer.DrawLine(vh, p3, p4, borderWidth / 2, borderColor); + ChartDrawer.DrawDoughnut(vh, pct, inRadius, outRadius, borderColor, Color.clear, smoothness, 270, 450); + ChartDrawer.DrawDoughnut(vh, pcb, inRadius, outRadius, borderColor, Color.clear, smoothness, 90, 270); + } + } + else + { + CheckClipAndDrawPolygon(vh, ref prb, ref plb, ref plt, ref prt, color, color, serie.clip); } } }