* UILineChart: 增加了数据沿Y轴变化时鼠标移动到数据点时显示数据点标签
This commit is contained in:
parent
43d3369365
commit
b49d082a7f
@ -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();
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user