C#:winform使用chart控件绘制折线图,时间轴可缩放
Chart坐标轴横轴为时间,纵轴是数值
如果只是一次性绘图,那么遍历一遍数据即可
如果想连续绘制(比如按照时间更新绘制),就需要一个Timer控件来更新绘图的数据。
以下为项目代码:
GUI界面添加一个Chart和一个timer即可
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace chartForTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Init_Chart();//初始化chart组件有关属性
timer1.Interval = 1000;//timer1用来更新图像,每秒增加一个点
timer1.Start();//窗口初始化完成即开始绘制
}
private void Init_Chart()
{
#region chart1
chart1.Series[0].IsValueShownAsLabel = true;//让点集0在图像上显示数值
chart1.Series[0].SmartLabelStyle.Enabled = true;
chart1.Series[0].XValueType = ChartValueType.DateTime;//坐标轴type改为时间
//去掉滚动条的按钮
chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.None;
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = false;
chart1.ChartAreas[0].AxisX.ScrollBar.Size = 20;
chart1.ChartAreas[0].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Seconds;
chart1.ChartAreas[0].AxisX.ScaleView.SizeType = DateTimeIntervalType.Seconds;
chart1.ChartAreas[0].AxisX.ScaleView.Size = 20;
chart1.ChartAreas[0].AxisX.ScaleView.MinSize = 15;
chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;
chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Seconds;
chart1.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Seconds;
//这个interval可以用来修改显示间隔
chart1.ChartAreas[0].AxisX.Interval = DateTime.Parse("00:00:01").Second;
chart1.ChartAreas[0].AxisX.TitleAlignment = StringAlignment.Near;
chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart1.ChartAreas[0].AxisX.MajorGrid.LineWidth = 1;
chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.LightGray;
//显示格式为时:分:秒
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";
chart1.ChartAreas[0].AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.LightGray;
#endregion
}
private void timer1_Tick(object sender, EventArgs e)
{
//让滚动条滚动到最新位置
this.chart1.ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.Last);
string now = DateTime.Now.ToLongTimeString();
//转换time的格式用于输出
DateTime time = DateTime.Parse(now);
//在点集0(serials[0])中加入新的点XY
//TIP:如果你使用数组存放要绘制的点,每次绘图从上一次绘制结束的位置开始即可
//不需要每次画图都从第一个点开始绘制
this.chart1.Series[0].Points.AddXY(time, DateTime.Now.Second);
}
}
}
上测试图:
PLUS:如果你还想让Chart实现时间坐标轴的缩放怎么做?
方便起见,我这里使用滚轮上下滑动
1.需要一个修改坐标轴间隔的事件
//记录当前的缩放位置,便于控制范围
private int IntervalNow = 0;
//可以使用代码控制,也可以像我这样使用固定的数组(其实这样更方便)
private string[] deltas = new string[] {"00:00:01",
"00:00:10",
"00:00:30",
"00:01:00",
"00:05:00",
"00:10:00",
"00:30:00",
"00:45:00",
"01:00:00"};
void myMouseWheel(object sender, MouseEventArgs e)
{
//if(sender == ch)
if (e.Delta > 0)
{//放大
//由于之前项目有不止一个Chart,所以我这里使用了(Chart)(sender)来获取触发事件的chart对象,省去判断,你们也可以把它直接换成chart1
if (((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size >= 0.5)
((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size = ((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size * 0.5;
if (Convert.ToInt32(((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size) >= 20)
{
--IntervalNow;
if (IntervalNow < 0)
IntervalNow = 0;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
else
{
IntervalNow = 0;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
}
else
{
if (((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size <= 100000)
((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size = ((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size * 2;
if (((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size >= 20)
{
++IntervalNow;
if (IntervalNow >= 9)
IntervalNow = 8;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
else
{
IntervalNow = 0;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
}
}
2.将Chart与缩放事件关联起来
chart1.MouseWheel += new MouseEventHandler(myMouseWheel);
3.运行试试看
最后附上带缩放控制的完整代码:
GUI界面需要的仍只是添加一个Chart和Timer即可(name分别为chart1和timer1)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace chartForTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Init_Chart();//初始化chart组件有关属性
timer1.Interval = 1000;//timer1用来更新图像,每秒增加一个点
timer1.Start();//窗口初始化完成即开始绘制
chart1.MouseWheel += new MouseEventHandler(myMouseWheel);
}
private void Init_Chart()
{
#region chart1
chart1.Series[0].IsValueShownAsLabel = true;//让点集0在图像上显示数值
chart1.Series[0].SmartLabelStyle.Enabled = true;
chart1.Series[0].XValueType = ChartValueType.DateTime;//坐标轴type改为时间
//去掉滚动条的按钮
chart1.ChartAreas[0].AxisX.ScrollBar.ButtonStyle = ScrollBarButtonStyles.None;
chart1.ChartAreas[0].AxisX.ScrollBar.IsPositionedInside = false;
chart1.ChartAreas[0].AxisX.ScrollBar.Size = 20;
chart1.ChartAreas[0].AxisX.ScaleView.MinSizeType = DateTimeIntervalType.Seconds;
chart1.ChartAreas[0].AxisX.ScaleView.SizeType = DateTimeIntervalType.Seconds;
chart1.ChartAreas[0].AxisX.ScaleView.Size = 20;
chart1.ChartAreas[0].AxisX.ScaleView.MinSize = 15;
chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = 1;
chart1.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Seconds;
chart1.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Seconds;
//这个interval可以用来修改显示间隔
chart1.ChartAreas[0].AxisX.Interval = DateTime.Parse("00:00:01").Second;
chart1.ChartAreas[0].AxisX.TitleAlignment = StringAlignment.Near;
chart1.ChartAreas[0].AxisX.MajorGrid.Enabled = true;
chart1.ChartAreas[0].AxisX.MajorGrid.LineWidth = 1;
chart1.ChartAreas[0].AxisX.MajorGrid.LineColor = Color.LightGray;
//显示格式为时:分:秒
chart1.ChartAreas[0].AxisX.LabelStyle.Format = "HH:mm:ss";
chart1.ChartAreas[0].AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
chart1.ChartAreas[0].AxisY.MajorGrid.LineColor = Color.LightGray;
#endregion
}
private void timer1_Tick(object sender, EventArgs e)
{
//让滚动条滚动到最新位置
this.chart1.ChartAreas[0].AxisX.ScaleView.Scroll(ScrollType.Last);
string now = DateTime.Now.ToLongTimeString();
//转换time的格式用于输出
DateTime time = DateTime.Parse(now);
//在点集0(serials[0])中加入新的点XY
//TIP:如果你使用数组存放要绘制的点,每次绘图从上一次绘制结束的位置开始即可
//不需要每次画图都从第一个点开始绘制
this.chart1.Series[0].Points.AddXY(time, DateTime.Now.Second);
}
//记录当前的缩放位置,便于控制范围
private int IntervalNow = 0;
//可以使用代码控制,也可以像我这样使用固定的数组(其实这样更方便)
private string[] deltas = new string[] {"00:00:01",
"00:00:10",
"00:00:30",
"00:01:00",
"00:05:00",
"00:10:00",
"00:30:00",
"00:45:00",
"01:00:00"};
void myMouseWheel(object sender, MouseEventArgs e)
{
if (e.Delta > 0)
{//放大
if (((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size >= 0.5)
((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size = ((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size * 0.5;
if (Convert.ToInt32(((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size) >= 20)
{
--IntervalNow;
if (IntervalNow < 0)
IntervalNow = 0;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
else
{
IntervalNow = 0;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
}
else
{
if (((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size <= 100000)
((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size = ((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size * 2;
if (((Chart)(sender)).ChartAreas[0].AxisX.ScaleView.Size >= 20)
{
++IntervalNow;
if (IntervalNow >= 9)
IntervalNow = 8;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
else
{
IntervalNow = 0;
((Chart)(sender)).ChartAreas[0].AxisX.Interval = DateTime.Parse(deltas[IntervalNow]).Second;
}
}
}
}
}
转载:https://blog.csdn.net/YangZuo_Chester/article/details/89227628?utm_medium=distribute.pc_relevant_bbs_down.none-task--2allfirst_rank_v2rank_v29-2.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task--2allfirst_rank_v2rank_v29-2.nonecase