* UILineChart: 增加了数据沿Y轴变化时鼠标移动到数据点时显示数据点标签

This commit is contained in:
Sunny 2023-07-02 22:15:03 +08:00
parent 43d3369365
commit b49d082a7f
2 changed files with 57 additions and 14 deletions

View File

@ -45,7 +45,8 @@
* 2023-05-12: V3.3.6 线 * 2023-05-12: V3.3.6 线
* 2023-05-14: V3.3.6 DrawString函数 * 2023-05-14: V3.3.6 DrawString函数
* 2023-06-06: V3.3.7 X轴文字重叠问题 * 2023-06-06: V3.3.7 X轴文字重叠问题
* 2024-07-02: V3.3.9 PointFormat * 2023-07-02: V3.3.9 PointFormat
* 2023-07-02: V3.3.9 沿Y轴变化时鼠标移动到数据点时显示数据点标签
******************************************************************************/ ******************************************************************************/
using System; using System;
@ -806,6 +807,7 @@ namespace Sunny.UI
{ {
if (series.DataCount == 0) continue; if (series.DataCount == 0) continue;
if (!series.Visible) continue; if (!series.Visible) continue;
if (series.GetNearestPoint(e.Location, 4, out double x, out double y, out int index)) if (series.GetNearestPoint(e.Location, 4, out double x, out double y, out int index))
{ {
UILineSelectPoint point = new UILineSelectPoint(); UILineSelectPoint point = new UILineSelectPoint();

View File

@ -31,6 +31,12 @@ using System.Linq;
namespace Sunny.UI namespace Sunny.UI
{ {
public enum UISeriesDataOrder
{
X,
Y
}
public sealed class UILineOption : UIOption, IDisposable public sealed class UILineOption : UIOption, IDisposable
{ {
public bool ShowZeroLine { get; set; } = true; public bool ShowZeroLine { get; set; } = true;
@ -543,6 +549,8 @@ namespace Sunny.UI
public int DataCount => XData.Count; public int DataCount => XData.Count;
public UISeriesDataOrder Order = UISeriesDataOrder.X;
public bool GetNearestPoint(Point p, int offset, out double x, out double y, out int index) public bool GetNearestPoint(Point p, int offset, out double x, out double y, out int index)
{ {
x = 0; x = 0;
@ -550,7 +558,12 @@ namespace Sunny.UI
index = -1; index = -1;
if (PointsX.Count == 0) return false; if (PointsX.Count == 0) return false;
index = PointsX.BinarySearchNearIndex(p.X); if (Order == UISeriesDataOrder.X)
index = BinarySearchNearIndex(PointsX, p.X);
if (Order == UISeriesDataOrder.Y)
index = BinarySearchNearIndex(PointsY, p.Y);
if (index == -1) return false;
if (p.X >= PointsX[index] - offset && p.X <= PointsX[index] + offset && if (p.X >= PointsX[index] - offset && p.X <= PointsX[index] + offset &&
p.Y >= PointsY[index] - offset && p.Y <= PointsY[index] + offset) p.Y >= PointsY[index] - offset && p.Y <= PointsY[index] + offset)
{ {
@ -562,22 +575,50 @@ namespace Sunny.UI
return false; return false;
} }
public bool GetNearestPointX(Point p, int offset, out double x, out double y, out int index) /// <summary>
/// 二分查找与最近值序号
/// </summary>
/// <param name="list">列表</param>
/// <param name="target">值</param>
/// <returns>最近值序号</returns>
internal int BinarySearchNearIndex(List<double> list, double target)
{ {
x = 0; if (list.Count == 0) return -1;
y = 0; if (list.Count == 1) return 0;
index = -1; int i = 0, j = list.Count - 1;
if (PointsX.Count == 0) return false;
index = PointsX.BinarySearchNearIndex(p.X); if (list[0] < list[list.Count - 1])
if (p.X >= PointsX[index] - offset && p.X <= PointsX[index] + offset)
{ {
x = XData[index]; if (target < list[0]) return 0;
y = YData[index]; if (target > list[list.Count - 1]) return list.Count - 1;
return true;
while (i <= j)
{
var mid = (i + j) / 2;
if (target > list[mid]) i = mid + 1;
if (target < list[mid]) j = mid - 1;
if (target.Equals(list[mid])) return mid;
} }
return false; if (i < 1) return i;
return target - list[i - 1] > list[i] - target ? i : i - 1;
}
else
{
if (target > list[0]) return 0;
if (target < list[list.Count - 1]) return list.Count - 1;
while (i <= j)
{
var mid = (i + j) / 2;
if (target < list[mid]) i = mid + 1;
if (target > list[mid]) j = mid - 1;
if (target.Equals(list[mid])) return mid;
}
if (i < 1) return i;
return target - list[i - 1] < list[i] - target ? i : i - 1;
}
} }
public void Clear() public void Clear()