最近一个项目中需要画图表,为了巩固知识并且方便以后的查找,把我的代码记录下来。
使用编程工具为VS2008,语言为c#,数据库为MySQL。
在from_load事件中调用画图表的程序:
private void FrmExerciseChart_Load(object sender, EventArgs e) { MySqlDB dbopt = new MySqlDB(); DataSet dsData = new DataSet(); dbopt.RunProc("SELECT AUTOID,VD_BIGVOL,VD_BIGSPD,VD_MIDVOL,VD_MIDSPD,VD_SMLVOL,VD_SMLSPD,VD_LANOCC,VD_TDATETIME FROM VD_CYCLEDATA where VD_ID='" + strDeviceInfo[0] + "' AND substring(date_format(VD_TDATETIME,'%Y-%m-%d'), 1, 10)>='" + DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd") + "' AND substring(date_format(VD_TDATETIME,'%Y-%m-%d'), 1, 10)<='" + DateTime.Now.AddDays(-1).ToString("yyyy-MM-dd") + "'", ref dsData, CommandType.Text); InitData(dsData); //这是初始化数据的方法,因为我的页面还要显示列表 CreateChart(zedGraphControl1, 0); //这是画图表的方法 }
初始化数据完成的工作是将查询得到的数据按照要求组合(要求是每5笔数据合成1笔),将组合好的数据显示在列表中。列表显示的列按顺序依次为:时间、流量、速度、占有率。生成图表时我只要遍历列表就可以了。
下面是画图表:
/// /// 画图表 /// /// 页面上的ZedGraph控件 /// 图表类型 private void CreateChart(ZedGraphControl zgc, int intType) { zgc.GraphPane.CurveList.Clear(); zgc.GraphPane.GraphObjList.Clear(); //初始化图表页面信息 GraphPane myPane = zgc.GraphPane; myPane.Title.Text = "检测器数据分析图"; myPane.XAxis.Title.Text = "时间"; myPane.XAxis.Type = AxisType.Date; myPane.XAxis.Scale.Format = "hh:mm:ss:"; myPane.YAxis.Title.Text = "平均车速"; myPane.Y2Axis.Title.Text = "占有率"; if (yAxis3 == null) { yAxis3 = new YAxis("流量"); myPane.YAxisList.Add(yAxis3); } //根据选择显示不同类型的图表 switch (intType) { case 0: LineChart(myPane); break; case 1: BarChart(myPane); break; case 2: PieChart(myPane); break; } myPane.XAxis.MajorGrid.IsVisible = true; myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f); zgc.AxisChange(); zgc.Refresh(); }
下面一个方法是为了控制在显示不同类型的图表时,图表的X轴、Y轴不会乱显示而设置的。因为我需要在显示折线图时显示3个Y轴,在显示柱状图时显示1个Y轴,在显示饼状图时不显示X轴和Y轴。本来不想加这个方法的,以为当切换图表的类型的时候只要重新调用DrawTheChart方法就可以像重新画图一样显示一个新的坐标正确的图标了,但实际上不行,有时有的坐标轴显示,有时有点不显示。没办法,我只好用苯办法控制一下。如果哪位可以解决我的这个问题请一定要通知我。
/// /// 控制不同类型的图表的坐标显示状态 /// /// private void SetAxis(int intType) { GraphPane myPane = zedGraphControl1.GraphPane; switch (intType) { case 0: //折线 myPane.XAxis.IsVisible = true; myPane.YAxis.IsVisible = true; myPane.Y2Axis.IsVisible = true; yAxis3.IsVisible = true; break; case 1: //柱状 myPane.XAxis.IsVisible = true; myPane.YAxis.IsVisible = true; myPane.Y2Axis.IsVisible = false; yAxis3.IsVisible = false; break; case 2: //饼状 myPane.XAxis.IsVisible = false; myPane.YAxis.IsVisible = false; myPane.Y2Axis.IsVisible = false; yAxis3.IsVisible = false; break; } }
下面是画折线图,看上去很多,但实际上有不少的代码只是用来设置样式的。
/// /// 画折线图表 /// /// private void LineChart(GraphPane myPane) { SetAxis(0); PointPairList vList = new PointPairList(); PointPairList sList = new PointPairList(); PointPairList oList = new PointPairList(); for (int i = 0; i < this.dataGridView1.Rows.Count; i++) { double time = new XDate(System.DateTime.Parse(this.dataGridView1.Rows[i].Cells[0].Value.ToString())); vList.Add(time, double.Parse(this.dataGridView1.Rows[i].Cells[1].Value.ToString())); sList.Add(time, double.Parse(this.dataGridView1.Rows[i].Cells[2].Value.ToString())); oList.Add(time, double.Parse(this.dataGridView1.Rows[i].Cells[3].Value.ToString())); } LineItem myCurve ; myCurve = myPane.AddCurve("平均车速", sList, Color.Red, SymbolType.Circle); //设置平均速度的折线、Y轴的显示样式等属性 myCurve.Symbol.Fill = new Fill(Color.White,Color.Red,45f); myPane.YAxis.Title.Text = "平均车速"; myPane.YAxis.Scale.FontSpec.FontColor = Color.Red; myPane.YAxis.Title.FontSpec.FontColor = Color.Red; myPane.YAxis.MajorTic.IsOpposite = false; myPane.YAxis.MinorTic.IsOpposite = false; myPane.YAxis.MajorGrid.IsZeroLine = false; myPane.YAxis.Scale.Align = AlignP.Inside; myPane.YAxis.Scale.Max = 150; myCurve = myPane.AddCurve("占有率", oList, Color.Blue, SymbolType.Diamond); //设置占有率的折线、Y轴的显示样式等属性 myCurve.Symbol.Fill = new Fill(Color.White, Color.Blue, 45f); myPane.Y2Axis.Title.Text = "车辆占有率"; myPane.Y2Axis.Scale.FontSpec.FontColor = Color.Blue; myPane.Y2Axis.Title.FontSpec.FontColor = Color.Blue; myPane.Y2Axis.MajorTic.IsOpposite = false; myPane.Y2Axis.MinorTic.IsOpposite = false; myPane.Y2Axis.MajorGrid.IsVisible = true; myPane.Y2Axis.Scale.Align = AlignP.Inside; myPane.Y2Axis.Scale.Min = 0; myPane.Y2Axis.Scale.Max = 220; myCurve = myPane.AddCurve("车流量", vList, Color.Green, SymbolType.Triangle); //设置车流量的折线、Y轴的显示样式等属性 myCurve.Symbol.Fill = new Fill(Color.White, Color.Green, 45f); yAxis3.IsVisible = true; myCurve.YAxisIndex = 1; yAxis3.Scale.FontSpec.FontColor = Color.Green; yAxis3.Title.FontSpec.FontColor = Color.Green; yAxis3.Color = Color.Green; yAxis3.MajorTic.IsInside = false; yAxis3.MinorTic.IsInside = false; yAxis3.MajorTic.IsOpposite = false; yAxis3.MinorTic.IsOpposite = false; yAxis3.Scale.Align = AlignP.Inside; yAxis3.Scale.Max = 250; yAxis3.Scale.Min = 0; }
下面是画柱状图,不需要设置太多样式,代码少了不少。
/// /// 画柱状图表 /// /// private void BarChart(GraphPane myPane) { SetAxis(1); int intNum = this.dataGridView1.Rows.Count; double[] dVolume = new double[intNum]; double[] dSpeed = new double[intNum]; double[] dOcc = new double[intNum]; for (int i=0; i < this.dataGridView1.Rows.Count; i++) { dVolume[i] = double.Parse(this.dataGridView1.Rows[i].Cells[1].Value.ToString()); dSpeed[i] = double.Parse(this.dataGridView1.Rows[i].Cells[2].Value.ToString()); dOcc[i] = double.Parse(this.dataGridView1.Rows[i].Cells[3].Value.ToString()); } BarItem myCurve; myCurve = myPane.AddBar("平均车速", null, dSpeed, Color.Red); myCurve.Bar.Fill = new Fill(Color.Red, Color.White, Color.Red); myCurve = myPane.AddBar("占有率", null, dOcc, Color.Blue); myCurve.Bar.Fill = new Fill(Color.Blue, Color.White, Color.Blue); myCurve = myPane.AddBar("车流量", null, dSpeed, Color.Green); myCurve.Bar.Fill = new Fill(Color.Green, Color.White, Color.Green); }
下面是画饼状图
/// /// 画饼状图 /// /// private void PieChart(GraphPane myPane) { SetAxis(2); double dVolume = 0; double dSpeed = 0; double dOcc = 0; for (int i = 0; i < this.dataGridView1.Rows.Count; i++) { dVolume += double.Parse(this.dataGridView1.Rows[i].Cells[1].Value.ToString()); dSpeed += double.Parse(this.dataGridView1.Rows[i].Cells[2].Value.ToString()); dOcc += double.Parse(this.dataGridView1.Rows[i].Cells[3].Value.ToString()); } PieItem myCurve; myCurve = myPane.AddPieSlice(dVolume, Color.Red, Color.White, 45f, 0, "平均速度"); myCurve = myPane.AddPieSlice(dSpeed, Color.Green, Color.White, 45f, 0, "车流量"); myCurve = myPane.AddPieSlice(dOcc, Color.Blue, Color.White, 45f, 0, "占有率"); }
好了,完成了。