diff --git a/Editor/PropertyDrawers/VisualMapDrawer.cs b/Editor/PropertyDrawers/VisualMapDrawer.cs index f6829d92..5466c0f7 100644 --- a/Editor/PropertyDrawers/VisualMapDrawer.cs +++ b/Editor/PropertyDrawers/VisualMapDrawer.cs @@ -20,6 +20,8 @@ namespace XCharts if (MakeFoldout(prop, "m_Enable")) { ++EditorGUI.indentLevel; + var type = (VisualMap.Type)prop.FindPropertyRelative("m_Type").enumValueIndex; + var isPiece = type == VisualMap.Type.Piecewise; PropertyField(prop, "m_Type"); PropertyField(prop, "m_AutoMinMax"); PropertyField(prop, "m_Min"); @@ -27,16 +29,7 @@ namespace XCharts PropertyField(prop, "m_SplitNumber"); PropertyField(prop, "m_Dimension"); PropertyListField(prop, "m_OutOfRange"); - var type = (VisualMap.Type)prop.FindPropertyRelative("m_Type").enumValueIndex; - switch (type) - { - case VisualMap.Type.Continuous: - PropertyListField(prop, "m_InRange"); - break; - case VisualMap.Type.Piecewise: - PropertyListField(prop, "m_Pieces"); - break; - } + PropertyListField(prop, isPiece ? "m_Pieces" : "m_InRange"); PropertyField(prop, "m_Show"); if (prop.FindPropertyRelative("m_Show").boolValue) { @@ -48,6 +41,7 @@ namespace XCharts PropertyField(prop, "m_Calculable"); PropertyField(prop, "m_ItemWidth"); PropertyField(prop, "m_ItemHeight"); + if (isPiece) PropertyField(prop, "m_ItemGap"); PropertyField(prop, "m_BorderWidth"); PropertyField(prop, "m_Orient"); PropertyField(prop, "m_Location"); diff --git a/Runtime/API/BaseChart_API.cs b/Runtime/API/BaseChart_API.cs index 9e8d6057..51021012 100644 --- a/Runtime/API/BaseChart_API.cs +++ b/Runtime/API/BaseChart_API.cs @@ -70,6 +70,18 @@ namespace XCharts /// public Settings settings { get { return m_Settings; } } /// + /// dataZoom component. + /// 区域缩放组件。 + /// + public DataZoom dataZoom { get { return m_DataZooms.Count > 0 ? m_DataZooms[0] : null; } } + public List dataZooms { get { return m_DataZooms; } } + /// + /// visualMap component. + /// 视觉映射组件。 + /// + public VisualMap visualMap { get { return m_VisualMaps.Count > 0 ? m_VisualMaps[0] : null; } } + public List visualMaps { get { return m_VisualMaps; } } + /// /// The x of chart. /// 图表的X /// diff --git a/Runtime/API/BaseGraph_API.cs b/Runtime/API/BaseGraph_API.cs index d0facd82..13829ed0 100644 --- a/Runtime/API/BaseGraph_API.cs +++ b/Runtime/API/BaseGraph_API.cs @@ -163,5 +163,16 @@ namespace XCharts ChartHelper.DestroyAllChildren(transform); //SetAllComponentDirty(); } + + public bool ScreenPointToChartPoint(Vector2 screenPoint, out Vector2 chartPoint) + { + var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera; + if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, + screenPoint, cam, out chartPoint)) + { + return false; + } + return true; + } } } diff --git a/Runtime/API/CoordinateChart_API.cs b/Runtime/API/CoordinateChart_API.cs index 357905d1..30228691 100644 --- a/Runtime/API/CoordinateChart_API.cs +++ b/Runtime/API/CoordinateChart_API.cs @@ -33,16 +33,7 @@ namespace XCharts /// 两个y轴。 /// public List yAxes { get { return m_YAxes; } } - /// - /// dataZoom component. - /// 区域缩放组件。 - /// - public DataZoom dataZoom { get { return m_DataZooms.Count > 0 ? m_DataZooms[0] : null; } } - /// - /// visualMap component. - /// 视觉映射组件。 - /// - public VisualMap visualMap { get { return m_VisualMaps.Count > 0 ? m_VisualMaps[0] : null; } } + /// /// X轴(下) /// @@ -204,7 +195,13 @@ namespace XCharts /// public void RefreshDataZoom() { - RefreshDataZoomLabel(); + foreach (var handler in m_ComponentHandlers) + { + if (handler is DataZoomHandler) + { + (handler as DataZoomHandler).RefreshDataZoomLabel(); + } + } } /// diff --git a/Runtime/Component/Main/DataZoom.cs b/Runtime/Component/Main/DataZoom.cs index a7e88803..47a01029 100644 --- a/Runtime/Component/Main/DataZoom.cs +++ b/Runtime/Component/Main/DataZoom.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using UnityEngine; +using UnityEngine.EventSystems; using UnityEngine.UI; namespace XCharts @@ -360,6 +361,10 @@ namespace XCharts public float runtimeY { get; private set; } public float runtimeWidth { get; private set; } public float runtimeHeight { get; private set; } + public bool runtimeDrag { get; internal set; } + public bool runtimeCoordinateDrag { get; internal set; } + public bool runtimeStartDrag { get; internal set; } + public bool runtimeEndDrag { get; internal set; } class AxisIndexValueInfo { @@ -631,4 +636,344 @@ namespace XCharts } } } + + + internal class DataZoomHandler : IComponentHandler + { + public CoordinateChart chart; + private Vector2 m_LastTouchPos0; + private Vector2 m_LastTouchPos1; + private bool m_CheckDataZoomLabel; + private float m_DataZoomLastStartIndex; + private float m_DataZoomLastEndIndex; + + public DataZoomHandler(BaseChart chart) + { + this.chart = chart as CoordinateChart; + } + + public void Init() { } + + public void Update() + { + foreach (var dataZoom in chart.dataZooms) + { + CheckDataZoomScale(dataZoom); + CheckDataZoomLabel(dataZoom); + } + } + + public void Draw(VertexHelper vh) + { + } + + public void OnBeginDrag(PointerEventData eventData) + { + if (Input.touchCount > 1) return; + Vector2 pos; + if (!chart.ScreenPointToChartPoint(eventData.position, out pos)) + { + return; + } + foreach (var dataZoom in chart.dataZooms) + { + if (!dataZoom.enable) continue; + var grid = chart.GetDataZoomGridOrDefault(dataZoom); + if (dataZoom.supportInside) + { + if (chart.IsInGrid(grid, pos)) + { + dataZoom.runtimeCoordinateDrag = true; + } + } + if (dataZoom.supportSlider) + { + if (dataZoom.IsInStartZoom(pos)) + { + dataZoom.runtimeStartDrag = true; + } + else if (dataZoom.IsInEndZoom(pos)) + { + dataZoom.runtimeEndDrag = true; + } + else if (dataZoom.IsInSelectedZoom(pos)) + { + dataZoom.runtimeDrag = true; + } + } + } + } + + public void OnDrag(PointerEventData eventData) + { + if (Input.touchCount > 1) return; + foreach (var dataZoom in chart.dataZooms) + { + var grid = chart.GetDataZoomGridOrDefault(dataZoom); + float deltaX = eventData.delta.x; + float deltaPercent = deltaX / grid.runtimeWidth * 100; + OnDragInside(dataZoom, deltaPercent); + OnDragSlider(dataZoom, deltaPercent); + } + } + + public void OnEndDrag(PointerEventData eventData) + { + foreach (var dataZoom in chart.dataZooms) + { + if (dataZoom.runtimeDrag || dataZoom.runtimeStartDrag || dataZoom.runtimeEndDrag + || dataZoom.runtimeCoordinateDrag) + { + chart.RefreshChart(); + } + dataZoom.runtimeDrag = false; + dataZoom.runtimeCoordinateDrag = false; + dataZoom.runtimeStartDrag = false; + dataZoom.runtimeEndDrag = false; + } + } + public void OnPointerDown(PointerEventData eventData) + { + if (Input.touchCount > 1) return; + Vector2 localPos; + if (!chart.ScreenPointToChartPoint(eventData.position, out localPos)) + { + return; + } + foreach (var dataZoom in chart.dataZooms) + { + var grid = chart.GetDataZoomGridOrDefault(dataZoom); + if (dataZoom.IsInStartZoom(localPos) || + dataZoom.IsInEndZoom(localPos)) + { + return; + } + if (dataZoom.IsInZoom(localPos) + && !dataZoom.IsInSelectedZoom(localPos)) + { + var pointerX = localPos.x; + var selectWidth = grid.runtimeWidth * (dataZoom.end - dataZoom.start) / 100; + var startX = pointerX - selectWidth / 2; + var endX = pointerX + selectWidth / 2; + if (startX < grid.runtimeX) + { + startX = grid.runtimeX; + endX = grid.runtimeX + selectWidth; + } + else if (endX > grid.runtimeX + grid.runtimeWidth) + { + endX = grid.runtimeX + grid.runtimeWidth; + startX = grid.runtimeX + grid.runtimeWidth - selectWidth; + } + dataZoom.start = (startX - grid.runtimeX) / grid.runtimeWidth * 100; + dataZoom.end = (endX - grid.runtimeX) / grid.runtimeWidth * 100; + RefreshDataZoomLabel(); + chart.RefreshChart(); + } + } + } + public void OnScroll(PointerEventData eventData) + { + if (Input.touchCount > 1) return; + foreach (var dataZoom in chart.dataZooms) + { + if (!dataZoom.enable || dataZoom.zoomLock) return; + Vector2 pos; + if (!chart.ScreenPointToChartPoint(eventData.position, out pos)) + { + return; + } + var grid = chart.GetDataZoomGridOrDefault(dataZoom); + if (!chart.IsInGrid(grid, pos) && !dataZoom.IsInSelectedZoom(pos)) + { + return; + } + ScaleDataZoom(dataZoom, eventData.scrollDelta.y * dataZoom.scrollSensitivity); + } + } + + private void OnDragInside(DataZoom dataZoom, float deltaPercent) + { + if (Input.touchCount > 1) return; + if (!dataZoom.supportInside) return; + if (!dataZoom.runtimeCoordinateDrag) return; + var diff = dataZoom.end - dataZoom.start; + if (deltaPercent > 0) + { + dataZoom.start -= deltaPercent; + dataZoom.end = dataZoom.start + diff; + } + else + { + dataZoom.end += -deltaPercent; + dataZoom.start = dataZoom.end - diff; + } + RefreshDataZoomLabel(); + chart.RefreshChart(); + } + + private void OnDragSlider(DataZoom dataZoom, float deltaPercent) + { + if (Input.touchCount > 1) return; + if (!dataZoom.supportSlider) return; + if (dataZoom.runtimeStartDrag) + { + dataZoom.start += deltaPercent; + if (dataZoom.start > dataZoom.end) + { + dataZoom.start = dataZoom.end; + dataZoom.runtimeEndDrag = true; + dataZoom.runtimeStartDrag = false; + } + if (dataZoom.realtime) + { + RefreshDataZoomLabel(); + chart.RefreshChart(); + } + } + else if (dataZoom.runtimeEndDrag) + { + dataZoom.end += deltaPercent; + if (dataZoom.end < dataZoom.start) + { + dataZoom.end = dataZoom.start; + dataZoom.runtimeStartDrag = true; + dataZoom.runtimeEndDrag = false; + } + if (dataZoom.realtime) + { + RefreshDataZoomLabel(); + chart.RefreshChart(); + } + } + else if (dataZoom.runtimeDrag) + { + if (deltaPercent > 0) + { + if (dataZoom.end + deltaPercent > 100) + { + deltaPercent = 100 - dataZoom.end; + } + } + else + { + if (dataZoom.start + deltaPercent < 0) + { + deltaPercent = -dataZoom.start; + } + } + dataZoom.start += deltaPercent; + dataZoom.end += deltaPercent; + if (dataZoom.realtime) + { + RefreshDataZoomLabel(); + chart.RefreshChart(); + } + } + } + + private void ScaleDataZoom(DataZoom dataZoom, float delta) + { + var grid = chart.GetDataZoomGridOrDefault(dataZoom); + float deltaPercent = Mathf.Abs(delta / grid.runtimeWidth * 100); + if (delta > 0) + { + if (dataZoom.end <= dataZoom.start) return; + dataZoom.end -= deltaPercent; + dataZoom.start += deltaPercent; + if (dataZoom.end <= dataZoom.start) + { + dataZoom.end = dataZoom.start; + } + } + else + { + dataZoom.end += deltaPercent; + dataZoom.start -= deltaPercent; + if (dataZoom.end > 100) dataZoom.end = 100; + if (dataZoom.start < 0) dataZoom.start = 0; + } + RefreshDataZoomLabel(); + chart.RefreshChart(); + } + + public void RefreshDataZoomLabel() + { + m_CheckDataZoomLabel = true; + } + + private void CheckDataZoomScale(DataZoom dataZoom) + { + if (!dataZoom.enable || dataZoom.zoomLock || !dataZoom.supportInside) return; + + if (Input.touchCount == 2) + { + var touch0 = Input.GetTouch(0); + var touch1 = Input.GetTouch(1); + if (touch1.phase == TouchPhase.Began) + { + m_LastTouchPos0 = touch0.position; + m_LastTouchPos1 = touch1.position; + } + else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved) + { + var tempPos0 = touch0.position; + var tempPos1 = touch1.position; + var currDist = Vector2.Distance(tempPos0, tempPos1); + var lastDist = Vector2.Distance(m_LastTouchPos0, m_LastTouchPos1); + var delta = (currDist - lastDist); + ScaleDataZoom(dataZoom, delta / dataZoom.scrollSensitivity); + m_LastTouchPos0 = tempPos0; + m_LastTouchPos1 = tempPos1; + } + } + } + + private void CheckDataZoomLabel(DataZoom dataZoom) + { + if (dataZoom.enable && dataZoom.supportSlider && dataZoom.showDetail) + { + Vector2 local; + if (!chart.ScreenPointToChartPoint(Input.mousePosition, out local)) + { + dataZoom.SetLabelActive(false); + return; + } + if (dataZoom.IsInSelectedZoom(local) + || dataZoom.IsInStartZoom(local) + || dataZoom.IsInEndZoom(local)) + { + dataZoom.SetLabelActive(true); + RefreshDataZoomLabel(); + } + else + { + dataZoom.SetLabelActive(false); + } + } + if (m_CheckDataZoomLabel) + { + m_CheckDataZoomLabel = false; + var xAxis = chart.GetXAxis(dataZoom.xAxisIndexs[0]); + var startIndex = (int)((xAxis.data.Count - 1) * dataZoom.start / 100); + var endIndex = (int)((xAxis.data.Count - 1) * dataZoom.end / 100); + if (m_DataZoomLastStartIndex != startIndex || m_DataZoomLastEndIndex != endIndex) + { + m_DataZoomLastStartIndex = startIndex; + m_DataZoomLastEndIndex = endIndex; + if (xAxis.data.Count > 0) + { + dataZoom.SetStartLabelText(xAxis.data[startIndex]); + dataZoom.SetEndLabelText(xAxis.data[endIndex]); + } + chart.InitAxisX(); + } + var start = dataZoom.runtimeX + dataZoom.runtimeWidth * dataZoom.start / 100; + var end = dataZoom.runtimeX + dataZoom.runtimeWidth * dataZoom.end / 100; + var hig = dataZoom.runtimeHeight; + dataZoom.UpdateStartLabelPosition(new Vector3(start - 10, chart.chartY + dataZoom.bottom + hig / 2)); + dataZoom.UpdateEndLabelPosition(new Vector3(end + 10, chart.chartY + dataZoom.bottom + hig / 2)); + } + } + } } \ No newline at end of file diff --git a/Runtime/Component/Main/VisualMap.cs b/Runtime/Component/Main/VisualMap.cs index 483616ea..c35d0d2e 100644 --- a/Runtime/Component/Main/VisualMap.cs +++ b/Runtime/Component/Main/VisualMap.cs @@ -7,6 +7,9 @@ using System.Collections.Generic; using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.UI; +using XUGL; namespace XCharts { @@ -95,6 +98,7 @@ namespace XCharts [SerializeField] private bool m_Realtime = true; [SerializeField] private float m_ItemWidth = 20f; [SerializeField] private float m_ItemHeight = 140f; + [SerializeField] private float m_ItemGap = 10f; [SerializeField] private float m_BorderWidth = 0; [SerializeField] private int m_Dimension = -1; [SerializeField] private bool m_HoverLink = true; @@ -236,6 +240,14 @@ namespace XCharts set { if (PropertyUtil.SetStruct(ref m_ItemHeight, value)) SetVerticesDirty(); } } /// + /// 每个图元之间的间隔距离。 + /// + public float itemGap + { + get { return m_ItemGap; } + set { if (PropertyUtil.SetStruct(ref m_ItemGap, value)) SetVerticesDirty(); } + } + /// /// Border line width. /// /// 边框线宽,单位px。 @@ -343,13 +355,13 @@ namespace XCharts /// 鼠标悬停选中的index /// /// - public int runtimeSelectedIndex { get; internal set; } - public float runtimeSelectedValue { get; internal set; } + public int runtimeSelectedIndex { get; set; } + public float runtimeSelectedValue { get; set; } /// /// the current pointer position. /// 当前鼠标位置。 /// - public Vector2 runtimePointerPos { get; internal set; } + public Vector2 runtimePointerPos { get; set; } public bool runtimeIsVertical { get { return orient == Orient.Vertical; } } public float rangeMin { @@ -388,6 +400,8 @@ namespace XCharts public float runtimeRangeMinHeight { get { return (rangeMin - min) / (max - min) * itemHeight; } } public float runtimeRangeMaxHeight { get { return (rangeMax - min) / (max - min) * itemHeight; } } + public bool runtimeMinDrag { get; internal set; } + public bool runtimeMaxDrag { get; internal set; } private List m_RtInRange = new List(); public List runtimeInRange @@ -616,4 +630,365 @@ namespace XCharts } } } + + internal class VisualMapHandler : IComponentHandler + { + public BaseChart chart; + + public VisualMapHandler(BaseChart chart) + { + this.chart = chart; + } + + public void Init() { } + public void OnBeginDrag(PointerEventData eventData) + { + foreach (var visualMap in chart.visualMaps) + { + OnDragVisualMapStart(visualMap); + } + } + public void OnDrag(PointerEventData eventData) + { + foreach (var visualMap in chart.visualMaps) + { + OnDragVisualMap(visualMap); + } + } + + public void OnEndDrag(PointerEventData eventData) + { + foreach (var visualMap in chart.visualMaps) + { + OnDragVisualMapEnd(visualMap); + } + } + public void OnPointerDown(PointerEventData eventData) { } + public void OnScroll(PointerEventData eventData) { } + + public void Update() + { + foreach (var visualMap in chart.visualMaps) + { + CheckVisualMap(visualMap); + } + } + + public void Draw(VertexHelper vh) + { + var visualMap = chart.visualMap; + if (!visualMap.enable || !visualMap.show) return; + switch (visualMap.type) + { + case VisualMap.Type.Continuous: + DrawContinuousVisualMap(vh, visualMap); + break; + case VisualMap.Type.Piecewise: + //DrawPiecewiseVisualMap(vh, visualMap); + break; + } + } + + private void CheckVisualMap(VisualMap visualMap) + { + if (visualMap == null || !visualMap.enable || !visualMap.show) return; + Vector2 local; + if (chart.canvas == null) return; + + if (!chart.ScreenPointToChartPoint(Input.mousePosition, out local)) + { + if (visualMap.runtimeSelectedIndex >= 0) + { + visualMap.runtimeSelectedIndex = -1; + chart.RefreshChart(); + } + return; + } + if (local.x < chart.chartX || local.x > chart.chartX + chart.chartWidth || + local.y < chart.chartY || local.y > chart.chartY + chart.chartHeight || + !visualMap.IsInRangeRect(local, chart.chartRect)) + { + if (visualMap.runtimeSelectedIndex >= 0) + { + visualMap.runtimeSelectedIndex = -1; + chart.RefreshChart(); + } + return; + } + var pos1 = Vector3.zero; + var pos2 = Vector3.zero; + var halfHig = visualMap.itemHeight / 2; + var centerPos = chart.chartPosition + visualMap.location.GetPosition(chart.chartWidth, chart.chartHeight); + var selectedIndex = -1; + var value = 0f; + switch (visualMap.orient) + { + case Orient.Horizonal: + pos1 = centerPos + Vector3.left * halfHig; + pos2 = centerPos + Vector3.right * halfHig; + value = visualMap.min + (local.x - pos1.x) / (pos2.x - pos1.x) * (visualMap.max - visualMap.min); + selectedIndex = visualMap.GetIndex(value); + break; + case Orient.Vertical: + pos1 = centerPos + Vector3.down * halfHig; + pos2 = centerPos + Vector3.up * halfHig; + value = visualMap.min + (local.y - pos1.y) / (pos2.y - pos1.y) * (visualMap.max - visualMap.min); + selectedIndex = visualMap.GetIndex(value); + break; + } + visualMap.runtimeSelectedValue = value; + visualMap.runtimeSelectedIndex = selectedIndex; + chart.RefreshChart(); + } + + private void DrawContinuousVisualMap(VertexHelper vh, VisualMap visualMap) + { + var centerPos = chart.chartPosition + visualMap.location.GetPosition(chart.chartWidth, chart.chartHeight); + var pos1 = Vector3.zero; + var pos2 = Vector3.zero; + var dir = Vector3.zero; + var halfWid = visualMap.itemWidth / 2; + var halfHig = visualMap.itemHeight / 2; + var xRadius = 0f; + var yRadius = 0f; + var splitNum = visualMap.runtimeInRange.Count; + var splitWid = visualMap.itemHeight / (splitNum - 1); + var isVertical = false; + var colors = visualMap.runtimeInRange; + var triangeLen = chart.theme.visualMap.triangeLen; + switch (visualMap.orient) + { + case Orient.Horizonal: + pos1 = centerPos + Vector3.left * halfHig; + pos2 = centerPos + Vector3.right * halfHig; + dir = Vector3.right; + xRadius = splitWid / 2; + yRadius = halfWid; + isVertical = false; + if (visualMap.calculable) + { + var p0 = pos1 + Vector3.right * visualMap.runtimeRangeMinHeight; + var p1 = p0 + Vector3.up * halfWid; + var p2 = p0 + Vector3.up * (halfWid + triangeLen); + var p3 = p2 + Vector3.left * triangeLen; + var color = visualMap.GetColor(visualMap.rangeMin); + UGL.DrawTriangle(vh, p1, p2, p3, color); + p0 = pos1 + Vector3.right * visualMap.runtimeRangeMaxHeight; + p1 = p0 + Vector3.up * halfWid; + p2 = p0 + Vector3.up * (halfWid + triangeLen); + p3 = p2 + Vector3.right * triangeLen; + color = visualMap.GetColor(visualMap.rangeMax); + UGL.DrawTriangle(vh, p1, p2, p3, color); + } + break; + case Orient.Vertical: + pos1 = centerPos + Vector3.down * halfHig; + pos2 = centerPos + Vector3.up * halfHig; + dir = Vector3.up; + xRadius = halfWid; + yRadius = splitWid / 2; + isVertical = true; + if (visualMap.calculable) + { + var p0 = pos1 + Vector3.up * visualMap.runtimeRangeMinHeight; + var p1 = p0 + Vector3.right * halfWid; + var p2 = p0 + Vector3.right * (halfWid + triangeLen); + var p3 = p2 + Vector3.down * triangeLen; + var color = visualMap.GetColor(visualMap.rangeMin); + UGL.DrawTriangle(vh, p1, p2, p3, color); + p0 = pos1 + Vector3.up * visualMap.runtimeRangeMaxHeight; + p1 = p0 + Vector3.right * halfWid; + p2 = p0 + Vector3.right * (halfWid + triangeLen); + p3 = p2 + Vector3.up * triangeLen; + color = visualMap.GetColor(visualMap.rangeMax); + UGL.DrawTriangle(vh, p1, p2, p3, color); + } + break; + } + if (visualMap.calculable && (visualMap.rangeMin > visualMap.min + || visualMap.rangeMax < visualMap.max)) + { + var rangeMin = visualMap.rangeMin; + var rangeMax = visualMap.rangeMax; + var diff = (visualMap.max - visualMap.min) / (splitNum - 1); + for (int i = 1; i < splitNum; i++) + { + var splitMin = visualMap.min + (i - 1) * diff; + var splitMax = splitMin + diff; + if (rangeMin > splitMax || rangeMax < splitMin) + { + continue; + } + else if (rangeMin <= splitMin && rangeMax >= splitMax) + { + var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid; + var startColor = colors[i - 1]; + var toColor = visualMap.IsPiecewise() ? startColor : colors[i]; + UGL.DrawRectangle(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical); + } + else if (rangeMin > splitMin && rangeMax >= splitMax) + { + var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; + var splitMaxPos = pos1 + dir * i * splitWid; + var splitPos = p0 + (splitMaxPos - p0) / 2; + var startColor = visualMap.GetColor(visualMap.rangeMin); + var toColor = visualMap.IsPiecewise() ? startColor : colors[i]; + var yRadius1 = Vector3.Distance(p0, splitMaxPos) / 2; + if (visualMap.orient == Orient.Vertical) + UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); + else + UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); + } + else if (rangeMax < splitMax && rangeMin <= splitMin) + { + var p0 = pos1 + dir * visualMap.runtimeRangeMaxHeight; + var splitMinPos = pos1 + dir * (i - 1) * splitWid; + var splitPos = splitMinPos + (p0 - splitMinPos) / 2; + var startColor = colors[i - 1]; + var toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(visualMap.rangeMax); + var yRadius1 = Vector3.Distance(p0, splitMinPos) / 2; + if (visualMap.orient == Orient.Vertical) + UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); + else + UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); + } + else + { + var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; + var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; + var splitPos = (p0 + p1) / 2; + var startColor = visualMap.GetColor(visualMap.rangeMin); + var toColor = visualMap.GetColor(visualMap.rangeMax); + var yRadius1 = Vector3.Distance(p0, p1) / 2; + if (visualMap.orient == Orient.Vertical) + UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); + else + UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); + } + } + } + else + { + for (int i = 1; i < splitNum; i++) + { + var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid; + var startColor = colors[i - 1]; + var toColor = visualMap.IsPiecewise() ? startColor : colors[i]; + UGL.DrawRectangle(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical); + } + } + + if (visualMap.rangeMin > visualMap.min) + { + var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; + UGL.DrawRectangle(vh, pos1, p0, visualMap.itemWidth / 2, chart.theme.visualMap.backgroundColor); + } + if (visualMap.rangeMax < visualMap.max) + { + var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; + UGL.DrawRectangle(vh, p1, pos2, visualMap.itemWidth / 2, chart.theme.visualMap.backgroundColor); + } + + if (visualMap.hoverLink) + { + if (visualMap.runtimeSelectedIndex >= 0) + { + var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; + var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; + var pointerPos = chart.pointerPos; + if (visualMap.orient == Orient.Vertical) + { + var p2 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y + (triangeLen / 2), p0.y, p1.y)); + var p3 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y - (triangeLen / 2), p0.y, p1.y)); + var p4 = new Vector3(centerPos.x + halfWid + triangeLen / 2, pointerPos.y); + UGL.DrawTriangle(vh, p2, p3, p4, colors[visualMap.runtimeSelectedIndex]); + } + else + { + var p2 = new Vector3(Mathf.Clamp(pointerPos.x + (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); + var p3 = new Vector3(Mathf.Clamp(pointerPos.x - (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); + var p4 = new Vector3(pointerPos.x, centerPos.y + halfWid + triangeLen / 2); + UGL.DrawTriangle(vh, p2, p3, p4, colors[visualMap.runtimeSelectedIndex]); + } + } + } + } + private void DrawPiecewiseVisualMap(VertexHelper vh, VisualMap visualMap) + { + var centerPos = chart.chartPosition + visualMap.location.GetPosition(chart.chartWidth, chart.chartHeight); + var pos1 = Vector3.zero; + var pos2 = Vector3.zero; + var dir = Vector3.zero; + var halfWid = visualMap.itemWidth / 2; + var halfHig = visualMap.itemHeight / 2; + var splitNum = visualMap.runtimeInRange.Count; + var splitWid = visualMap.itemHeight / (splitNum - 1); + var colors = visualMap.runtimeInRange; + switch (visualMap.orient) + { + case Orient.Horizonal: + for (int i = 0; i < visualMap.pieces.Count; i++) + { + var piece = visualMap.pieces[i]; + + } + break; + case Orient.Vertical: + var each = visualMap.itemHeight + visualMap.itemGap; + for (int i = 0; i < visualMap.pieces.Count; i++) + { + var piece = visualMap.pieces[i]; + var pos = new Vector3(centerPos.x, centerPos.y - each * i); + UGL.DrawRectangle(vh, pos, halfWid, halfHig, piece.color); + } + break; + } + } + + protected void OnDragVisualMapStart(VisualMap visualMap) + { + if (!visualMap.enable || !visualMap.show || !visualMap.calculable) return; + var inMinRect = visualMap.IsInRangeMinRect(chart.pointerPos, chart.chartRect, chart.theme.visualMap.triangeLen); + var inMaxRect = visualMap.IsInRangeMaxRect(chart.pointerPos, chart.chartRect, chart.theme.visualMap.triangeLen); + if (inMinRect || inMaxRect) + { + if (inMinRect) + { + visualMap.runtimeMinDrag = true; + } + else + { + visualMap.runtimeMaxDrag = true; + } + } + } + + protected void OnDragVisualMap(VisualMap visualMap) + { + if (!visualMap.enable || !visualMap.show || !visualMap.calculable) return; + if (!visualMap.runtimeMinDrag && !visualMap.runtimeMaxDrag) return; + + var value = visualMap.GetValue(chart.pointerPos, chart.chartRect); + if (visualMap.runtimeMinDrag) + { + visualMap.rangeMin = value; + } + else + { + visualMap.rangeMax = value; + } + chart.RefreshChart(); + } + + protected void OnDragVisualMapEnd(VisualMap visualMap) + { + if (!visualMap.enable || !visualMap.show || !visualMap.calculable) return; + if (visualMap.runtimeMinDrag || visualMap.runtimeMaxDrag) + { + chart.RefreshChart(); + visualMap.runtimeMinDrag = false; + visualMap.runtimeMaxDrag = false; + } + } + } } \ No newline at end of file diff --git a/Runtime/Internal/BaseChart.cs b/Runtime/Internal/BaseChart.cs index 8d9dd89d..c02785bd 100644 --- a/Runtime/Internal/BaseChart.cs +++ b/Runtime/Internal/BaseChart.cs @@ -87,6 +87,7 @@ namespace XCharts private Theme m_CheckTheme = 0; protected List m_DrawSeries = new List(); + protected List m_ComponentHandlers = new List(); protected override void InitComponent() { @@ -102,7 +103,12 @@ namespace XCharts m_DrawSeries.Add(new DrawSerieGauge(this)); m_DrawSeries.Add(new DrawSerieLiquid(this)); m_DrawSeries.Add(new DrawSerieRadar(this)); - foreach (var drawSerie in m_DrawSeries) drawSerie.InitComponent(); + foreach (var draw in m_DrawSeries) draw.InitComponent(); + + m_ComponentHandlers.Clear(); + m_ComponentHandlers.Add(new VisualMapHandler(this)); + m_ComponentHandlers.Add(new DataZoomHandler(this)); + foreach (var draw in m_ComponentHandlers) draw.Init(); } protected override void Awake() @@ -154,6 +160,7 @@ namespace XCharts CheckRefreshLabel(); Internal_CheckAnimation(); foreach (var draw in m_DrawSeries) draw.Update(); + foreach (var draw in m_ComponentHandlers) draw.Update(); } internal Painter GetPainter(int index) @@ -771,6 +778,31 @@ namespace XCharts { base.OnPointerDown(eventData); foreach (var drawSerie in m_DrawSeries) drawSerie.OnPointerDown(eventData); + foreach (var handler in m_ComponentHandlers) handler.OnPointerDown(eventData); + } + + public override void OnBeginDrag(PointerEventData eventData) + { + base.OnBeginDrag(eventData); + foreach (var handler in m_ComponentHandlers) handler.OnBeginDrag(eventData); + } + + public override void OnDrag(PointerEventData eventData) + { + base.OnDrag(eventData); + foreach (var handler in m_ComponentHandlers) handler.OnDrag(eventData); + } + + public override void OnEndDrag(PointerEventData eventData) + { + base.OnEndDrag(eventData); + foreach (var handler in m_ComponentHandlers) handler.OnEndDrag(eventData); + } + + public override void OnScroll(PointerEventData eventData) + { + base.OnScroll(eventData); + foreach (var handler in m_ComponentHandlers) handler.OnScroll(eventData); } protected virtual void OnLegendButtonClick(int index, string legendName, bool show) @@ -829,7 +861,8 @@ namespace XCharts DrawBackground(vh); DrawPainterBase(vh); DrawLegend(vh); - foreach (var drawSerie in m_DrawSeries) drawSerie.DrawBase(vh); + foreach (var draw in m_ComponentHandlers) draw.Draw(vh); + foreach (var draw in m_DrawSeries) draw.DrawBase(vh); if (m_OnCustomDrawBaseCallback != null) { m_OnCustomDrawBaseCallback(vh); diff --git a/Runtime/Internal/BaseGraph.cs b/Runtime/Internal/BaseGraph.cs index ccf4c79e..0e581c52 100644 --- a/Runtime/Internal/BaseGraph.cs +++ b/Runtime/Internal/BaseGraph.cs @@ -274,9 +274,7 @@ namespace XCharts raycastTarget = true; if (canvas == null) return; Vector2 local; - var cam = canvas.renderMode == RenderMode.ScreenSpaceOverlay ? null : canvas.worldCamera; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - Input.mousePosition, cam, out local)) + if (!ScreenPointToChartPoint(Input.mousePosition, out local)) { pointerPos = Vector2.zero; } diff --git a/Runtime/Internal/CoordinateChart.cs b/Runtime/Internal/CoordinateChart.cs index bb204130..84fe4244 100644 --- a/Runtime/Internal/CoordinateChart.cs +++ b/Runtime/Internal/CoordinateChart.cs @@ -9,7 +9,6 @@ using UnityEngine; using UnityEngine.UI; using System.Collections.Generic; using System.Text; -using UnityEngine.EventSystems; using XUGL; namespace XCharts @@ -19,14 +18,6 @@ namespace XCharts private static readonly string s_DefaultDataZoom = "datazoom"; private static readonly string s_DefaultAxisName = "name"; - private bool m_DataZoomDrag; - private bool m_DataZoomCoordinateDrag; - private bool m_DataZoomStartDrag; - private bool m_DataZoomEndDrag; - private float m_DataZoomLastStartIndex; - private float m_DataZoomLastEndIndex; - private bool m_CheckDataZoomLabel; - protected override void InitComponent() { base.InitComponent(); @@ -46,8 +37,6 @@ namespace XCharts { CheckMinMaxValue(); CheckRaycastTarget(); - CheckDataZoom(); - CheckVisualMap(); base.Update(); } @@ -91,7 +80,6 @@ namespace XCharts base.DrawPainterBase(vh); DrawCoordinate(vh); DrawDataZoomSlider(vh); - DrawVisualMap(vh); } protected override void DrawBackground(VertexHelper vh) @@ -667,7 +655,7 @@ namespace XCharts } } - private void InitAxisX() + internal void InitAxisX() { for (int i = 0; i < m_XAxes.Count; i++) { @@ -1485,95 +1473,6 @@ namespace XCharts } } - private void CheckDataZoom() - { - if (dataZoom == null || !dataZoom.enable) return; - CheckDataZoomScale(); - CheckDataZoomLabel(); - } - - private bool m_IsSingleTouch; - private Vector2 m_LastSingleTouchPos; - private Vector2 m_LastTouchPos0; - private Vector2 m_LastTouchPos1; - private void CheckDataZoomScale() - { - if (!dataZoom.enable || dataZoom.zoomLock || !dataZoom.supportInside) return; - - if (Input.touchCount == 2) - { - var touch0 = Input.GetTouch(0); - var touch1 = Input.GetTouch(1); - if (touch1.phase == TouchPhase.Began) - { - m_LastTouchPos0 = touch0.position; - m_LastTouchPos1 = touch1.position; - } - else if (touch0.phase == TouchPhase.Moved || touch1.phase == TouchPhase.Moved) - { - var tempPos0 = touch0.position; - var tempPos1 = touch1.position; - var currDist = Vector2.Distance(tempPos0, tempPos1); - var lastDist = Vector2.Distance(m_LastTouchPos0, m_LastTouchPos1); - var delta = (currDist - lastDist); - ScaleDataZoom(delta / dataZoom.scrollSensitivity); - m_LastTouchPos0 = tempPos0; - m_LastTouchPos1 = tempPos1; - } - } - } - - private void CheckDataZoomLabel() - { - if (dataZoom.supportSlider && dataZoom.showDetail) - { - Vector2 local; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - Input.mousePosition, canvas.worldCamera, out local)) - { - foreach (var datazoom in m_DataZooms) datazoom.SetLabelActive(false); - return; - } - foreach (var dataZoom in m_DataZooms) - { - if (dataZoom.IsInSelectedZoom(local) - || dataZoom.IsInStartZoom(local) - || dataZoom.IsInEndZoom(local)) - { - dataZoom.SetLabelActive(true); - RefreshDataZoomLabel(); - } - else - { - dataZoom.SetLabelActive(false); - } - } - } - if (m_CheckDataZoomLabel) - { - m_CheckDataZoomLabel = false; - var xAxis = m_XAxes[dataZoom.xAxisIndexs[0]]; - var startIndex = (int)((xAxis.data.Count - 1) * dataZoom.start / 100); - var endIndex = (int)((xAxis.data.Count - 1) * dataZoom.end / 100); - if (m_DataZoomLastStartIndex != startIndex || m_DataZoomLastEndIndex != endIndex) - { - m_DataZoomLastStartIndex = startIndex; - m_DataZoomLastEndIndex = endIndex; - if (xAxis.data.Count > 0) - { - dataZoom.SetStartLabelText(xAxis.data[startIndex]); - dataZoom.SetEndLabelText(xAxis.data[endIndex]); - } - InitAxisX(); - } - var start = dataZoom.runtimeX + dataZoom.runtimeWidth * dataZoom.start / 100; - var end = dataZoom.runtimeX + dataZoom.runtimeWidth * dataZoom.end / 100; - var hig = dataZoom.runtimeHeight; - dataZoom.UpdateStartLabelPosition(new Vector3(start - 10, chartY + dataZoom.bottom + hig / 2)); - dataZoom.UpdateEndLabelPosition(new Vector3(end + 10, chartY + dataZoom.bottom + hig / 2)); - } - } - public bool IsAnyYAxisIsCategory() { foreach (var yAxis in m_YAxes) @@ -1733,236 +1632,8 @@ namespace XCharts } } - public override void OnBeginDrag(PointerEventData eventData) - { - base.OnBeginDrag(eventData); - if (Input.touchCount > 1) return; - Vector2 pos; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - eventData.position, canvas.worldCamera, out pos)) - { - return; - } - var grid = GetDataZoomGridOrDefault(dataZoom); - if (dataZoom.supportInside) - { - if (IsInGrid(grid, pos)) - { - m_DataZoomCoordinateDrag = true; - } - } - if (dataZoom.supportSlider) - { - if (dataZoom.IsInStartZoom(pos)) - { - m_DataZoomStartDrag = true; - } - else if (dataZoom.IsInEndZoom(pos)) - { - m_DataZoomEndDrag = true; - } - else if (dataZoom.IsInSelectedZoom(pos)) - { - m_DataZoomDrag = true; - } - } - OnDragVisualMapStart(); - } - public override void OnDrag(PointerEventData eventData) - { - base.OnDrag(eventData); - if (Input.touchCount > 1) return; - var grid = GetDataZoomGridOrDefault(dataZoom); - float deltaX = eventData.delta.x; - float deltaPercent = deltaX / grid.runtimeWidth * 100; - OnDragInside(deltaPercent); - OnDragSlider(deltaPercent); - OnDragVisualMap(); - } - private void OnDragInside(float deltaPercent) - { - if (Input.touchCount > 1) return; - if (!dataZoom.supportInside) return; - if (!m_DataZoomCoordinateDrag) return; - var diff = dataZoom.end - dataZoom.start; - if (deltaPercent > 0) - { - dataZoom.start -= deltaPercent; - dataZoom.end = dataZoom.start + diff; - } - else - { - dataZoom.end += -deltaPercent; - dataZoom.start = dataZoom.end - diff; - } - RefreshDataZoomLabel(); - RefreshChart(); - } - - private void OnDragSlider(float deltaPercent) - { - if (Input.touchCount > 1) return; - if (!dataZoom.supportSlider) return; - if (m_DataZoomStartDrag) - { - dataZoom.start += deltaPercent; - if (dataZoom.start > dataZoom.end) - { - dataZoom.start = dataZoom.end; - m_DataZoomEndDrag = true; - m_DataZoomStartDrag = false; - } - if (dataZoom.realtime) - { - RefreshDataZoomLabel(); - RefreshChart(); - } - } - else if (m_DataZoomEndDrag) - { - dataZoom.end += deltaPercent; - if (dataZoom.end < dataZoom.start) - { - dataZoom.end = dataZoom.start; - m_DataZoomStartDrag = true; - m_DataZoomEndDrag = false; - } - if (dataZoom.realtime) - { - RefreshDataZoomLabel(); - RefreshChart(); - } - } - else if (m_DataZoomDrag) - { - if (deltaPercent > 0) - { - if (dataZoom.end + deltaPercent > 100) - { - deltaPercent = 100 - dataZoom.end; - } - } - else - { - if (dataZoom.start + deltaPercent < 0) - { - deltaPercent = -dataZoom.start; - } - } - dataZoom.start += deltaPercent; - dataZoom.end += deltaPercent; - if (dataZoom.realtime) - { - RefreshDataZoomLabel(); - RefreshChart(); - } - } - } - - private void RefreshDataZoomLabel() - { - m_CheckDataZoomLabel = true; - } - - public override void OnEndDrag(PointerEventData eventData) - { - base.OnEndDrag(eventData); - if (m_DataZoomDrag || m_DataZoomStartDrag || m_DataZoomEndDrag || m_DataZoomCoordinateDrag) - { - RefreshChart(); - } - m_DataZoomDrag = false; - m_DataZoomCoordinateDrag = false; - m_DataZoomStartDrag = false; - m_DataZoomEndDrag = false; - OnDragVisualMapEnd(); - } - - public override void OnPointerDown(PointerEventData eventData) - { - base.OnPointerDown(eventData); - if (Input.touchCount > 1) return; - Vector2 localPos; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - eventData.position, canvas.worldCamera, out localPos)) - { - return; - } - var grid = GetDataZoomGridOrDefault(dataZoom); - if (dataZoom.IsInStartZoom(localPos) || - dataZoom.IsInEndZoom(localPos)) - { - return; - } - if (dataZoom.IsInZoom(localPos) - && !dataZoom.IsInSelectedZoom(localPos)) - { - var pointerX = localPos.x; - var selectWidth = grid.runtimeWidth * (dataZoom.end - dataZoom.start) / 100; - var startX = pointerX - selectWidth / 2; - var endX = pointerX + selectWidth / 2; - if (startX < grid.runtimeX) - { - startX = grid.runtimeX; - endX = grid.runtimeX + selectWidth; - } - else if (endX > grid.runtimeX + grid.runtimeWidth) - { - endX = grid.runtimeX + grid.runtimeWidth; - startX = grid.runtimeX + grid.runtimeWidth - selectWidth; - } - dataZoom.start = (startX - grid.runtimeX) / grid.runtimeWidth * 100; - dataZoom.end = (endX - grid.runtimeX) / grid.runtimeWidth * 100; - RefreshDataZoomLabel(); - RefreshChart(); - } - } - - public override void OnScroll(PointerEventData eventData) - { - base.OnScroll(eventData); - if (Input.touchCount > 1) return; - if (!dataZoom.enable || dataZoom.zoomLock) return; - Vector2 pos; - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - eventData.position, canvas.worldCamera, out pos)) - { - return; - } - var grid = GetDataZoomGridOrDefault(dataZoom); - if (!IsInGrid(grid, pos) && !dataZoom.IsInSelectedZoom(pos)) - { - return; - } - ScaleDataZoom(eventData.scrollDelta.y * dataZoom.scrollSensitivity); - } - - private void ScaleDataZoom(float delta) - { - var grid = GetDataZoomGridOrDefault(dataZoom); - float deltaPercent = Mathf.Abs(delta / grid.runtimeWidth * 100); - if (delta > 0) - { - if (dataZoom.end <= dataZoom.start) return; - dataZoom.end -= deltaPercent; - dataZoom.start += deltaPercent; - if (dataZoom.end <= dataZoom.start) - { - dataZoom.end = dataZoom.start; - } - } - else - { - dataZoom.end += deltaPercent; - dataZoom.start -= deltaPercent; - if (dataZoom.end > 100) dataZoom.end = 100; - if (dataZoom.start < 0) dataZoom.start = 0; - } - RefreshDataZoomLabel(); - RefreshChart(); - } public void Internal_CheckClipAndDrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4, Color32 color, bool clip, Grid grid) diff --git a/Runtime/Internal/CoordinateChart_DrawHeatmap.cs b/Runtime/Internal/CoordinateChart_DrawHeatmap.cs index a5f0ce60..e1a81f4a 100644 --- a/Runtime/Internal/CoordinateChart_DrawHeatmap.cs +++ b/Runtime/Internal/CoordinateChart_DrawHeatmap.cs @@ -13,108 +13,6 @@ namespace XCharts { public partial class CoordinateChart { - private bool m_VisualMapMinDrag; - private bool m_VisualMapMaxDrag; - - protected void CheckVisualMap() - { - if (visualMap == null || !visualMap.enable || !visualMap.show) return; - Vector2 local; - if (canvas == null) return; - - if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, - Input.mousePosition, canvas.worldCamera, out local)) - { - if (visualMap.runtimeSelectedIndex >= 0) - { - visualMap.runtimeSelectedIndex = -1; - RefreshChart(); - } - return; - } - if (local.x < chartX || local.x > chartX + chartWidth || - local.y < chartY || local.y > chartY + chartHeight || - !visualMap.IsInRangeRect(local, chartRect)) - { - if (visualMap.runtimeSelectedIndex >= 0) - { - visualMap.runtimeSelectedIndex = -1; - RefreshChart(); - } - return; - } - var pos1 = Vector3.zero; - var pos2 = Vector3.zero; - var halfHig = visualMap.itemHeight / 2; - var centerPos = chartPosition + visualMap.location.GetPosition(chartWidth, chartHeight); - var selectedIndex = -1; - var value = 0f; - switch (visualMap.orient) - { - case Orient.Horizonal: - pos1 = centerPos + Vector3.left * halfHig; - pos2 = centerPos + Vector3.right * halfHig; - value = visualMap.min + (local.x - pos1.x) / (pos2.x - pos1.x) * (visualMap.max - visualMap.min); - selectedIndex = visualMap.GetIndex(value); - break; - case Orient.Vertical: - pos1 = centerPos + Vector3.down * halfHig; - pos2 = centerPos + Vector3.up * halfHig; - value = visualMap.min + (local.y - pos1.y) / (pos2.y - pos1.y) * (visualMap.max - visualMap.min); - selectedIndex = visualMap.GetIndex(value); - break; - } - visualMap.runtimeSelectedValue = value; - visualMap.runtimeSelectedIndex = selectedIndex; - RefreshChart(); - } - - protected void OnDragVisualMapStart() - { - if (!visualMap.enable || !visualMap.show || !visualMap.calculable) return; - var inMinRect = visualMap.IsInRangeMinRect(pointerPos, chartRect, m_Theme.visualMap.triangeLen); - var inMaxRect = visualMap.IsInRangeMaxRect(pointerPos, chartRect, m_Theme.visualMap.triangeLen); - if (inMinRect || inMaxRect) - { - if (inMinRect) - { - m_VisualMapMinDrag = true; - } - else - { - m_VisualMapMaxDrag = true; - } - } - } - - protected void OnDragVisualMap() - { - if (!visualMap.enable || !visualMap.show || !visualMap.calculable) return; - if (!m_VisualMapMinDrag && !m_VisualMapMaxDrag) return; - - var value = visualMap.GetValue(pointerPos, chartRect); - if (m_VisualMapMinDrag) - { - visualMap.rangeMin = value; - } - else - { - visualMap.rangeMax = value; - } - RefreshChart(); - } - - protected void OnDragVisualMapEnd() - { - if (!visualMap.enable || !visualMap.show || !visualMap.calculable) return; - if (m_VisualMapMinDrag || m_VisualMapMaxDrag) - { - RefreshChart(); - m_VisualMapMinDrag = false; - m_VisualMapMaxDrag = false; - } - } - protected void DrawHeatmapSerie(VertexHelper vh, int colorIndex, Serie serie) { if (serie.animation.HasFadeOut()) return; @@ -212,199 +110,5 @@ namespace XCharts RefreshPainter(serie); } } - - protected void DrawVisualMap(VertexHelper vh) - { - if (!visualMap.enable || !visualMap.show) return; - var centerPos = chartPosition + visualMap.location.GetPosition(chartWidth, chartHeight); - - var pos1 = Vector3.zero; - var pos2 = Vector3.zero; - var dir = Vector3.zero; - var halfWid = visualMap.itemWidth / 2; - var halfHig = visualMap.itemHeight / 2; - var xRadius = 0f; - var yRadius = 0f; - var splitNum = visualMap.runtimeInRange.Count; - var splitWid = visualMap.itemHeight / (splitNum - 1); - var isVertical = false; - var colors = visualMap.runtimeInRange; - var triangeLen = m_Theme.visualMap.triangeLen; - switch (visualMap.orient) - { - case Orient.Horizonal: - pos1 = centerPos + Vector3.left * halfHig; - pos2 = centerPos + Vector3.right * halfHig; - dir = Vector3.right; - xRadius = splitWid / 2; - yRadius = halfWid; - isVertical = false; - if (visualMap.calculable) - { - var p0 = pos1 + Vector3.right * visualMap.runtimeRangeMinHeight; - var p1 = p0 + Vector3.up * halfWid; - var p2 = p0 + Vector3.up * (halfWid + triangeLen); - var p3 = p2 + Vector3.left * triangeLen; - var color = visualMap.GetColor(visualMap.rangeMin); - UGL.DrawTriangle(vh, p1, p2, p3, color); - p0 = pos1 + Vector3.right * visualMap.runtimeRangeMaxHeight; - p1 = p0 + Vector3.up * halfWid; - p2 = p0 + Vector3.up * (halfWid + triangeLen); - p3 = p2 + Vector3.right * triangeLen; - color = visualMap.GetColor(visualMap.rangeMax); - UGL.DrawTriangle(vh, p1, p2, p3, color); - } - break; - case Orient.Vertical: - pos1 = centerPos + Vector3.down * halfHig; - pos2 = centerPos + Vector3.up * halfHig; - dir = Vector3.up; - xRadius = halfWid; - yRadius = splitWid / 2; - isVertical = true; - if (visualMap.calculable) - { - var p0 = pos1 + Vector3.up * visualMap.runtimeRangeMinHeight; - var p1 = p0 + Vector3.right * halfWid; - var p2 = p0 + Vector3.right * (halfWid + triangeLen); - var p3 = p2 + Vector3.down * triangeLen; - var color = visualMap.GetColor(visualMap.rangeMin); - UGL.DrawTriangle(vh, p1, p2, p3, color); - p0 = pos1 + Vector3.up * visualMap.runtimeRangeMaxHeight; - p1 = p0 + Vector3.right * halfWid; - p2 = p0 + Vector3.right * (halfWid + triangeLen); - p3 = p2 + Vector3.up * triangeLen; - color = visualMap.GetColor(visualMap.rangeMax); - UGL.DrawTriangle(vh, p1, p2, p3, color); - } - break; - } - if (visualMap.calculable && (visualMap.rangeMin > visualMap.min - || visualMap.rangeMax < visualMap.max)) - { - var rangeMin = visualMap.rangeMin; - var rangeMax = visualMap.rangeMax; - var diff = (visualMap.max - visualMap.min) / (splitNum - 1); - for (int i = 1; i < splitNum; i++) - { - var splitMin = visualMap.min + (i - 1) * diff; - var splitMax = splitMin + diff; - if (rangeMin > splitMax || rangeMax < splitMin) - { - continue; - } - else if (rangeMin <= splitMin && rangeMax >= splitMax) - { - var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid; - var startColor = colors[i - 1]; - var toColor = visualMap.IsPiecewise() ? startColor : colors[i]; - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical); - } - else if (rangeMin > splitMin && rangeMax >= splitMax) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - var splitMaxPos = pos1 + dir * i * splitWid; - var splitPos = p0 + (splitMaxPos - p0) / 2; - var startColor = visualMap.GetColor(visualMap.rangeMin); - var toColor = visualMap.IsPiecewise() ? startColor : colors[i]; - var yRadius1 = Vector3.Distance(p0, splitMaxPos) / 2; - if (visualMap.orient == Orient.Vertical) - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); - else - UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); - } - else if (rangeMax < splitMax && rangeMin <= splitMin) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - var splitMinPos = pos1 + dir * (i - 1) * splitWid; - var splitPos = splitMinPos + (p0 - splitMinPos) / 2; - var startColor = colors[i - 1]; - var toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(visualMap.rangeMax); - var yRadius1 = Vector3.Distance(p0, splitMinPos) / 2; - if (visualMap.orient == Orient.Vertical) - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); - else - UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); - } - else - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - var splitPos = (p0 + p1) / 2; - var startColor = visualMap.GetColor(visualMap.rangeMin); - var toColor = visualMap.GetColor(visualMap.rangeMax); - var yRadius1 = Vector3.Distance(p0, p1) / 2; - if (visualMap.orient == Orient.Vertical) - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical); - else - UGL.DrawRectangle(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical); - } - } - } - else - { - for (int i = 1; i < splitNum; i++) - { - var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid; - var startColor = colors[i - 1]; - var toColor = visualMap.IsPiecewise() ? startColor : colors[i]; - UGL.DrawRectangle(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical); - } - } - - if (visualMap.rangeMin > visualMap.min) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - UGL.DrawRectangle(vh, pos1, p0, visualMap.itemWidth / 2, m_Theme.visualMap.backgroundColor); - } - if (visualMap.rangeMax < visualMap.max) - { - var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - UGL.DrawRectangle(vh, p1, pos2, visualMap.itemWidth / 2, m_Theme.visualMap.backgroundColor); - } - - if (visualMap.hoverLink) - { - if (visualMap.runtimeSelectedIndex >= 0) - { - var p0 = pos1 + dir * visualMap.runtimeRangeMinHeight; - var p1 = pos1 + dir * visualMap.runtimeRangeMaxHeight; - - if (visualMap.orient == Orient.Vertical) - { - var p2 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y + (triangeLen / 2), p0.y, p1.y)); - var p3 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y - (triangeLen / 2), p0.y, p1.y)); - var p4 = new Vector3(centerPos.x + halfWid + triangeLen / 2, pointerPos.y); - UGL.DrawTriangle(vh, p2, p3, p4, colors[visualMap.runtimeSelectedIndex]); - } - else - { - var p2 = new Vector3(Mathf.Clamp(pointerPos.x + (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); - var p3 = new Vector3(Mathf.Clamp(pointerPos.x - (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); - var p4 = new Vector3(pointerPos.x, centerPos.y + halfWid + triangeLen / 2); - UGL.DrawTriangle(vh, p2, p3, p4, colors[visualMap.runtimeSelectedIndex]); - } - } - else if (tooltip.show && tooltip.runtimeXValues[0] >= 0 && tooltip.runtimeYValues[0] >= 0) - { - // var p0 = pos1 + dir * m_VisualMap.rangeMinHeight; - // var p1 = pos1 + dir * m_VisualMap.rangeMaxHeight; - // if (m_VisualMap.orient == Orient.Vertical) - // { - // var p2 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y + (triangeLen / 2), p0.y, p1.y)); - // var p3 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y - (triangeLen / 2), p0.y, p1.y)); - // var p4 = new Vector3(centerPos.x + halfWid + triangeLen / 2, pointerPos.y); - // UGL.DrawTriangle(vh, p2, p3, p4, colors[m_VisualMap.rtSelectedIndex]); - // } - // else - // { - // var p2 = new Vector3(Mathf.Clamp(pointerPos.x + (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); - // var p3 = new Vector3(Mathf.Clamp(pointerPos.x - (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid); - // var p4 = new Vector3(pointerPos.x, centerPos.y + halfWid + triangeLen / 2); - // UGL.DrawTriangle(vh, p2, p3, p4, colors[m_VisualMap.rtSelectedIndex]); - // } - } - } - } } } \ No newline at end of file diff --git a/Runtime/Internal/Interface/IComponentHandler.cs b/Runtime/Internal/Interface/IComponentHandler.cs new file mode 100644 index 00000000..0210f3fb --- /dev/null +++ b/Runtime/Internal/Interface/IComponentHandler.cs @@ -0,0 +1,25 @@ +/************************************************/ +/* */ +/* Copyright (c) 2018 - 2021 monitor1394 */ +/* https://github.com/monitor1394 */ +/* */ +/************************************************/ + +using UnityEngine.EventSystems; +using UnityEngine.UI; + +namespace XCharts +{ + public interface IComponentHandler + { + void Init(); + void Update(); + void Draw(VertexHelper vh); + void OnDrag(PointerEventData eventData); + void OnBeginDrag(PointerEventData eventData); + void OnEndDrag(PointerEventData eventData); + void OnPointerDown(PointerEventData eventData); + void OnScroll(PointerEventData eventData); + + } +} \ No newline at end of file diff --git a/Runtime/Internal/Interface/IComponentHandler.cs.meta b/Runtime/Internal/Interface/IComponentHandler.cs.meta new file mode 100644 index 00000000..5b93960d --- /dev/null +++ b/Runtime/Internal/Interface/IComponentHandler.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 062750f03b8ce4ef8a8ae46721a7d884 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: