using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; using System.Collections; namespace chartTC { public delegate void clickEventHandler(Stack name, Stack x, Stack y); public partial class chartTC: UserControl { public chartTC() { InitializeComponent(); } private void chart1_Click(object sender, EventArgs e) { } private void chartTC_Load(object sender, EventArgs e) { chart1.Series.Clear(); //ChartHelper.AddSeries(chart1, "曲线图", SeriesChartType.Line, Color.Red, Color.Red); //ChartHelper.SetTitle(chart1, "sif", new Font("微软雅黑", 12), Docking.Bottom, Color.White); ChartHelper.SetStyle(chart1, Color.Transparent, Color.White); //ChartHelper.SetLegend(chart1, Docking.Top, StringAlignment.Center, Color.Transparent, Color.White); //ChartHelper.SetXY(chart1, "波长", "值", StringAlignment.Far, Color.Black, Color.Black, AxisArrowStyle.None/*AxisArrowStyle.SharpTriangle*/, 10, 5); ChartHelper.SetMajorGrid(chart1, Color.Gray, 20, 2); //chart1.GetToolTipText += new EventHandler(chart_GetToolTipText);//https://bbs.csdn.net/topics/390754014 chart1.ChartAreas[0].CursorX.Interval = 0; chart1.ChartAreas[0].CursorX.IsUserEnabled = true; chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled = true; } void chart_GetToolTipText(object sender, ToolTipEventArgs e) { if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) { int i = e.HitTestResult.PointIndex; DataPoint dp = e.HitTestResult.Series.Points[i]; e.Text = string.Format("{1:F3}", dp.XValue, dp.YValues[0]); } } Point? prevPosition = null; ToolTip tooltip = new ToolTip(); void chart1_MouseMove(object sender, MouseEventArgs e) { var pos = e.Location; if (prevPosition.HasValue && pos == prevPosition.Value) return; tooltip.RemoveAll(); prevPosition = pos; var results = chart1.HitTest(pos.X, pos.Y, false, ChartElementType.DataPoint); //double XVuale = chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X); //chart1.Series[0]. //tooltip.Show("X=" + prop.AxisLabel + ", Y=" + prop.YValues[0], this.chart1, pos.X, pos.Y - 15); foreach (var result in results) { if (result.ChartElementType == ChartElementType.DataPoint) { var prop = result.Object as DataPoint; if (prop != null) { var pointXPixel = result.ChartArea.AxisX.ValueToPixelPosition(prop.XValue); var pointYPixel = result.ChartArea.AxisY.ValueToPixelPosition(prop.YValues[0]); // check if the cursor is really close to the point (2 pixels around the point) //if (Math.Abs(pos.X - pointXPixel) < 2 && // Math.Abs(pos.Y - pointYPixel) < 2) //{ // tooltip.Show("X=" + prop.XValue + ", Y=" + prop.YValues[0], this.chart1, // pos.X, pos.Y - 15); //} tooltip.Show("X=" + prop.AxisLabel + ", Y=" + prop.YValues[0], this.chart1, pos.X, pos.Y - 15); } } } } private void chart_MouseMove(object sender, MouseEventArgs e) { //labX.Text = e.X.ToString(); //labY.Text = e.Y.ToString(); //if (e.HitTestResult.ChartElementType == ChartElementType.DataPoint) //{ // int i = e.HitTestResult.PointIndex; // DataPoint dp = e.HitTestResult.Series.Points[i]; // e.Text = string.Format("{1:F3}", dp.XValue, dp.YValues[0]); //} //ChartHitInfo hitInfo = chartControl4.CalcHitInfo(e.Location); //if (hitInfo.SeriesPoint != null) //{ // MessageBox.Show(hitInfo.SeriesPoint.Values[0].ToString()); //} } private void chart_Wave1_MouseMove(object sender, MouseEventArgs e) { HitTestResult myTestResult = chart1.HitTest(e.X, e.Y); if (myTestResult.ChartElementType == ChartElementType.DataPoint) { this.Cursor = Cursors.Cross; int i = myTestResult.PointIndex; DataPoint dp = myTestResult.Series.Points[i]; double doubleXValue = (dp.XValue); double doubleYValue = dp.YValues[0]; //自我实现值的显示 MessageBox.Show(doubleYValue.ToString()); } else { this.Cursor = Cursors.Default; } } public event clickEventHandler clickPointEvent; private void chart1_MouseClick(object sender, MouseEventArgs e) { if (chart1.Series.Count == 0) return; if (e.Button == MouseButtons.Left) { //var collection = chart1.Series.Select(series => series.Points.Where(point => point.XValue == 0).ToList()).ToList();//???????????????????????????????????????????????????????? //chart1.Series.ElementAt ////方式1:遍历x坐标处的所有y坐标 //var pos = e.Location; //var yAxis = chart1.ChartAreas[0].AxisY; //int yMin = (int)yAxis.ValueToPixelPosition(yAxis.Maximum) - 1; //int yMax = (int)yAxis.ValueToPixelPosition(yAxis.Minimum); //for (int i = yMin; i < yMax + 1; i++) //{ // var results = chart1.HitTest(pos.X, pos.Y, true, ChartElementType.DataPoint); // foreach (var result in results) // { // if (result.ChartElementType == ChartElementType.DataPoint) // { // var prop = result.Object as DataPoint; // if (prop != null) // { // var pointXPixel = result.ChartArea.AxisX.ValueToPixelPosition(prop.XValue); // var pointYPixel = result.ChartArea.AxisY.ValueToPixelPosition(prop.YValues[0]); // int b = 1; // } // } // } //} //方式2: double cursorPos = chart1.ChartAreas[0].CursorX.Position; var xAxis = chart1.ChartAreas[0].AxisX; double XVuale1 = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(e.X); double XVuale2 = chart1.ChartAreas[0].AxisX.GetPosition(e.X); double XVuale3 = Math.Round(chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.X)); if (XVuale3-1 < xAxis.Minimum)//XVuale3-1:因为在chart上绘制的曲线的第一个点的x坐标为1而不是0; XVuale3 = 1; else if (chart1.Series[0].Points.Count - 1 < XVuale3 - 1) XVuale3= chart1.Series[0].Points.Count; chart1.ChartAreas[0].CursorX.Position = XVuale3; Stack name = new Stack(); Stack x = new Stack(); Stack y = new Stack(); for (int i = 0; i < chart1.Series.Count; i++) { DataPoint p1 = chart1.Series[i].Points.ElementAt((int)XVuale3 - 1); name.Push(chart1.Series[i].Name); x.Push(p1.AxisLabel); y.Push(p1.YValues[0]); } if(clickPointEvent != null) clickPointEvent(name, x, y); } else if (e.Button == MouseButtons.Right) { contextMenuStrip1.Show(chart1, e.X, e.Y); } } private double calcCursorGraphX(int clientX) { var xAxis = chart1.ChartAreas[0].AxisX; int xRight = (int)xAxis.ValueToPixelPosition(xAxis.Maximum) - 1; int xLeft = (int)xAxis.ValueToPixelPosition(xAxis.Minimum); if (clientX > xRight) { return xAxis.Maximum; } else if (clientX < xLeft) { return xAxis.Minimum; } else { return xAxis.PixelPositionToValue(clientX); } } //private int nearestPreceedingValue(double x) //{ // var bpData = chart1.Series[0].Points; // int bpIndex = bpData.BinarySearch(x, (xVal, point) => Math.Sign(x - point.XValue)); // if (bpIndex < 0) // { // bpIndex = ~bpIndex; // BinarySearch() returns the index of the next element LARGER than the target. // bpIndex = Math.Max(0, bpIndex - 1); // We want the value of the previous element, so we must decrement the returned index. // } // If this is before the start of the graph, use the first valid data point. // return bpIndex; //} private void clearAllToolStripMenuItem_Click(object sender, EventArgs e) { chart1.Series.Clear(); } public void clearAll() { chart1.Series.Clear(); } private Color ss() { int iSeed = 10; Random ro = new Random(10); long tick = DateTime.Now.Ticks; Random ran = new Random((int)(tick & 0xffffffffL) | (int)(tick >> 32)); int R = ran.Next(255); int G = ran.Next(255); int B = ran.Next(255); B = (R + G > 400) ? R + G - 400 : B;//0 : 380 - R - G; B = (B > 255) ? 255 : B; return Color.FromArgb(R, G, B); //return or.FromArgb(random.Next(255), random.Next(255), random.Next(255)); } public Color GetRandomColor() { Random RandomNum_First = new Random((int)DateTime.Now.Ticks); // 对于C#的随机数,没什么好说的 System.Threading.Thread.Sleep(RandomNum_First.Next(50)); Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks); // 为了在白色背景上显示,尽量生成深色 int int_Red = RandomNum_First.Next(256); int int_Green = RandomNum_Sencond.Next(256); int int_Blue = (int_Red + int_Green > 400) ? 0 : 400 - int_Red - int_Green; int_Blue = (int_Blue > 255) ? 255 : int_Blue; return Color.FromArgb(int_Red, int_Green, int_Blue); } public void addSeries(string[] x, double[] y,string name) { int count = chart1.Series.Count; //ChartHelper.AddSeries(chart1, name, SeriesChartType.Line, Color.Green, Color.Red, false); //ChartHelper.AddSeries(chart1, name, SeriesChartType.Line, ss(), ss(), false); ChartHelper.AddSeries(chart1, name, SeriesChartType.Line, GetRandomColor(), GetRandomColor(), false); chart1.Series[count].Points.DataBindXY(x, y); //chart1.Series[count].Points.DataBindY(y); } private void chart1_MouseDoubleClick(object sender, MouseEventArgs e) { //Chart chart1 = sender as Chart; //右键恢复事件 if (e.Button == MouseButtons.Left) { chart1.ChartAreas[0].AxisX.ScaleView.ZoomReset(0); } } } //https://blog.csdn.net/boxuming/article/details/89678159?spm=1001.2101.3001.6650.4&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-4.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-4.pc_relevant_default&utm_relevant_index=9 public class ChartHelper { /// /// Name:添加序列 /// Author:by boxuming 2019-04-28 13:59 /// /// 图表对象 /// 序列名称 /// 图表类型 /// 颜色 /// 标记点颜色 /// 是否显示数值 public static void AddSeries(Chart chart, string seriesName, SeriesChartType chartType, Color color, Color markColor, bool showValue = false) { chart.Series.Add(seriesName); chart.Series[seriesName].ChartType = chartType; chart.Series[seriesName].Color = color; if (showValue) { chart.Series[seriesName].IsValueShownAsLabel = true; chart.Series[seriesName].MarkerStyle = MarkerStyle.Circle; chart.Series[seriesName].MarkerColor = markColor; chart.Series[seriesName].LabelForeColor = color; chart.Series[seriesName].LabelAngle = -90; } } /// /// Name:设置标题 /// Author:by boxuming 2019-04-28 14:25 /// /// 图表对象 /// 图表名称 public static void SetTitle(Chart chart, string chartName, Font font, Docking docking, Color foreColor) { chart.Titles.Add(chartName); chart.Titles[0].Font = font; chart.Titles[0].Docking = docking; chart.Titles[0].ForeColor = foreColor; } /// /// Name:设置样式 /// Author:by boxuming 2019-04-23 14:04 /// /// 图表对象 /// 背景颜色 /// 字体颜色 public static void SetStyle(Chart chart, Color backColor, Color foreColor) { chart.BackColor = backColor; chart.ChartAreas[0].BackColor = backColor; chart.ForeColor = Color.Red; } /// /// Name:设置图例 /// Author:by boxuming 2019-04-23 14:30 /// /// 图表对象 /// 停靠位置 /// 对齐方式 /// 背景颜色 /// 字体颜色 public static void SetLegend(Chart chart, Docking docking, StringAlignment align, Color backColor, Color foreColor) { chart.Legends[0].Docking = docking; chart.Legends[0].Alignment = align; chart.Legends[0].BackColor = backColor; chart.Legends[0].ForeColor = foreColor; } /// /// Name:设置XY轴 /// Author:by boxuming 2019-04-23 14:35 /// /// 图表对象 /// X轴标题 /// Y轴标题 /// 坐标轴标题对齐方式 /// 坐标轴字体颜色 /// 坐标轴颜色 /// 坐标轴箭头样式 /// X轴的间距 /// Y轴的间距 public static void SetXY(Chart chart, string xTitle, string yTitle, StringAlignment align, Color foreColor, Color lineColor, AxisArrowStyle arrowStyle, double xInterval, double yInterval) { chart.ChartAreas[0].AxisX.Title = xTitle; chart.ChartAreas[0].AxisY.Title = yTitle; chart.ChartAreas[0].AxisX.TitleAlignment = align; chart.ChartAreas[0].AxisY.TitleAlignment = align; chart.ChartAreas[0].AxisX.TitleForeColor = foreColor; chart.ChartAreas[0].AxisY.TitleForeColor = foreColor; chart.ChartAreas[0].AxisX.LabelStyle = new LabelStyle() { ForeColor = foreColor }; chart.ChartAreas[0].AxisY.LabelStyle = new LabelStyle() { ForeColor = foreColor }; chart.ChartAreas[0].AxisX.LineColor = lineColor; chart.ChartAreas[0].AxisY.LineColor = lineColor; chart.ChartAreas[0].AxisX.ArrowStyle = arrowStyle; chart.ChartAreas[0].AxisY.ArrowStyle = arrowStyle; //chart.ChartAreas[0].AxisX.Interval = xInterval; //chart.ChartAreas[0].AxisY.Interval = yInterval; chart.ChartAreas[0].AxisY.IsStartedFromZero = false; } /// /// Name:设置网格 /// Author:by boxuming 2019-04-23 14:55 /// /// 图表对象 /// 网格线颜色 /// X轴网格的间距 /// Y轴网格的间距 public static void SetMajorGrid(Chart chart, Color lineColor, double xInterval, double yInterval) { chart.ChartAreas[0].AxisX.MajorGrid.LineColor = lineColor; chart.ChartAreas[0].AxisY.MajorGrid.LineColor = lineColor; chart.ChartAreas[0].AxisX.MajorGrid.Interval = xInterval; chart.ChartAreas[0].AxisY.MajorGrid.Interval = yInterval; } } }