MSChart鼠标移动时如何在Y2轴上实时显示当前Y值
实现方案
整体实现逻辑如下:
- 声明类级别的全局变量存储当前鼠标位置对应的Y值
- 在原有的MouseMove事件中补充Y值获取逻辑,同步更新全局变量并触发控件重绘
- 订阅Chart控件的PostPaint绘制事件,将当前Y值实时绘制到Y2轴旁的对应位置
具体实现步骤
1. 预先配置Y2轴属性
在窗体初始化或Chart控件初始化逻辑中添加如下代码,预留标签显示空间:
// 启用次要Y轴(Y2) chart1.ChartAreas[0].AxisY2.Enabled = AxisEnabled.True; // 隐藏Y2轴默认刻度和标签,仅保留自定义绘制内容 chart1.ChartAreas[0].AxisY2.LabelStyle.Enabled = false; chart1.ChartAreas[0].AxisY2.MajorTickMark.Enabled = false;
2. 声明全局存储变量
在窗体类中声明变量存储当前有效Y值:
// 存储当前鼠标对应的Y值,默认设为无效值 private double currentYVal = double.NaN;
3. 修改原MouseMove事件代码
在原有逻辑基础上补充Y值获取逻辑:
private void chart1_MouseMove(object sender, MouseEventArgs e) { // 原有Tooltip和光标逻辑保持不变 string info = "Value: " + "#VAL{N2}" + "\n" + "Average: " + "#AVG{N2}" + "\n" + "Plus Bas: " + "#MIN{N2}" + "\n" + "Plus Haut: " + "#MAX{N2}" + "\n" + "First: " + "#FIRST{N2}" + "\n" + "Last: " + "#LAST{N2}"; chart1.Series[0].ToolTip = "Series name..." + "\n" + info; chart1.Series[1].ToolTip = "Series name2..." + "\n" + info; chart1.Series[2].ToolTip = "Series name3..." + "\n" + info; System.Drawing.Point p = new System.Drawing.Point(e.X, e.Y); chart1.ChartAreas[0].CursorX.Interval = 0; chart1.ChartAreas[0].CursorX.SetCursorPixelPosition(p, true); chart1.ChartAreas[0].CursorY.SetCursorPixelPosition(p, true); // 新增:获取当前位置的Y轴数值 HitTestResult hitResult = chart1.HitTest(e.X, e.Y); if (hitResult.ChartArea != null) { // 将鼠标像素坐标转换为Y轴实际数值,若数据绑定到Y2轴则此处换为AxisY2 currentYVal = chart1.ChartAreas[0].AxisY.PixelPositionToValue(e.Y); chart1.Invalidate(); } else { // 鼠标离开绘图区域时清空数值 currentYVal = double.NaN; chart1.Invalidate(); } }
4. 实现PostPaint绘制逻辑
订阅Chart控件的PostPaint事件,在Y2轴旁绘制实时数值:
private void chart1_PostPaint(object sender, ChartPaintEventArgs e) { if (double.IsNaN(currentYVal)) return; ChartArea targetArea = chart1.ChartAreas[0]; // 将Y值转换为对应像素坐标,实现和光标Y位置对齐 float yPixel = (float)targetArea.AxisY.ValueToPixelPosition(currentYVal); // 标签X坐标设置在Y2轴右侧,可调整偏移量适配界面 float xPixel = (float)targetArea.AxisY2.Position.ToRectangleF().Right + 3; // 格式化显示文本,可自定义小数位数 string showText = currentYVal.ToString("F2"); Font textFont = new Font("宋体", 9f); SizeF textSize = e.Graphics.MeasureString(showText, textFont); // 绘制白色背景避免文字和网格重叠 e.Graphics.FillRectangle(Brushes.White, xPixel, yPixel - textSize.Height / 2, textSize.Width, textSize.Height); // 绘制数值文本,可自定义颜色 e.Graphics.DrawString(showText, textFont, Brushes.Red, xPixel, yPixel - textSize.Height / 2); }
自定义调整说明
- 如果数据绑定到Y2轴,将代码中所有用到
AxisY的地方替换为AxisY2即可 - 标签的字体、颜色、偏移量都可以根据界面需求自行修改
- 如需展示多个系列的对应Y值,可以分别存储每个系列的当前Y值,依次排列绘制即可
内容的提问来源于stack exchange,提问作者Cranshow
相关产品推荐
相关产品推荐

