C# 标准绘图控件 chart 多 Y 值的编程应用
- 1、前言
- 2、声明标准绘图控件 chart 命名空间
- 3、使用绘图控件 chart
- 3.1、在窗体中拖入绘图控件 chart ,拖入绘图控件 chart 最简单实用。
- 3.2、在语句中声明加入,但要将 控件和其组件加入窗体或其它容器很麻烦,不如使用上面拖入使用。
- 4、使用标准绘图控件 chart 绘制多曲线,应用多 Y 值在标签中显示数据其它属性
- 4.1、绘图要求
- 4.1.1 绘制测区平面坐标
- 4.1.2 绘制时间和水深的剖面图
- 4.1.3 绘制起点距和水深的剖面图
- 4.2、绘图控件 chart 剖面图的代码实现
- 4.2.1、获取图幅范围大小等必要参数
- 4.2.2、初始化绘图控件 chart
- 4.2.3、绘图控件 chart 加载数据显示图形
- 4.3、绘图控件 chart 上鼠标移动的关注点的代码实现
- 4.3.1 起点距⁓水深 剖面图上鼠标移动的关注点显示
- 4.3.2 时间⁓水深 剖面图上鼠标移动的关注点显示
1、前言
最近开发一个小软件,涉及到曲线绘图,绘制多条曲线,并显示标签,以及数据点的其它信息。不想用其它增强性能的控件,还是想研究微软原始的标准绘图控件 chart。在网上查了很多资料没有这方面的详细的正确知识,要么是代码语法结构错误,要么就是虚假的张冠李戴,浪费时间。通过不懈的摸索和测试,终于找到了正解。其实很简单,只是微软网站关于控件的指导太模糊,示例代码太简单,没有详细注解。
数据为超声波测深仪和 Hypack 软件测量的输出原始数据,数据存在多面性,有平面坐标和水深关系、有时间和水深的关系,水深有常规测量和定标测量(按间距或时间差测量水深的事件)。为了展示各种关系曲线以一目了然,就涉及到绘图控件 chart 的多 Y 值应用。
- 倾心奉献展示源代码,请不要吝啬点赞和收藏!!!
2、声明标准绘图控件 chart 命名空间
using System.Windows.Forms.DataVisualization.Charting;
3、使用绘图控件 chart
3.1、在窗体中拖入绘图控件 chart ,拖入绘图控件 chart 最简单实用。
3.2、在语句中声明加入,但要将 控件和其组件加入窗体或其它容器很麻烦,不如使用上面拖入使用。
Chart chart = new Chart();
this.Controls.Add(this.chart);
4、使用标准绘图控件 chart 绘制多曲线,应用多 Y 值在标签中显示数据其它属性
4.1、绘图要求
4.1.1 绘制测区平面坐标
4.1.2 绘制时间和水深的剖面图
绘制时间和水深的剖面图,线型为折线,数据点 X 为时间,Y1 为水深(绘制在横坐标以下),并同时显示时间和定标水深的剖面图,并标注定标序号,Y2 为定标序号。
4.1.3 绘制起点距和水深的剖面图
绘制起点距和水深的剖面图,线型为折线,数据点 X 为起点距,Y1为水深(绘制在横坐标以下),并同时显示起点距和定标水深的剖面图,并标注定标序号,Y2 为定标序号。
4.2、绘图控件 chart 剖面图的代码实现
4.2.1、获取图幅范围大小等必要参数
double MaxWaterDepth = 0; double MaxDistance = 0; double MinDistance = 1000000;
MaxSecond = 0; MinSecond = 1000000;
for (int i = 0; i < POS.GetLength(0); i++)
{
double Second = POS[i, 0];
double X = Common.Round46(POS[i, 4]);
double Y = Common.Round46(POS[i, 5]);
POSWaterDepth[i] = Convert.ToDouble(Common.Round46(POS[i, 6], "H"));
double POSPointDistance = Distance(StartDotCoordEast, StartDotCoordNorth, X, Y);//点距到点距
double MeasureLine = DegreesToRadian(AzimuthCalc(StartDotCoordEast, StartDotCoordNorth, X, Y));//测线方位角
double POSOnlineDistance = Cos(MeasureLine - PlannedLineAzimuth) * POSPointDistance;//在线距
MaxWaterDepth = Max(MaxWaterDepth, POSWaterDepth[i]);//最大水深
MaxDistance = Max(MaxDistance, POSOnlineDistance);//最大在线距离
MinDistance = Min(MinDistance, POSOnlineDistance);//最小在线距离
MaxSecond = Max(MaxSecond, Second);//最大秒数
MinSecond = Min(MinSecond, Second);//最小秒数
}
double Xwide = Math.Abs(EndDotCoordEast - StartDotCoordEast);//X宽
double Ywide = Math.Abs(EndDotCoordNorth - StartDotCoordNorth);//Y宽
double Xcenter = (StartDotCoordEast + EndDotCoordEast) / 2;//X中心
double Ycenter = (StartDotCoordNorth + EndDotCoordNorth) / 2;//Y中心
double XYwideMax = Math.Max(Xwide, Ywide);//最大图幅XY宽
double Inter = Math.Pow(10, ((int)XYwideMax).ToString().Length - 1);//图幅位数,坐标间隔
XMin = Math.Round((Xcenter - XYwideMax / 2) / 10, 0) * 10 - 50;
YMin = Math.Round((Ycenter - XYwideMax / 2) / 10, 0) * 10 - 50;
XMax = Math.Round((Xcenter + XYwideMax / 2) / 10, 0) * 10 + 50;
YMax = Math.Round((Ycenter + XYwideMax / 2) / 10, 0) * 10 + 50;
4.2.2、初始化绘图控件 chart
chart1.Series.Clear();// 清除平面图,Chart控件中所有系列
chart2.Series.Clear();// 清除起点距⁓水深 剖面图 Chart控件中所有系列
chart3.Series.Clear();// 清除时间⁓水深 剖面图 Chart控件中所有系列
#region "平面图 初始化"
//区域边框实线
chart1.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
// 设置X和Y轴的标签
chart1.ChartAreas[0].AxisX.Title = "东向坐标 X (m)";
chart1.ChartAreas[0].AxisY.Title = "北向坐标 Y (m)";
// X坐标范围最大最小
chart1.ChartAreas[0].AxisX.Minimum = XMin;
chart1.ChartAreas[0].AxisX.Maximum = XMax;
// X坐标范围最大最小
chart1.ChartAreas[0].AxisY.Minimum = YMin;
chart1.ChartAreas[0].AxisY.Maximum = YMax;
// 坐标轴间隔
chart1.ChartAreas[0].AxisX.Interval = Inter / 2;
chart1.ChartAreas[0].AxisY.Interval = Inter / 2;
// 设置 X 坐标轴和 Y 坐标轴刻度的格式
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "0";
chart1.ChartAreas[0].AxisY.LabelStyle.Format = "0";
// 显示主坐标网格线
chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart1.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
// 主坐标网格线间隔
chart1.ChartAreas[0].AxisX.MajorGrid.Interval = Inter;
chart1.ChartAreas[0].AxisY.MajorGrid.Interval = Inter;
// 显示主坐标网格 X轴和Y轴的刻度
chart1.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
chart1.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
// 设置主网格线为点
chart1.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart1.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
// 设置主网格线颜色
chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
// 显示次坐标网格线
chart1.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart1.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
// 次坐标网格线间隔
chart1.ChartAreas[0].AxisX.MinorGrid.Interval = Inter / 10;
chart1.ChartAreas[0].AxisY.MinorGrid.Interval = Inter / 10;
// 显示次坐标网格 X轴和Y轴的刻度
chart1.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart1.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
// 设置次网格线为点
chart1.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
chart1.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
// 设置次网格线颜色
chart1.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.LightGray;
chart1.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray;
//缩放状态禁止显示滚动条
chart1.ChartAreas[0].AxisX.ScrollBar.Enabled = false;
chart1.ChartAreas[0].AxisY.ScrollBar.Enabled = false;
// 如果你想要更多的自定义设置,可以设置鼠标滚轮的行为
chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true; // 横向轴允许缩放
chart1.ChartAreas[0].AxisY.ScaleView.Zoomable = true; // 纵向轴允许缩放
// 如果需要,还可以设置选中区域的样式
chart1.ChartAreas[0].CursorX.SelectionColor = Color.Blue;
chart1.ChartAreas[0].CursorY.SelectionColor = Color.Blue;
// 将Chart置于放大状态
chart1.ChartAreas[0].CursorX.AutoScroll = true;
chart1.ChartAreas[0].CursorY.AutoScroll = true;
//启用游标鼠标滚动放大
chart1.ChartAreas[0].AxisX.ScaleView.Zoom(XMin, XMax);
chart1.ChartAreas[0].AxisY.ScaleView.Zoom(YMin, YMax);
chart1.ChartAreas[0].AxisX.IsMarginVisible = true;
chart1.ChartAreas[0].AxisY.IsMarginVisible = true;
chart1.ChartAreas[0].AxisX.ScaleBreakStyle.Enabled = false;
chart1.ChartAreas[0].AxisY.ScaleBreakStyle.Enabled = false;
//chart1.ChartAreas[0].AxisX.ScaleView.MinSize = chart1.ChartAreas[0].AxisY.ScaleView.MinSize = 1;
//chart1.ChartAreas[0].AxisX.IsLogarithmic = chart1.ChartAreas[0].AxisY.IsLogarithmic = true;
// 可以设置更多样式,如图表标题和图例等
chart1.Titles.Clear();
chart1.Titles.Add(StationName);
chart1.Titles[0].Text = StationName;
//chart1.Legends.Add("Legend");//图例
chart1.Legends[0].BackColor = Color.Transparent;
#endregion
#region "起点距⁓水深 剖面图 初始化"
chart2.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
chart2.ChartAreas[0].AxisY.IsReversed = true;//反转Y坐标
// 设置X和Y轴的标签
chart2.ChartAreas[0].AxisX.Title = "起点距 X (m)";
chart2.ChartAreas[0].AxisY.Title = "水深 Y (m)";
// X坐标范围最大最小
double PlanLineLength = Distance(Xwide, Ywide);// Math.Sqrt(Math.Pow(Xwide, 2) + Math.Pow(Ywide, 2));//计划线长
chart2.ChartAreas[0].AxisX.Minimum = (int)MinDistance - 5;
chart2.ChartAreas[0].AxisX.Maximum = Round46(MaxDistance, 0) + 5;
// X坐标范围最大最小
chart2.ChartAreas[0].AxisY.Minimum = 0;
chart2.ChartAreas[0].AxisY.Maximum = Round46(MaxWaterDepth, 0) + 2;
// 坐标轴间隔
chart2.ChartAreas[0].AxisX.Interval = 10;
chart2.ChartAreas[0].AxisY.Interval = 5;
// 设置 X 坐标轴和 Y 坐标轴刻度的格式
chart2.ChartAreas[0].AxisX.LabelStyle.Format = "0";
chart2.ChartAreas[0].AxisY.LabelStyle.Format = "0.0";
// 显示主坐标网格线
chart2.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart2.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
// 主坐标网格线间隔
chart2.ChartAreas[0].AxisX.MajorGrid.Interval = 10;
chart2.ChartAreas[0].AxisY.MajorGrid.Interval = 5;
// 显示主坐标网格 X轴和Y轴的刻度
chart2.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
chart2.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
// 设置主网格线为点
chart2.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart2.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
// 设置主网格线颜色
chart2.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
chart2.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
// 显示次坐标网格线
chart2.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart2.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
// 次坐标网格线间隔
chart2.ChartAreas[0].AxisX.MinorGrid.Interval = 1;
chart2.ChartAreas[0].AxisY.MinorGrid.Interval = 1;
// 显示次坐标网格 X轴和Y轴的刻度
chart2.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart2.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
// 设置次网格线为点
chart2.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
chart2.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
// 设置次网格线颜色
chart2.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.LightGray;
chart2.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray;
//缩放状态禁止显示滚动条
chart2.ChartAreas[0].AxisX.ScrollBar.Enabled = false;
chart2.ChartAreas[0].AxisY.ScrollBar.Enabled = false;
// 如果你想要更多的自定义设置,可以设置鼠标滚轮的行为
chart2.ChartAreas[0].AxisX.ScaleView.Zoomable = true; // 横向轴允许缩放
chart2.ChartAreas[0].AxisY.ScaleView.Zoomable = false; // 纵向轴禁止缩放
// 将Chart置于放大状态
chart2.ChartAreas[0].CursorX.AutoScroll = true;
chart2.ChartAreas[0].CursorY.AutoScroll = false;
//启用游标鼠标滚动放大
chart2.ChartAreas[0].AxisX.ScaleView.Zoom((int)MinDistance - 5, Round46(MaxDistance, 0) + 5);
chart2.Legends[0].BackColor = Color.Transparent;
#endregion
#region "时间⁓水深 剖面图 初始化"
chart3.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
chart3.ChartAreas[0].AxisY.IsReversed = true;//反转Y坐标
// 设置X和Y轴的标签
chart3.ChartAreas[0].AxisX.Title = "时间 X (s)";
chart3.ChartAreas[0].AxisY.Title = "水深 Y (m)";
// X坐标范围最大最小
chart3.ChartAreas[0].AxisX.Minimum = (int)MinSecond - 10;
chart3.ChartAreas[0].AxisX.Maximum = Round46(MaxSecond, 0) + 10;
// X坐标范围最大最小
chart3.ChartAreas[0].AxisY.Minimum = 0;
chart3.ChartAreas[0].AxisY.Maximum = Round46(MaxWaterDepth, 0) + 2;
// 坐标轴间隔
chart3.ChartAreas[0].AxisX.Interval = 60;
chart3.ChartAreas[0].AxisY.Interval = 5;
// 设置 X 坐标轴和 Y 坐标轴刻度的格式
chart3.ChartAreas[0].AxisX.LabelStyle.Format = "0";
chart3.ChartAreas[0].AxisY.LabelStyle.Format = "0.0";
// 显示主坐标网格线
chart3.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart3.ChartAreas[0].AxisY.MajorGrid.Enabled = true;
// 主坐标网格线间隔
chart3.ChartAreas[0].AxisX.MajorGrid.Interval = 60;
chart3.ChartAreas[0].AxisY.MajorGrid.Interval = 5;
// 显示主坐标网格 X轴和Y轴的刻度
chart3.ChartAreas[0].AxisX.MajorTickMark.Enabled = true;
chart3.ChartAreas[0].AxisY.MajorTickMark.Enabled = true;
// 设置主网格线为点
chart3.ChartAreas[0].AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
chart3.ChartAreas[0].AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Solid;
// 设置主网格线颜色
chart3.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.Black;
chart3.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.Black;
// 显示次坐标网格线
chart3.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart3.ChartAreas[0].AxisY.MinorGrid.Enabled = true;
// 次坐标网格线间隔
chart3.ChartAreas[0].AxisX.MinorGrid.Interval = 10;
chart3.ChartAreas[0].AxisY.MinorGrid.Interval = 1;
// 显示次坐标网格 X轴和Y轴的刻度
chart3.ChartAreas[0].AxisX.MinorTickMark.Enabled = true;
chart3.ChartAreas[0].AxisY.MinorTickMark.Enabled = true;
// 设置次网格线为点
chart3.ChartAreas[0].AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
chart3.ChartAreas[0].AxisY.MinorGrid.LineDashStyle = ChartDashStyle.Dot;
// 设置次网格线颜色
chart3.ChartAreas[0].AxisX.MinorGrid.LineColor = Color.LightGray;
chart3.ChartAreas[0].AxisY.MinorGrid.LineColor = Color.LightGray;
//缩放状态禁止显示滚动条
chart3.ChartAreas[0].AxisX.ScrollBar.Enabled = false;
chart3.ChartAreas[0].AxisY.ScrollBar.Enabled = false;
// 如果你想要更多的自定义设置,可以设置鼠标滚轮的行为
chart3.ChartAreas[0].AxisX.ScaleView.Zoomable = true; // 横向轴允许缩放
chart3.ChartAreas[0].AxisY.ScaleView.Zoomable = false; // 纵向轴禁止缩放
// 将Chart置于放大状态
chart3.ChartAreas[0].CursorX.AutoScroll = true;
chart3.ChartAreas[0].CursorY.AutoScroll = false;
//启用游标鼠标滚动放大
chart3.ChartAreas[0].AxisX.ScaleView.Zoom((int)MinSecond - 10, Round46(MaxSecond, 0) + 10);
chart3.Legends[0].BackColor = Color.Transparent;
#endregion
4.2.3、绘图控件 chart 加载数据显示图形
#region "平面图 添加系列数据"
Series series1 = new Series();
series1.Name = PlannedLineName;
//Series series1 = new Series(PlannedLineName);
series1.ChartType = SeriesChartType.Line;// 添加一个二维线图表系列
series1.Color = Color.Black;
series1.MarkerColor = Color.Black;
series1.MarkerSize = 5;
series1.MarkerStyle = MarkerStyle.Circle;
// 添加数据点
series1.Points.AddXY(StartDotCoordEast, StartDotCoordNorth);
series1.Points.AddXY(EndDotCoordEast, EndDotCoordNorth);
// 设置标签样式
series1.Label = "#SERIESNAME(#VALX #VAL)"; // #VAL将显示每个数据点的值
// 添加起点终点坐标系列
chart1.Series.Add(series1);
#endregion
double[,] FIXADD = new double[FIX.GetLength(0) + ADD.GetLength(0), 6];//合并FIX和ADD数组
for (int i = 0; i < FIX.GetLength(0); i++)
{
FIXADD[i, 0] = FIX[i, 0];//秒
FIXADD[i, 1] = FIX[i, 1];//打标序号
FIXADD[i, 2] = FIX[i, 2];//东坐标
FIXADD[i, 3] = FIX[i, 3];//北坐标
FIXADD[i, 4] = FIX[i, 4];//水深
FIXADD[i, 5] = 0;//FIX 打标标志
}
for (int i = 0; i < ADD.GetLength(0); i++)
{
FIXADD[i + FIX.GetLength(0), 0] = ADD[i, 0];
FIXADD[i + FIX.GetLength(0), 1] = ADD[i, 1];
FIXADD[i + FIX.GetLength(0), 2] = ADD[i, 2];
FIXADD[i + FIX.GetLength(0), 3] = ADD[i, 3];
FIXADD[i + FIX.GetLength(0), 4] = ADD[i, 4];
FIXADD[i + FIX.GetLength(0), 5] = 1;//后处理人工添加打标标志
}
MaxNumber = FIXADD[FIXADD.GetLength(0) - 1, 1];
//Console.WriteLine(MaxNumber);
if (ADD.Length > 0)
{
FIXADD = Common.OrderbyCol(FIXADD, 0);//二维数据按时间升序排序
}
FIXADDPointDistance = new double[FIXADD.GetLength(0)];//到点距
FIXADDOnlineDistance = new double[FIXADD.GetLength(0)];//起点距
FIXADDOffset = new double[FIXADD.GetLength(0)];//偏距
FIXADDWaterDepth = new double[FIXADD.GetLength(0)];//水深
//创建新数组
FixAddOutData = new string[FIXADD.GetLength(0), 10];//新的FIX和ADD数组含类型
if (FIXADD.Length > 0)
{
Series series5 = new Series();
series5.Name = "FIX 打标点";
series5.ChartType = SeriesChartType.Line;
series5.Color = Color.Red;
series5.MarkerColor = Color.Red;
series5.MarkerSize = 5;
series5.MarkerStyle = MarkerStyle.Circle;
series5.YValuesPerPoint = 2;//设置 2 个Y值
// 设置标签样式
//series5.Label = "#VAL"; // 显示每个数据点的打标数
Series series6 = new Series();
series6.Name = "FIX 打标点";
series6.ChartType = SeriesChartType.Column;
series6.Color = Color.Red;
series6.MarkerColor = Color.Red;
series6.MarkerSize = 2;
series6.MarkerStyle = MarkerStyle.None;
series6["PixelPointWidth"] = "2";//自定义点线宽
series6.Label = "#VALY2";//标签显示第二个Y值,即每个数据点的打标数
series6.SmartLabelStyle.IsMarkerOverlappingAllowed = false;
series6.SmartLabelStyle.MovingDirection = LabelAlignmentStyles.Bottom;
series6.SmartLabelStyle.IsOverlappedHidden = false;
series6.SmartLabelStyle.MaxMovingDistance = 10;
series6.SmartLabelStyle.MinMovingDistance = 20;
series6.SmartLabelStyle.CalloutLineColor = Color.Red;
series6.SmartLabelStyle.CalloutLineDashStyle = ChartDashStyle.Dash;
series6.SmartLabelStyle.CalloutLineAnchorCapStyle = LineAnchorCapStyle.Round;
series6.YValuesPerPoint = 2;//设置 2 个Y值
Series series7 = new Series();
series7.Name = "FIX 打标点";
series7.ChartType = SeriesChartType.Column;
series7.Color = Color.Red;
series7.MarkerColor = Color.Red;
series7.MarkerSize = 2;
series7.MarkerStyle = MarkerStyle.None;
series7["PixelPointWidth"] = "2";
series7.Label = "#VALY2";//标签显示第二个Y值,即每个数据点的打标数
series7.SmartLabelStyle.IsMarkerOverlappingAllowed = false;
series7.SmartLabelStyle.MovingDirection= LabelAlignmentStyles.Bottom ;
series7.SmartLabelStyle.IsOverlappedHidden = false;
series7.SmartLabelStyle.MaxMovingDistance = 10;
series7.SmartLabelStyle.MinMovingDistance = 20;
series7.SmartLabelStyle.CalloutLineColor = Color.Red;
series7.SmartLabelStyle.CalloutLineDashStyle = ChartDashStyle.Dash;
series7.SmartLabelStyle.CalloutLineAnchorCapStyle = LineAnchorCapStyle.Round;
series7.YValuesPerPoint = 2;//设置 2 个Y值
//series7.LabelForeColor = Color.Red;//标签字颜色
// 添加数据点
for (int i = 0; i < FIXADD.GetLength(0); i++)
{
double Second = FIXADD[i, 0];//秒
double Number = FIXADD[i, 1];//打标号
double X = Common.Round46(FIXADD[i, 2]);//东坐标
double Y = Common.Round46(FIXADD[i, 3]);//北坐标
FIXADDWaterDepth[i] = Convert.ToDouble(Common.Round46(FIXADD[i, 4], "H"));
if (FIXSurveyLineCheck.Checked)
{
series5.Points.AddXY(X, Y, Number);//平面图添加X、Y坐标和定标序号
}
FIXADDPointDistance[i] = Distance(StartDotCoordEast, StartDotCoordNorth, X, Y);//到点距
double MeasureLine = DegreesToRadian(AzimuthCalc(StartDotCoordEast, StartDotCoordNorth, X, Y));//测线方位角
FIXADDOnlineDistance[i] = Cos(MeasureLine - PlannedLineAzimuth) * FIXADDPointDistance[i];//在线起点距
FIXADDOffset[i] = Sin(MeasureLine - PlannedLineAzimuth) * FIXADDPointDistance[i];
int identify = (int)FIXADD[i, 5];
string Ident = "";
if (identify == 0)
{
Ident = "FIX";
}
else
{
Ident = "ADD";
}
string sTime = SP[21].Substring(0, 10) + " " + Hypack.GetTime(Second);
FixAddOutData[i, 0] = Second.ToString("0.000");//秒
FixAddOutData[i, 1] = X.ToString("0.000");//东
FixAddOutData[i, 2] = Y.ToString("0.000");//北
FixAddOutData[i, 3] = Common.Round46(FIXADD[i, 4], "H");//水深
FixAddOutData[i, 4] = Common.Round46(FIXADDOnlineDistance[i], 3).ToString("0.000");//在线距
FixAddOutData[i, 5] = Common.Round46(FIXADDPointDistance[i], 3).ToString("0.000");//到点距
FixAddOutData[i, 6] = Common.Round46(FIXADDOffset[i], 3).ToString("0.000");//偏距
FixAddOutData[i, 7] = sTime;//日期时间
FixAddOutData[i, 8] = Ident;//打标类型
FixAddOutData[i, 9] = Number.ToString("0");//点数
//Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\r\n", OutData[i, 0], OutData[i, 1], OutData[i, 2], OutData[i, 3], OutData[i, 4], OutData[i, 5], OutData[i, 6], OutData[i, 7], OutData[i, 8], OutData[i, 9]);
series6.Points.AddXY(Common.Round46(FIXADDOnlineDistance[i]), FIXADDWaterDepth[i], Number);//起点距-水深图添加 X 起点距、Y 水深和定标序号
series7.Points.AddXY(Second, FIXADDWaterDepth[i], Number);//时间-水深图添加 X 时间、Y水深和定标序号
}
chart1.Series.Add(series5);//平面图添加测深坐标点曲线
chart2.Series.Add(series6);
chart3.Series.Add(series7);
4.3、绘图控件 chart 上鼠标移动的关注点的代码实现
4.3.1 起点距⁓水深 剖面图上鼠标移动的关注点显示
private void chart2_MouseMove(object sender, MouseEventArgs e)
{
// 判断鼠标是否在折线上
HitTestResult hitResult = chart2.HitTest(e.X, e.Y);
if (hitResult.ChartElementType == ChartElementType.DataPoint)
{
// 获取鼠标所在区域线的坐标值
//double xValue = chart2.ChartAreas[0].AxisX.PixelPositionToValue(e.X);
//double yValue = chart2.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);
// 获取数据点的索引
int index = hitResult.PointIndex;
seriesName2 = hitResult.Series.Name;//系列名称
//获取鼠标所在系列点的坐标点
dataPoint = chart2.Series[seriesName2].Points[hitResult.PointIndex];
double xValue = dataPoint.XValue;
double y1Value = dataPoint.YValues[0];
string ShowString = "";
if (seriesName2 == "FIX 打标点")
{
double y2Value = dataPoint.YValues[1];
ShowString = $"{seriesName2}\r\nX: {xValue:f3}, Y: {y1Value:f2}, 打标点号: {y2Value}";
}
else
{
ShowString = $"{seriesName2}\r\nX: {xValue:f3}, Y: {y1Value:f2}";//鼠标移动显示 起点距、水深、定标序号
}
// 显示坐标值,限制为两位小数
toolTip1.Show(ShowString, this.chart2, e.Location.X - 55, e.Location.Y - 50);
}
else if (hitResult.ChartElementType == ChartElementType.PlottingArea || hitResult.ChartElementType == ChartElementType.TickMarks)
{
if (NotLoadData)
{
toolTip1.Show("鼠标滚动缩放\r\n鼠标左键按下拖移", this.chart2, e.Location.X - 55, e.Location.Y - 50);
}
else
{
toolTip1.Hide(this.chart2);
}
}
else
{
toolTip1.Hide(this.chart2); // 鼠标不在折线上,隐藏ToolTip
}
double MaxX = 0, MaxY = 0;
var results = chart2.HitTest(e.X, e.Y, false, ChartElementType.PlottingArea);
foreach (var result in results)
{
if (result.ChartElementType == ChartElementType.PlottingArea)
{
MaxX = (int)result.ChartArea.AxisX.ValueToPixelPosition(result.ChartArea.AxisX.Maximum);
MaxY = (int)result.ChartArea.AxisY.ValueToPixelPosition(result.ChartArea.AxisY.Maximum);//坐标相反
}
}
if (!double.IsNaN(MaxY) && MaxX > 0 && MaxY > 0)
{
if (e.X < MaxX && e.Y < MaxY)
{
double xValue = chart2.ChartAreas[0].AxisX.PixelPositionToValue(e.X);//状态栏显示鼠标点位置的起点距
double yValue = chart2.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);//状态栏显示鼠标点位置的水深
if (yValue < 0) yValue = 0;
StatusLabel1.Text = "起点距:";
StatusLabel3.Text = "水深:";
StatusLabel2.Text = xValue.ToString("0.000");
StatusLabel4.Text = yValue.ToString("0.00");
}
}
if (IsMoveChart)
{
mouseDownxNewX = e.X;
chart2.ChartAreas[0].AxisX.ScaleView.Position = mouseDownPosX + (mouseDownXoldX - mouseDownxNewX) * mouseRateX;
mouseDownxNewY = e.Y;
chart2.ChartAreas[0].AxisY.ScaleView.Position = mouseDownPosY + (mouseDownXoldY - mouseDownxNewY) * mouseRateY;
}
}
4.3.2 时间⁓水深 剖面图上鼠标移动的关注点显示
private void chart3_MouseMove(object sender, MouseEventArgs e)
{
// 判断鼠标是否在折线上
HitTestResult hitResult = chart3.HitTest(e.X, e.Y);
if (hitResult.ChartElementType == ChartElementType.DataPoint)
{
// 获取鼠标所在区域线的坐标值
//double xValue = chart3.ChartAreas[0].AxisX.PixelPositionToValue(e.X);
//double yValue = chart3.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);
// 获取数据点的索引
int index = hitResult.PointIndex;
seriesName3 = hitResult.Series.Name;//系列名称
//获取鼠标所在系列点的坐标点
dataPoint = chart3.Series[seriesName3].Points[hitResult.PointIndex];
double xValue = dataPoint.XValue;
double y1Value = dataPoint.YValues[0];
string ShowString = "";
if (seriesName3 == "FIX 打标点")
{
double y2Value = dataPoint.YValues[1];
ShowString = $"{seriesName3}\r\nX: {xValue:f3}, Y: {y1Value:f2}, 打标点号: {y2Value}";
}
else
{
ShowString = $"{seriesName3}\r\nX: {xValue:f3}, Y: {y1Value:f2}";//鼠标移动显示 时间、水深、定标序号
}
// 显示坐标值,限制为两位小数
toolTip1.Show(ShowString, this.chart3, e.Location.X - 65, e.Location.Y - 50);
}
else if (hitResult.ChartElementType == ChartElementType.PlottingArea || hitResult.ChartElementType == ChartElementType.TickMarks)
{
if (NotLoadData)
{
toolTip1.Show("鼠标左键单击选择测点\r\n鼠标右键单击手工添加或删除测点为打标", this.chart3, e.Location.X - 115, e.Location.Y - 50);
}
else
{
toolTip1.Hide(this.chart3);
}
}
else
{
toolTip1.Hide(this.chart3); // 鼠标不在折线上,隐藏ToolTip
}
double MaxX = 0, MaxY = 0;
var results = chart3.HitTest(e.X, e.Y, false, ChartElementType.PlottingArea);
foreach (var result in results)
{
if (result.ChartElementType == ChartElementType.PlottingArea)
{
MaxX = (int)result.ChartArea.AxisX.ValueToPixelPosition(result.ChartArea.AxisX.Maximum);
MaxY = (int)result.ChartArea.AxisY.ValueToPixelPosition(result.ChartArea.AxisY.Maximum);
}
}
if (!double.IsNaN(MaxY) && MaxX > 0 && MaxY > 0)
{
if (e.X < MaxX && e.Y < MaxY)
{
double xValue = chart3.ChartAreas[0].AxisX.PixelPositionToValue(e.X);//状态栏显示鼠标点位置的时间
double yValue = chart3.ChartAreas[0].AxisY.PixelPositionToValue(e.Y);//状态栏显示鼠标点位置的水深
AddDataSecond = xValue;
if (yValue < 0) yValue = 0;
StatusLabel1.Text = "时间:";
StatusLabel3.Text = "水深:";
StatusLabel2.Text = xValue.ToString("0.000");
StatusLabel4.Text = yValue.ToString("0.00");
}
}
if (IsMoveChart)
{
mouseDownxNewX = e.X;
chart3.ChartAreas[0].AxisX.ScaleView.Position = mouseDownPosX + (mouseDownXoldX - mouseDownxNewX) * mouseRateX;
mouseDownxNewY = e.Y;
chart3.ChartAreas[0].AxisY.ScaleView.Position = mouseDownPosY + (mouseDownXoldY - mouseDownxNewY) * mouseRateY;
}
}
注意:上述代码,其中部分自定义计算函数没有在这里展示