画直方图
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
首先画坐标系
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Collections;
namespace Sirc.cem.ZFT
{
///
/// 直角坐标系类
/// 用于表示气象自动站时段内降雨量在各个时间的分布
///
public class ZFTCoordinate
{
private int jtLength = 20; //箭头的长度
private int valueLent = 4; //刻度线的长度
private Hashtable table = new Hashtable(); //记录直方图X轴各个刻度的坐标,用键值对的形式保存在table中
List
///
/// 各个小直方图单元集合
///
public List
{
get
{
return cellList;
}
set { cellList = value; }
}
private double xCellValue = 0; //X轴一个单元格表示的值
///
/// X轴一个单元格表示的值
///
public double XCellValue
{
get { return xCellValue; }
set { xCellValue = value; }
}
private int xCellCount = 0; //X轴单元格的数目
///
/// X轴单元格的数目
///
public int XCellCount
{
get { return xCellCount; }
set { xCellCount = value; }
}
private int xCellLength = 0; //X轴单元格长度
///
/// X轴单元格长度
///
public int XCellLength
{
get { return xCellLength; }
set { xCellLength = value; }
}
private double yCellValue = 0; //Y轴一个单元格表示的值
///
/// Y轴一个单元格表示的值
///
public double YCellValue
{
get { return yCellValue; }
set { yCellValue = value; }
}
private int yCellCount = 0; //Y轴单元格的数目
///
/// Y轴单元格的数目
///
public int YCellCount
{
get { return yCellCount; }
set { yCellCount = value; }
}
private int yCellLength = 0; //Y轴单元格长度
///
/// Y轴单元格长度
///
public int YCellLength
{
get { return yCellLength; }
set { yCellLength = value; }
}
private int xStyle = 0; //X轴的样式,0表示从08点-08点 1表示20点-20点 2表示近多少小时
///
/// X轴的样式,
/// 0表示从08点-08点 也就是fromHour需要加上8
/// 1表示20点-20点 也就是fromHour需要加上20
/// 2表示近多少
小时 fromHour不需要加任何数值
/// 默认是0
///
public int XStyle
{
get { return xStyle; }
set { xStyle = value; }
}
private Point coordinatesOrigin; //坐标原点origin of coordinates
///
/// 坐标原点
///
public Point CoordinatesOrigin
{
get { return coordinatesOrigin; }
set { coordinatesOrigin = value; }
}
private int fromHour = 0; //起点时间
///
/// 起点时间
/// X轴的起点时间
///
public int FromHour
{
get { return fromHour; }
set
{
fromHour = value;
if (fromHour == 8)
xStyle = 0;
else if (fromHour == 20)
xStyle = 1;
else
xStyle = 2;
}
}
public ZFTCoordinate()
{
}
public ZFTCoordinate(double xCellValue, int xCellCount, double yCellValue, int yCellCount)
{
this.xCellCount = xCellCount;
this.xCellValue = xCellValue;
this.yCellCount = yCellCount;
this.yCellValue = yCellValue;
}
///
/// 依据雨量的最大值
/// 计算Y轴刻度值的分布
/// 保证直方图尽量的大
///
///
public void SetYValue(double maxRainfall)
{
if (maxRainfall > 5)
{
//计算Y轴刻度最大值
//计算方法:用最大雨量除以5,取整数加上1,再乘以5
int count1 = Convert.ToInt32(maxRainfall / 5);
int count2 = count1 + 1;
double maxCellValue = count2 * 5;
yCellValue = maxCellValue / 5;
}
else
{
yCellValue = 1;
}
}
///
/// 画直方图
/// 包括坐标系 雨量等
///
///
///
///
public Image Draw(int width,int height)
{
Image img = new Bitmap(width, height);
Graphics g = Graphics.FromImage(img);
//画坐标系
DrawXLine(g);
DrawYLine(g);
DrawCell(g, cellList);
g.Dispose();
return img;
}
///
/// 利用坐标系参数 画坐标系
///
///
private void DrawXLine(Graphics g)
{
//坐标原点Co
ordinatesOrigin
//画X轴
//一个单元格一个单元格的画
Point fromPt = coordinatesOrigin;
Point toPt = new Point();
Pen pen = new Pen(Color.Black);
Font font = new Font("宋体", 9);
for (int i = 0; i < xCellCount; i++)
{
//画单元格
toPt = new Point(fromPt.X + xCellLength, fromPt.Y);
g.DrawLine(pen, fromPt, toPt);
//画刻度线
Point xCellValuePoint = new Point(toPt.X, toPt.Y + valueLent);
g.DrawLine(pen, toPt, xCellValuePoint);
//画数值 只画偶数
int hour = i;
if (i % 2 == 0)
{
string s = "";
if (xStyle == 0)
{
hour = hour + 8;
}
else if (xStyle == 1)
{
hour = hour + 20;
}
else
{
if (fromHour % 2 != 0)
hour = hour + fromHour - 1;
else
hour = hour + fromHour;
}
if (hour == 24)
{
hour = 0;
}
else if (hour > 24)
{
hour = hour - 24;
}
s = (hour < 10) ? ("0" + hour) : hour + "";
//保存刻度点 用来画直方图时使用
if (i > 0)
{
table.Add(hour, toPt);
}
else
table.Add(-1, toPt);//X轴第一个点
Point sPoint = new Point(xCellValuePoint.X - 7, xCellValuePoint.Y + 5);
g.DrawString(s, font, Brushes.Black, sPoint);
}
fromPt = toPt;
}
//画箭头
Point jtPoint = new Point(toPt.X + jtLength, toPt.Y);
g.DrawLine(pen, toPt, jtPoint);
g.DrawLine(pen, jtPoint.X, jtPoint.Y, jtPoint.X - jtLength / 4, jtPoint.Y + jtLength / 4);
g.DrawLine(pen, jtPoint.X, jtPoint.Y, jtPoint.X - jtLength / 4, jtPoint.Y - jtLength / 4);
//画单位
Point sjtPoint = new Point(jtPoint.X + 5, jtPoint.Y+5);
string jts = "时";
g.DrawString(jts, font, Brushes.Black, sjtPoint);
pen.Dispose();
font.Dispose();
}
///
/// 利用坐标系参数 画坐标系
///
///
private void DrawYLine(Graphics g)
{
//坐标原点CoordinatesOrigin
//画X轴
//一个单元格一个单元格的画
Point fromPt = coordinatesOrigin;
Point toPt = new Point();
Pen pen = new Pen(Color.Black);
Font font = new Font("宋体", 9);
for (int i = 0; i < yCellCount; i++)
{
//画单元格
toPt = new Point(fromPt.X, fromPt.Y - yCellLength);
g.DrawLine(pen, fromPt, toPt);
//画刻度线
Point yCellValuePoint = new Point(toPt.X - valueLent, toPt.Y);
g.DrawLine(pen, toPt, yCellValuePoint);
//画数值
Point sPoint = new Point(yCellValuePoint.X - 20, yCellValuePoint.Y - 5);
string s = (i + 1) * yCellValue + "";
g.DrawString(s, font, Brushes.Black, sPoint);
fromPt = toPt;
}
//画箭头
Point jtPoint = new Point(toPt.X, toPt.Y - jtLength);
g.DrawLine(pen, toPt, jtPoint);
g.DrawLine(pen, jtPoint.X, jtPoint.Y, jtPoint.X + jtLength / 4, jtPoint.Y + jtLength / 4);
g.DrawLine(pen, jtPoint.X, jtPoint.Y, jtPoint.X - jtLength / 4, jtPoint.Y + jtLength / 4);
//画单位
Point sjtPoint = new Point(jtPoint.X + 10, jtPoint.Y);
string jts = "毫米";
g.DrawString(jts, font, Brushes.Black, sjtPoint);
pen.Dispose();
font.Dispose();
}
///
/// 画直方图
///
///
private void DrawCell(Graphics g,List
{
if (cellList == null)
return;
Pen pen = new Pen(Color.Black);
foreach (ZFTCell cell in cellList)
{
System.Drawing.Point fromPt = new Point();
int hours = cell.Hour;
if (hours % 2 != 0)
{
hours = hours - 1;
if(hours == fromHour)
fromPt = (Point)table[-1];
else
fromPt = (Point)table[hours];
fromPt.X += xCellLength;
}
else
{
fromPt = (Point)table[hours];
}
int lenth = Convert.ToInt32((cell.Rainfall / yCellValue) * yCellLength);
Point leftUp = new Point(fromPt.X - xCellLength / 2, fromPt.Y - lenth);
Point rightLow = new Point(fromPt.X + xCellLength / 2, fromPt.Y);
Rectangle rect = new Rectangle(leftUp.X, leftUp.Y, rightLow.X - leftUp.X, rightLow.Y - leftUp.Y);
g.FillRectangle(Brushes.LightBlue, rect);
g.DrawRec
tangle(pen, rect);
}
}
}
}
接下来是构造各个直方图单元格
using System;
using System.Collections.Generic;
using System.Text;
namespace Sirc.cem.ZFT
{
///
/// 直方图类
/// 存有雨量值和对应的时间
///
public class ZFTCell
{
private int hour = 0; //几点
///
/// 标志该单元格表示的是几点的雨量
///
public int Hour
{
get { return hour; }
set { hour = value; }
}
private double rainfall = 0; //雨量
///
/// 雨量值
///
public double Rainfall
{
get { return rainfall; }
set { rainfall = value; }
}
public ZFTCell(int hour, double rainfall)
{
this.hour = hour;
this.rainfall = rainfall;
}
}
}
最后是使用方法
//分析直方图的值
double maxRainfall = 0;//表示雨量的最大值,用来计算Y轴刻度值的分布
List
string[] splitDoller = { "$" };
string[] cellStrArr = s.Split(splitDoller, StringSplitOptions.RemoveEmptyEntries);
foreach (string cellStr in cellStrArr)
{
if (cellStr.IndexOf("-") == -1)
continue;
string[] splitCellStr = { "-" };
string[] cellInfoArr = cellStr.Split(splitCellStr, StringSplitOptions.RemoveEmptyEntries);
int hour = Convert.ToInt32(cellInfoArr[0]);
double rainfall = Convert.ToDouble(cellInfoArr[1]);
ZFTCell cell = new ZFTCell(hour, rainfall);
maxRainfall = Math.Max(maxRainfall, rainfall);
cellList.Add(cell);
}
//画直方图
ZFTCoordinate c = new ZFTCoordinate(1, 25, 0, 5);
//fromTime是世界时,而直方图上显示的为北京时,所以要进行一个转换
c.FromHour = fromTime.Hour + 8;
c.SetYValue(maxRainfall);
c.CoordinatesOrigin = new System.Drawing.Point(30, 120);
c.XCellLength = 10;
c.YCellLength = 20;
c.CellList = cellList;
Image img = c.Draw(this.pictureBoxZFT.Width, this.pictureBoxZFT.Height);
this.pictureBoxZFT.Image = img;