diff --git a/Assets/XCharts/CHANGELOG-EN.md b/Assets/XCharts/CHANGELOG-EN.md index 5c9018ea..73870a3b 100644 --- a/Assets/XCharts/CHANGELOG-EN.md +++ b/Assets/XCharts/CHANGELOG-EN.md @@ -1,6 +1,8 @@ # 更新日志 +* (2020.08.29) Added the `onPointerClickPie` of `PieChart`, a callback function of click pie area. +* (2020.08.29) Added the `onPointerClickBar` of `BarChart`, a callback function of click bar. * (2020.08.24) Release `V1.6.0` version * (2020.08.23) Refactor code, replace `Color` with `Color32` for reduce implicit conversion (Can cause custom colors to lose, reference [Q&A 29](https://github.com/monitor1394/unity-ugui-XCharts/blob/master/Assets/XCharts/Documentation/xcharts-questions-and-answers-EN.md) to upgrade) * (2020.08.15) Optimize `PieChart` drawing performance effect #85 diff --git a/Assets/XCharts/CHANGELOG.md b/Assets/XCharts/CHANGELOG.md index 5655b27a..6cf3f3b7 100644 --- a/Assets/XCharts/CHANGELOG.md +++ b/Assets/XCharts/CHANGELOG.md @@ -1,6 +1,8 @@ # 更新日志 +* (2020.08.29) 增加`PieChart`的`onPointerClickPie`点击扇形图扇区回调 +* (2020.08.29) 增加`BarChart`的`onPointerClickBar`点击柱形图柱条回调 * (2020.08.24) 发布`v1.6.0`版本 * (2020.08.23) 重构代码,将与绘制相关的`Color`改为`Color32`,减少隐式转换(更新后会导致自定义的颜色丢失,可参考[问答29](https://github.com/monitor1394/unity-ugui-XCharts/blob/master/Assets/XCharts/Documentation/XCharts问答.md)进行升级) * (2020.08.15) 优化`PieChart`绘制表现效果#85 diff --git a/Assets/XCharts/Documentation/XChartsAPI.md b/Assets/XCharts/Documentation/XChartsAPI.md index 135b3576..a0f39b1c 100644 --- a/Assets/XCharts/Documentation/XChartsAPI.md +++ b/Assets/XCharts/Documentation/XChartsAPI.md @@ -103,10 +103,14 @@ * 继承自 `BaseChart`。 * 继承自 `CoordinateChart`。 +* `BarChart.onPointerClickBar`:点击柱条回调。参数:`eventData`, `dataIndex` + ## `PieChart` * 继承自 `BaseChart`。 +* `PieChart.onPointerClickPie`:点击柱条回调。参数:`eventData`, `serieIndex`, `dataIndex` + ## `RadarChart` * 继承自 `BaseChart`。 diff --git a/Assets/XCharts/Documentation/xcharts-api-EN.md b/Assets/XCharts/Documentation/xcharts-api-EN.md index 135b3576..a0f39b1c 100644 --- a/Assets/XCharts/Documentation/xcharts-api-EN.md +++ b/Assets/XCharts/Documentation/xcharts-api-EN.md @@ -103,10 +103,14 @@ * 继承自 `BaseChart`。 * 继承自 `CoordinateChart`。 +* `BarChart.onPointerClickBar`:点击柱条回调。参数:`eventData`, `dataIndex` + ## `PieChart` * 继承自 `BaseChart`。 +* `PieChart.onPointerClickPie`:点击柱条回调。参数:`eventData`, `serieIndex`, `dataIndex` + ## `RadarChart` * 继承自 `BaseChart`。 diff --git a/Assets/XCharts/Examples/Runtime/Example02_ChartEvent.cs b/Assets/XCharts/Examples/Runtime/Example02_ChartEvent.cs index 4be8cdc1..c1e93af6 100644 --- a/Assets/XCharts/Examples/Runtime/Example02_ChartEvent.cs +++ b/Assets/XCharts/Examples/Runtime/Example02_ChartEvent.cs @@ -31,32 +31,32 @@ namespace XCharts.Examples chart.onScroll = OnScroll; } - void OnPointerEnter(BaseGraph chart, PointerEventData eventData) + void OnPointerEnter(PointerEventData eventData, BaseGraph chart) { //Debug.LogError("enter:" + chart); } - void OnPointerExit(BaseGraph chart, PointerEventData eventData) + void OnPointerExit(PointerEventData eventData, BaseGraph chart) { //Debug.LogError("exit:" + chart); } - void OnPointerDown(BaseGraph chart, PointerEventData eventData) + void OnPointerDown(PointerEventData eventData, BaseGraph chart) { //Debug.LogError("down:" + chart); } - void OnPointerUp(BaseGraph chart, PointerEventData eventData) + void OnPointerUp(PointerEventData eventData, BaseGraph chart) { //Debug.LogError("up:" + chart); } - void OnPointerClick(BaseGraph chart, PointerEventData eventData) + void OnPointerClick(PointerEventData eventData, BaseGraph chart) { //Debug.LogError("click:" + chart); } - void OnScroll(BaseGraph chart, PointerEventData eventData) + void OnScroll(PointerEventData eventData, BaseGraph chart) { //Debug.LogError("scroll:" + chart); } diff --git a/Assets/XCharts/Runtime/API/BarChart_API.cs b/Assets/XCharts/Runtime/API/BarChart_API.cs new file mode 100644 index 00000000..6ba5b351 --- /dev/null +++ b/Assets/XCharts/Runtime/API/BarChart_API.cs @@ -0,0 +1,22 @@ +/******************************************/ +/* */ +/* Copyright (c) 2018 monitor1394 */ +/* https://github.com/monitor1394 */ +/* */ +/******************************************/ + +using UnityEngine; +using System; +using UnityEngine.EventSystems; + +namespace XCharts +{ + public partial class BarChart + { + /// + /// the callback function of click bar. + /// 点击柱形图柱条回调。参数:eventData, dataIndex + /// + public Action onPointerClickBar { set { m_OnPointerClickBar = value; m_ForceOpenRaycastTarget = true; } } + } +} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/API/BarChart_API.cs.meta b/Assets/XCharts/Runtime/API/BarChart_API.cs.meta new file mode 100644 index 00000000..7238897f --- /dev/null +++ b/Assets/XCharts/Runtime/API/BarChart_API.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 73ae9e0b481fc4587828be9149026b0f +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XCharts/Runtime/API/BaseGraph_API.cs b/Assets/XCharts/Runtime/API/BaseGraph_API.cs index 22e4015f..39178d0b 100644 --- a/Assets/XCharts/Runtime/API/BaseGraph_API.cs +++ b/Assets/XCharts/Runtime/API/BaseGraph_API.cs @@ -65,39 +65,39 @@ namespace XCharts /// /// 鼠标点击回调。 /// - public Action onPointerClick { set { m_OnPointerClick = value; m_ForceOpenRaycastTarget = true; } } + public Action onPointerClick { set { m_OnPointerClick = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标按下回调。 /// - public Action onPointerDown { set { m_OnPointerDown = value; m_ForceOpenRaycastTarget = true; } } + public Action onPointerDown { set { m_OnPointerDown = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标弹起回调。 /// - public Action onPointerUp { set { m_OnPointerUp = value; m_ForceOpenRaycastTarget = true; } } + public Action onPointerUp { set { m_OnPointerUp = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标进入回调。 /// - public Action onPointerEnter { set { m_OnPointerEnter = value; m_ForceOpenRaycastTarget = true; } } + public Action onPointerEnter { set { m_OnPointerEnter = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标退出回调。 /// - public Action onPointerExit { set { m_OnPointerExit = value; m_ForceOpenRaycastTarget = true; } } + public Action onPointerExit { set { m_OnPointerExit = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标开始拖拽回调。 /// - public Action onBeginDrag { set { m_OnBeginDrag = value; m_ForceOpenRaycastTarget = true; } } + public Action onBeginDrag { set { m_OnBeginDrag = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标拖拽回调。 /// - public Action onDrag { set { m_OnDrag = value; m_ForceOpenRaycastTarget = true; } } + public Action onDrag { set { m_OnDrag = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标结束拖拽回调。 /// - public Action onEndDrag { set { m_OnEndDrag = value; m_ForceOpenRaycastTarget = true; } } + public Action onEndDrag { set { m_OnEndDrag = value; m_ForceOpenRaycastTarget = true; } } /// /// 鼠标滚动回调。 /// - public Action onScroll { set { m_OnScroll = value; m_ForceOpenRaycastTarget = true; } } + public Action onScroll { set { m_OnScroll = value; m_ForceOpenRaycastTarget = true; } } /// /// 设置图形的宽高(在非stretch pivot下才有效,其他情况需要自己调整RectTransform) diff --git a/Assets/XCharts/Runtime/API/PieChart_API.cs b/Assets/XCharts/Runtime/API/PieChart_API.cs new file mode 100644 index 00000000..a4ecfc7b --- /dev/null +++ b/Assets/XCharts/Runtime/API/PieChart_API.cs @@ -0,0 +1,22 @@ +/******************************************/ +/* */ +/* Copyright (c) 2018 monitor1394 */ +/* https://github.com/monitor1394 */ +/* */ +/******************************************/ + +using UnityEngine; +using System; +using UnityEngine.EventSystems; + +namespace XCharts +{ + public partial class PieChart + { + /// + /// the callback function of click pie area. + /// 点击饼图区域回调。参数:PointerEventData,SerieIndex,SerieDataIndex + /// + public Action onPointerClickPie { set { m_OnPointerClickPie = value; m_ForceOpenRaycastTarget = true; } } + } +} \ No newline at end of file diff --git a/Assets/XCharts/Runtime/API/PieChart_API.cs.meta b/Assets/XCharts/Runtime/API/PieChart_API.cs.meta new file mode 100644 index 00000000..4507e9ad --- /dev/null +++ b/Assets/XCharts/Runtime/API/PieChart_API.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 85c7f8858dca444f88830d61b9af3700 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/XCharts/Runtime/BarChart.cs b/Assets/XCharts/Runtime/BarChart.cs index 389d7c1a..789c9d3f 100644 --- a/Assets/XCharts/Runtime/BarChart.cs +++ b/Assets/XCharts/Runtime/BarChart.cs @@ -5,7 +5,9 @@ /* */ /******************************************/ +using System; using UnityEngine; +using UnityEngine.EventSystems; namespace XCharts { @@ -13,9 +15,15 @@ namespace XCharts [ExecuteInEditMode] [RequireComponent(typeof(RectTransform))] [DisallowMultipleComponent] - public class BarChart : CoordinateChart + public partial class BarChart : CoordinateChart { + protected Action m_OnPointerClickBar; + protected override void Awake() + { + base.Awake(); + raycastTarget = false; + } #if UNITY_EDITOR protected override void Reset() { @@ -27,9 +35,22 @@ namespace XCharts for (int i = 0; i < 5; i++) { AddXAxisData("x" + (i + 1)); - AddData(0, Random.Range(10, 90)); + AddData(0, UnityEngine.Random.Range(10, 90)); } } #endif + + public override void OnPointerDown(PointerEventData eventData) + { + base.OnPointerDown(eventData); + if (m_OnPointerClickBar == null) return; + if (pointerPos == Vector2.zero) return; + UpdateTooltipValue(pointerPos); + var dataIndex = m_Tooltip.runtimeDataIndex[0]; + if (dataIndex >= 0) + { + m_OnPointerClickBar(eventData, dataIndex); + } + } } } diff --git a/Assets/XCharts/Runtime/Internal/BaseGraphic.cs b/Assets/XCharts/Runtime/Internal/BaseGraph.cs similarity index 86% rename from Assets/XCharts/Runtime/Internal/BaseGraphic.cs rename to Assets/XCharts/Runtime/Internal/BaseGraph.cs index d20e7555..a72a15ac 100644 --- a/Assets/XCharts/Runtime/Internal/BaseGraphic.cs +++ b/Assets/XCharts/Runtime/Internal/BaseGraph.cs @@ -33,15 +33,15 @@ namespace XCharts protected bool m_IsControlledByLayout = false; protected Vector3 m_LastLocalPosition; - protected Action m_OnPointerClick; - protected Action m_OnPointerDown; - protected Action m_OnPointerUp; - protected Action m_OnPointerEnter; - protected Action m_OnPointerExit; - protected Action m_OnBeginDrag; - protected Action m_OnDrag; - protected Action m_OnEndDrag; - protected Action m_OnScroll; + protected Action m_OnPointerClick; + protected Action m_OnPointerDown; + protected Action m_OnPointerUp; + protected Action m_OnPointerEnter; + protected Action m_OnPointerExit; + protected Action m_OnBeginDrag; + protected Action m_OnDrag; + protected Action m_OnEndDrag; + protected Action m_OnScroll; protected Vector2 chartAnchorMax { get { return m_GraphMinAnchor; } } protected Vector2 chartAnchorMin { get { return m_GraphMaxAnchor; } } @@ -228,53 +228,53 @@ namespace XCharts public virtual void OnPointerClick(PointerEventData eventData) { - if (m_OnPointerClick != null) m_OnPointerClick(this, eventData); + if (m_OnPointerClick != null) m_OnPointerClick(eventData, this); } public virtual void OnPointerDown(PointerEventData eventData) { - if (m_OnPointerDown != null) m_OnPointerDown(this, eventData); + if (m_OnPointerDown != null) m_OnPointerDown(eventData, this); } public virtual void OnPointerUp(PointerEventData eventData) { - if (m_OnPointerUp != null) m_OnPointerUp(this, eventData); + if (m_OnPointerUp != null) m_OnPointerUp(eventData, this); } public virtual void OnPointerEnter(PointerEventData eventData) { isPointerInChart = true; - if (m_OnPointerEnter != null) m_OnPointerEnter(this, eventData); + if (m_OnPointerEnter != null) m_OnPointerEnter(eventData, this); } public virtual void OnPointerExit(PointerEventData eventData) { isPointerInChart = false; - if (m_OnPointerExit != null) m_OnPointerExit(this, eventData); + if (m_OnPointerExit != null) m_OnPointerExit(eventData, this); } public virtual void OnBeginDrag(PointerEventData eventData) { if (m_ScrollRect != null) m_ScrollRect.OnBeginDrag(eventData); - if (m_OnBeginDrag != null) m_OnBeginDrag(this, eventData); + if (m_OnBeginDrag != null) m_OnBeginDrag(eventData, this); } public virtual void OnEndDrag(PointerEventData eventData) { if (m_ScrollRect != null) m_ScrollRect.OnEndDrag(eventData); - if (m_OnEndDrag != null) m_OnEndDrag(this, eventData); + if (m_OnEndDrag != null) m_OnEndDrag(eventData, this); } public virtual void OnDrag(PointerEventData eventData) { if (m_ScrollRect != null) m_ScrollRect.OnDrag(eventData); - if (m_OnDrag != null) m_OnDrag(this, eventData); + if (m_OnDrag != null) m_OnDrag(eventData, this); } public virtual void OnScroll(PointerEventData eventData) { if (m_ScrollRect != null) m_ScrollRect.OnScroll(eventData); - if (m_OnScroll != null) m_OnScroll(this, eventData); + if (m_OnScroll != null) m_OnScroll(eventData, this); } } } diff --git a/Assets/XCharts/Runtime/Internal/CoordinateChart.cs b/Assets/XCharts/Runtime/Internal/CoordinateChart.cs index ff9a42e5..3987f4f6 100644 --- a/Assets/XCharts/Runtime/Internal/CoordinateChart.cs +++ b/Assets/XCharts/Runtime/Internal/CoordinateChart.cs @@ -250,111 +250,7 @@ namespace XCharts } else { - var isCartesian = IsValue(); - int dataCount = m_Series.list.Count > 0 ? m_Series.list[0].GetDataList(dataZoom).Count : 0; - for (int i = 0; i < m_XAxises.Count; i++) - { - var xAxis = m_XAxises[i]; - var yAxis = m_YAxises[i]; - if (!xAxis.show && !yAxis.show) continue; - if (isCartesian && xAxis.show && yAxis.show) - { - var yRate = (yAxis.runtimeMaxValue - yAxis.runtimeMinValue) / m_CoordinateHeight; - var xRate = (xAxis.runtimeMaxValue - xAxis.runtimeMinValue) / m_CoordinateWidth; - var yValue = yRate * (local.y - m_CoordinateY - yAxis.runtimeZeroYOffset); - if (yAxis.runtimeMinValue > 0) yValue += yAxis.runtimeMinValue; - m_Tooltip.runtimeYValues[i] = yValue; - var xValue = xRate * (local.x - m_CoordinateX - xAxis.runtimeZeroXOffset); - if (xAxis.runtimeMinValue > 0) xValue += xAxis.runtimeMinValue; - m_Tooltip.runtimeXValues[i] = xValue; - - for (int j = 0; j < m_Series.Count; j++) - { - var serie = m_Series.GetSerie(j); - for (int n = 0; n < serie.data.Count; n++) - { - var serieData = serie.data[n]; - var xdata = serieData.GetData(0, xAxis.inverse); - var ydata = serieData.GetData(1, yAxis.inverse); - var symbol = SerieHelper.GetSerieSymbol(serie, serieData); - var symbolSize = symbol.GetSize(serieData == null ? null : serieData.data); - if (Mathf.Abs(xValue - xdata) / xRate < symbolSize - && Mathf.Abs(yValue - ydata) / yRate < symbolSize) - { - m_Tooltip.runtimeDataIndex[i] = n; - serieData.highlighted = true; - } - else - { - serieData.highlighted = false; - } - } - } - } - else if (IsCategory()) - { - - for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++) - { - float splitWid = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); - float pX = m_CoordinateX + j * splitWid; - if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || - (!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) - { - m_Tooltip.runtimeXValues[i] = j; - m_Tooltip.runtimeDataIndex[i] = j; - break; - } - } - for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++) - { - float splitWid = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); - float pY = m_CoordinateY + j * splitWid; - if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || - (!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) - { - m_Tooltip.runtimeYValues[i] = j; - break; - } - } - } - else if (xAxis.IsCategory()) - { - var value = (yAxis.runtimeMaxValue - yAxis.runtimeMinValue) * (local.y - m_CoordinateY - yAxis.runtimeZeroYOffset) / m_CoordinateHeight; - if (yAxis.runtimeMinValue > 0) value += yAxis.runtimeMinValue; - m_Tooltip.runtimeYValues[i] = value; - for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++) - { - float splitWid = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); - float pX = m_CoordinateX + j * splitWid; - if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || - (!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) - { - m_Tooltip.runtimeXValues[i] = j; - m_Tooltip.runtimeDataIndex[i] = j; - break; - } - } - } - else if (yAxis.IsCategory()) - { - var value = (xAxis.runtimeMaxValue - xAxis.runtimeMinValue) * (local.x - m_CoordinateX - xAxis.runtimeZeroXOffset) / m_CoordinateWidth; - if (xAxis.runtimeMinValue > 0) value += xAxis.runtimeMinValue; - m_Tooltip.runtimeXValues[i] = value; - for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++) - { - float splitWid = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); - float pY = m_CoordinateY + j * splitWid; - if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || - (!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) - { - m_Tooltip.runtimeYValues[i] = j; - m_Tooltip.runtimeDataIndex[i] = j; - break; - } - } - } - } + UpdateTooltipValue(local); } if (m_Tooltip.IsSelected()) { @@ -373,6 +269,115 @@ namespace XCharts } } + protected void UpdateTooltipValue(Vector2 local) + { + var isCartesian = IsValue(); + int dataCount = m_Series.list.Count > 0 ? m_Series.list[0].GetDataList(dataZoom).Count : 0; + for (int i = 0; i < m_XAxises.Count; i++) + { + var xAxis = m_XAxises[i]; + var yAxis = m_YAxises[i]; + if (!xAxis.show && !yAxis.show) continue; + if (isCartesian && xAxis.show && yAxis.show) + { + var yRate = (yAxis.runtimeMaxValue - yAxis.runtimeMinValue) / m_CoordinateHeight; + var xRate = (xAxis.runtimeMaxValue - xAxis.runtimeMinValue) / m_CoordinateWidth; + var yValue = yRate * (local.y - m_CoordinateY - yAxis.runtimeZeroYOffset); + if (yAxis.runtimeMinValue > 0) yValue += yAxis.runtimeMinValue; + m_Tooltip.runtimeYValues[i] = yValue; + var xValue = xRate * (local.x - m_CoordinateX - xAxis.runtimeZeroXOffset); + if (xAxis.runtimeMinValue > 0) xValue += xAxis.runtimeMinValue; + m_Tooltip.runtimeXValues[i] = xValue; + + for (int j = 0; j < m_Series.Count; j++) + { + var serie = m_Series.GetSerie(j); + for (int n = 0; n < serie.data.Count; n++) + { + var serieData = serie.data[n]; + var xdata = serieData.GetData(0, xAxis.inverse); + var ydata = serieData.GetData(1, yAxis.inverse); + var symbol = SerieHelper.GetSerieSymbol(serie, serieData); + var symbolSize = symbol.GetSize(serieData == null ? null : serieData.data); + if (Mathf.Abs(xValue - xdata) / xRate < symbolSize + && Mathf.Abs(yValue - ydata) / yRate < symbolSize) + { + m_Tooltip.runtimeDataIndex[i] = n; + serieData.highlighted = true; + } + else + { + serieData.highlighted = false; + } + } + } + } + else if (IsCategory()) + { + + for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++) + { + float splitWid = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); + float pX = m_CoordinateX + j * splitWid; + if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || + (!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) + { + m_Tooltip.runtimeXValues[i] = j; + m_Tooltip.runtimeDataIndex[i] = j; + break; + } + } + for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++) + { + float splitWid = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); + float pY = m_CoordinateY + j * splitWid; + if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || + (!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) + { + m_Tooltip.runtimeYValues[i] = j; + break; + } + } + } + else if (xAxis.IsCategory()) + { + var value = (yAxis.runtimeMaxValue - yAxis.runtimeMinValue) * (local.y - m_CoordinateY - yAxis.runtimeZeroYOffset) / m_CoordinateHeight; + if (yAxis.runtimeMinValue > 0) value += yAxis.runtimeMinValue; + m_Tooltip.runtimeYValues[i] = value; + for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++) + { + float splitWid = AxisHelper.GetDataWidth(xAxis, m_CoordinateWidth, dataCount, m_DataZoom); + float pX = m_CoordinateX + j * splitWid; + if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) || + (!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2))) + { + m_Tooltip.runtimeXValues[i] = j; + m_Tooltip.runtimeDataIndex[i] = j; + break; + } + } + } + else if (yAxis.IsCategory()) + { + var value = (xAxis.runtimeMaxValue - xAxis.runtimeMinValue) * (local.x - m_CoordinateX - xAxis.runtimeZeroXOffset) / m_CoordinateWidth; + if (xAxis.runtimeMinValue > 0) value += xAxis.runtimeMinValue; + m_Tooltip.runtimeXValues[i] = value; + for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++) + { + float splitWid = AxisHelper.GetDataWidth(yAxis, m_CoordinateHeight, dataCount, m_DataZoom); + float pY = m_CoordinateY + j * splitWid; + if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) || + (!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2))) + { + m_Tooltip.runtimeYValues[i] = j; + m_Tooltip.runtimeDataIndex[i] = j; + break; + } + } + } + } + } + protected StringBuilder sb = new StringBuilder(100); protected override void UpdateTooltip() { diff --git a/Assets/XCharts/Runtime/PieChart.cs b/Assets/XCharts/Runtime/PieChart.cs index 49de3e89..043ccb4f 100644 --- a/Assets/XCharts/Runtime/PieChart.cs +++ b/Assets/XCharts/Runtime/PieChart.cs @@ -5,6 +5,7 @@ /* */ /******************************************/ +using System; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; @@ -15,11 +16,13 @@ namespace XCharts [ExecuteInEditMode] [RequireComponent(typeof(RectTransform))] [DisallowMultipleComponent] - public class PieChart : BaseChart + public partial class PieChart : BaseChart { private bool isDrawPie; private bool m_IsEnterLegendButtom; + protected Action m_OnPointerClickPie; + protected override void Awake() { base.Awake(); @@ -529,28 +532,28 @@ namespace XCharts public override void OnPointerDown(PointerEventData eventData) { base.OnPointerDown(eventData); - - Vector2 local; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - eventData.position, canvas.worldCamera, out local)) - { - return; - } + if (pointerPos == Vector2.zero) return; + var refresh = false; for (int i = 0; i < m_Series.Count; i++) { var serie = m_Series.GetSerie(i); if (serie.type != SerieType.Pie) continue; - var index = GetPosPieIndex(serie, local); + var index = GetPosPieIndex(serie, pointerPos); if (index >= 0) { + refresh = true; for (int j = 0; j < serie.data.Count; j++) { if (j == index) serie.data[j].selected = !serie.data[j].selected; else serie.data[j].selected = false; } + if (m_OnPointerClickPie != null) + { + m_OnPointerClickPie(eventData, i, index); + } } } - RefreshChart(); + if (refresh) RefreshChart(); } } } diff --git a/Doc/教程:5分钟上手XCharts.md b/Doc/教程:5分钟上手XCharts.md index d7a01544..32530273 100644 --- a/Doc/教程:5分钟上手XCharts.md +++ b/Doc/教程:5分钟上手XCharts.md @@ -9,9 +9,9 @@ 你可以通过以下几种方式获取 `XCharts`。 -如果你只是想运行 `Demo` 查看效果,可以在 [Github](https://github.com/monitor1394/unity-ugui-XCharts)上的 [Clone or download](https://github.com/monitor1394/unity-ugui-XCharts/archive/master.zip)下载整个项目或去 [release](https://github.com/monitor1394/unity-ugui-XCharts/releases)下载稳定版本,将源码工程解压后用`unity`打开即可。 +如果你只是想运行 `Demo` 查看效果,可以在 [Github](https://github.com/monitor1394/unity-ugui-XCharts)上的 [Code](https://github.com/monitor1394/unity-ugui-XCharts)下载整个项目或去 [release](https://github.com/monitor1394/unity-ugui-XCharts/releases)下载稳定版本,将源码工程解压后用`unity`打开即可。如果访问Github不稳定的话,可以从[国内镜像](https://gitee.com/monitor1394/unity-ugui-XCharts)下载。 -如果你要将 `XCharts` 加入你的项目中,可以在[Github](https://github.com/monitor1394/unity-ugui-XCharts)上下载最新的 [release](https://github.com/monitor1394/unity-ugui-XCharts/releases)稳定版本,这里一般会包含`XCharts`和`XChartsDemo`两个`unitypackage`,将 `XCharts` 通过 Unity 导入到你的项目中,`XChartsDemo` 是示例Demo,可视情况导入。或下载 Source code 解压后将内部的 `XCharts` 文件夹拷贝到你项目的 `Assets` 目录下。 +如果你要将 `XCharts` 加入你的项目中,可以在[Github](https://github.com/monitor1394/unity-ugui-XCharts)上下载最新的 [release](https://github.com/monitor1394/unity-ugui-XCharts/releases)稳定版本,这里一般会包含`XCharts`和`XChartsDemo`两个`unitypackage`,将 `XCharts` 通过 `Unity` 导入到你的项目中,`XChartsDemo` 是示例`Demo`,可视情况导入。或下载 `Source Code` 解压后将内部的 `XCharts` 文件夹拷贝到你项目的 `Assets` 目录下。 如果你是`Unity 2018.3`及以上版本,可通过Package Manager来安装XCharts包,通过此方式导入的包只包含`XCharts`核心部分,不包含`XChartsDemo`示例`Demo`部分。具体操作步骤如下: diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 6d7e6977..b61c7932 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -7,7 +7,6 @@ PlayerSettings: productGUID: 8d45a4151f4b362428c99c10f0901f14 AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 - AndroidEnableSustainedPerformanceMode: 0 defaultScreenOrientation: 4 targetDevice: 2 useOnDemandResources: 0 @@ -52,6 +51,7 @@ PlayerSettings: m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 + tizenShowActivityIndicatorOnLoading: -1 iosAppInBackgroundBehavior: 0 displayResolutionDialog: 1 iosAllowHTTPDownload: 1 @@ -63,9 +63,8 @@ PlayerSettings: use32BitDisplayBuffer: 1 preserveFramebufferAlpha: 0 disableDepthAndStencilBuffers: 0 - androidStartInFullscreen: 1 - androidRenderOutsideSafeArea: 0 androidBlitType: 0 + defaultIsFullScreen: 1 defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 0 @@ -92,12 +91,16 @@ PlayerSettings: visibleInBackground: 1 allowFullscreenSwitch: 1 graphicsJobMode: 0 - fullscreenMode: 1 + macFullscreenMode: 2 + d3d11FullscreenMode: 1 xboxSpeechDB: 0 xboxEnableHeadOrientation: 0 xboxEnableGuest: 0 xboxEnablePIXSampling: 0 metalFramebufferOnly: 0 + n3dsDisableStereoscopicView: 0 + n3dsEnableSharedListOpt: 1 + n3dsEnableVSync: 0 xboxOneResolution: 0 xboxOneSResolution: 0 xboxOneXResolution: 3 @@ -105,13 +108,18 @@ PlayerSettings: xboxOneLoggingLevel: 1 xboxOneDisableEsram: 0 xboxOnePresentImmediateThreshold: 0 - switchQueueCommandMemory: 1048576 - switchQueueControlMemory: 16384 - switchQueueComputeMemory: 262144 - switchNVNShaderPoolsGranularity: 33554432 - switchNVNDefaultPoolsGranularity: 16777216 - switchNVNOtherPoolsGranularity: 16777216 - vulkanEnableSetSRGBWrite: 0 + videoMemoryForVertexBuffers: 0 + psp2PowerMode: 0 + psp2AcquireBGM: 1 + wiiUTVResolution: 0 + wiiUGamePadMSAA: 1 + wiiUSupportsNunchuk: 0 + wiiUSupportsClassicController: 0 + wiiUSupportsBalanceBoard: 0 + wiiUSupportsMotionPlus: 0 + wiiUSupportsProController: 0 + wiiUAllowScreenCapture: 1 + wiiUControllerCount: 0 m_SupportedAspectRatios: 4:3: 1 5:4: 1 @@ -125,7 +133,6 @@ PlayerSettings: m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 0 xboxOneEnable7thCore: 0 - isWsaHolographicRemotingEnabled: 0 vrSettings: cardboard: depthFormat: 0 @@ -143,9 +150,7 @@ PlayerSettings: oculus: sharedDepthBuffer: 1 dashSupport: 1 - enable360StereoCapture: 0 protectGraphicsMemory: 0 - enableFrameTimingStats: 0 useHDRDisplay: 0 m_ColorGamuts: 00000000 targetPixelDensity: 30 @@ -169,7 +174,9 @@ PlayerSettings: APKExpansionFiles: 0 keepLoadedShadersAlive: 0 StripUnusedMeshComponents: 0 - VertexChannelCompressionMask: 214 + VertexChannelCompressionMask: + serializedVersion: 2 + m_Bits: 4294901998 iPhoneSdkVersion: 988 iOSTargetOSVersionString: 9.0 tvOSSdkVersion: 0 @@ -198,7 +205,6 @@ PlayerSettings: tvOSSmallIconLayers: [] tvOSSmallIconLayers2x: [] tvOSLargeIconLayers: [] - tvOSLargeIconLayers2x: [] tvOSTopShelfImageLayers: [] tvOSTopShelfImageLayers2x: [] tvOSTopShelfImageWideLayers: [] @@ -232,21 +238,13 @@ PlayerSettings: appleDeveloperTeamID: iOSManualSigningProvisioningProfileID: tvOSManualSigningProvisioningProfileID: - iOSManualSigningProvisioningProfileType: 0 - tvOSManualSigningProvisioningProfileType: 0 appleEnableAutomaticSigning: 0 - iOSRequireARKit: 0 - iOSAutomaticallyDetectAndAddCapabilities: 1 - appleEnableProMotion: 0 clonedFromGUID: 00000000000000000000000000000000 - templatePackageId: - templateDefaultScene: AndroidTargetArchitectures: 5 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} AndroidKeystoreName: AndroidKeyaliasName: - AndroidBuildApkPerCpuArchitecture: 0 AndroidTVCompatibility: 1 AndroidIsGame: 1 AndroidEnableTango: 0 @@ -259,7 +257,6 @@ PlayerSettings: androidGamepadSupportLevel: 0 resolutionDialogBanner: {fileID: 0} m_BuildTargetIcons: [] - m_BuildTargetPlatformIcons: [] m_BuildTargetBatching: [] m_BuildTargetGraphicsAPIs: [] m_BuildTargetVRSettings: [] @@ -278,9 +275,25 @@ PlayerSettings: m_EncodingQuality: 1 - m_BuildTarget: PS4 m_EncodingQuality: 1 - m_BuildTargetGroupLightmapSettings: [] + wiiUTitleID: 0005000011000000 + wiiUGroupID: 00010000 + wiiUCommonSaveSize: 4096 + wiiUAccountSaveSize: 2048 + wiiUOlvAccessKey: 0 + wiiUTinCode: 0 + wiiUJoinGameId: 0 + wiiUJoinGameModeMask: 0000000000000000 + wiiUCommonBossSize: 0 + wiiUAccountBossSize: 0 + wiiUAddOnUniqueIDs: [] + wiiUMainThreadStackSize: 3072 + wiiULoaderThreadStackSize: 1024 + wiiUSystemHeapSize: 128 + wiiUTVStartupScreen: {fileID: 0} + wiiUGamePadStartupScreen: {fileID: 0} + wiiUDrcBufferDisabled: 0 + wiiUProfilerLibPath: playModeTestRunnerEnabled: 0 - runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 enableInternalProfiler: 0 logObjCUncaughtExceptions: 1 @@ -401,11 +414,7 @@ PlayerSettings: switchAllowsRuntimeAddOnContentInstall: 0 switchDataLossConfirmation: 0 switchUserAccountLockEnabled: 0 - switchSystemResourceMemory: 16777216 switchSupportedNpadStyles: 3 - switchNativeFsCacheSize: 32 - switchIsHoldTypeHorizontal: 0 - switchSupportedNpadCount: 8 switchSocketConfigEnabled: 0 switchTcpInitialSendBufferSize: 32 switchTcpInitialReceiveBufferSize: 64 @@ -461,8 +470,6 @@ PlayerSettings: ps4pnFriends: 1 ps4pnGameCustomData: 1 playerPrefsSupport: 0 - enableApplicationExit: 0 - resetTempFolder: 1 restrictedAudioUsageRights: 0 ps4UseResolutionFallback: 0 ps4ReprojectionSupport: 0 @@ -486,6 +493,54 @@ PlayerSettings: ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] monoEnv: + psp2Splashimage: {fileID: 0} + psp2NPTrophyPackPath: + psp2NPSupportGBMorGJP: 0 + psp2NPAgeRating: 12 + psp2NPTitleDatPath: + psp2NPCommsID: + psp2NPCommunicationsID: + psp2NPCommsPassphrase: + psp2NPCommsSig: + psp2ParamSfxPath: + psp2ManualPath: + psp2LiveAreaGatePath: + psp2LiveAreaBackroundPath: + psp2LiveAreaPath: + psp2LiveAreaTrialPath: + psp2PatchChangeInfoPath: + psp2PatchOriginalPackage: + psp2PackagePassword: 5PN2qmWqBlQ9wQj99nsQzldVI5ZuGXbE + psp2KeystoneFile: + psp2MemoryExpansionMode: 0 + psp2DRMType: 0 + psp2StorageType: 0 + psp2MediaCapacity: 0 + psp2DLCConfigPath: + psp2ThumbnailPath: + psp2BackgroundPath: + psp2SoundPath: + psp2TrophyCommId: + psp2TrophyPackagePath: + psp2PackagedResourcesPath: + psp2SaveDataQuota: 10240 + psp2ParentalLevel: 1 + psp2ShortTitle: Not Set + psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF + psp2Category: 0 + psp2MasterVersion: 01.00 + psp2AppVersion: 01.00 + psp2TVBootMode: 0 + psp2EnterButtonAssignment: 2 + psp2TVDisableEmu: 0 + psp2AllowTwitterDialog: 1 + psp2Upgradable: 0 + psp2HealthWarning: 0 + psp2UseLibLocation: 0 + psp2InfoBarOnStartup: 0 + psp2InfoBarColor: 0 + psp2ScriptOptimizationLevel: 0 + psmSplashimage: {fileID: 0} splashScreenBackgroundSourceLandscape: {fileID: 0} splashScreenBackgroundSourcePortrait: {fileID: 0} spritePackerPolicy: @@ -499,16 +554,12 @@ PlayerSettings: webGLTemplate: APPLICATION:Default webGLAnalyzeBuildSize: 0 webGLUseEmbeddedResources: 0 + webGLUseWasm: 0 webGLCompressionFormat: 1 - webGLLinkerTarget: 1 - webGLThreadsSupport: 0 scriptingDefineSymbols: {} platformArchitecture: {} scriptingBackend: {} - il2cppCompilerConfiguration: {} - managedStrippingLevel: {} incrementalIl2cppBuild: {} - allowUnsafeCode: 0 additionalIl2CppArgs: scriptingRuntimeVersion: 0 apiCompatibilityLevelPerPlatform: {} @@ -524,12 +575,11 @@ PlayerSettings: metroApplicationDescription: XChart wsaImages: {} metroTileShortName: + metroCommandLineArgsFile: metroTileShowName: 0 metroMediumTileShowName: 0 metroLargeTileShowName: 0 metroWideTileShowName: 0 - metroSupportStreamingInstall: 0 - metroLastRequiredScene: 0 metroDefaultTileSize: 1 metroTileForegroundText: 2 metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} @@ -537,11 +587,29 @@ PlayerSettings: a: 1} metroSplashScreenUseBackgroundColor: 0 platformCapabilities: {} - metroTargetDeviceFamilies: {} metroFTAName: metroFTAFileTypes: [] metroProtocolName: metroCompilationOverrides: 1 + tizenProductDescription: + tizenProductURL: + tizenSigningProfileName: + tizenGPSPermissions: 0 + tizenMicrophonePermissions: 0 + tizenDeploymentTarget: + tizenDeploymentTargetType: -1 + tizenMinOSVersion: 1 + n3dsUseExtSaveData: 0 + n3dsCompressStaticMem: 1 + n3dsExtSaveDataNumber: 0x12345 + n3dsStackSize: 131072 + n3dsTargetPlatform: 2 + n3dsRegion: 7 + n3dsMediaSize: 0 + n3dsLogoStyle: 3 + n3dsTitle: GameName + n3dsProductCode: + n3dsApplicationId: 0xFF3FF XboxOneProductId: XboxOneUpdateKey: XboxOneSandboxId: @@ -551,7 +619,6 @@ PlayerSettings: XboxOneGameOsOverridePath: XboxOnePackagingOverridePath: XboxOneAppManifestOverridePath: - XboxOneVersion: 1.0.0.0 XboxOnePackageEncryption: 0 XboxOnePackageUpdateGranularity: 2 XboxOneDescription: @@ -567,36 +634,16 @@ PlayerSettings: XboxOnePersistentLocalStorageSize: 0 XboxOneXTitleMemory: 8 xboxOneScriptCompiler: 0 - XboxOneOverrideIdentityName: vrEditorSettings: daydream: daydreamIconForeground: {fileID: 0} daydreamIconBackground: {fileID: 0} cloudServicesEnabled: {} - luminIcon: - m_Name: - m_ModelFolderPath: - m_PortalFolderPath: - luminCert: - m_CertPath: - m_PrivateKeyPath: - luminIsChannelApp: 0 - luminVersion: - m_VersionCode: 1 - m_VersionName: facebookSdkVersion: 7.9.4 - facebookAppId: - facebookCookies: 1 - facebookLogging: 1 - facebookStatus: 1 - facebookXfbml: 0 - facebookFrictionlessRequests: 1 - apiCompatibilityLevel: 6 + apiCompatibilityLevel: 3 cloudProjectId: 3b1850f7-c289-4929-a842-faf5ef85f8ca - framebufferDepthMemorylessMode: 0 projectName: XChart organizationId: huang-qingzhen cloudEnabled: 0 enableNativePlatformBackendsForNewInputSystem: 0 disableOldInputManagerSupport: 0 - legacyClampBlendShapeWeights: 1