一个简单的MFC柱状图显示程序

英语课最后大作业是做一份调查问卷,最后数据统计出来,结果用柱状图显示。

但是考虑到题目有20多道,全部做成柱状图一个个截图未免太俗套,不符合一个码农的口味,因此,我就花了两三个小时,从raw data开始,写了一个小代码,显示统计结果

一个简单的MFC柱状图显示程序

上面就是我小程序的基本布局,为了寻求简单,X轴一共只有5个标签,XY轴均没有考虑单位

因为长时间没有接触MFC了,所以,MFC下文件操作已经忘的差不多,索性直接用程序统计好所有所需的数据,格式化输出成数组的格式,直接保存在了头文件里。 一个简单的MFC柱状图显示程序勿喷


为所有的标签添加值类型的变量,下方五个静态标签定义5个变量
DDX_Text(pDX, IDC_STATIC_A, m_strLable[0]);
DDX_Text(pDX, IDC_STATIC_B, m_strLable[1]);
DDX_Text(pDX, IDC_STATIC_C, m_strLable[2]);
DDX_Text(pDX, IDC_STATIC_D, m_strLable[3]);
DDX_Text(pDX, IDC_STATIC_E, m_strLable[4]);
存放在一个数组中,方便修改内容

所有的数据都有,该如何画呢?

别急

第一步:取GroupBox的区域,并保存四个值   左,上,右,下
//获取屏幕坐标
((CWnd*)GetDlgItem(IDC_STATIC_CHART))->GetWindowRect(rect);
//计算x轴y轴基本单位
int dx = (rect.right-rect.left)/50;
int dy = (rect.bottom-rect.top)/80;
//转换成对话框坐标
ScreenToClient(rect);
//保存4个值
int L = rect.left,R = rect.right,T = rect.top,B = rect.bottom;

GroupBox的区域我忘记标出来了,就在上面图中柱状图那一块

第二步:获取DC,这一步没什么好说的
CPaintDC dc(this);
第三步:画X轴,Y轴
//X
dc.MoveTo(L+dx*2,B-dy*3);
dc.LineTo(L+dx*49,B-dy*3);
//最后的那个箭头
dc.MoveTo(L+dx*49,B-dy*3);
dc.LineTo(L+dx*48,B-dy*2);
dc.MoveTo(L+dx*49,B-dy*3);
dc.LineTo(L+dx*48,B-dy*4);

Y轴同理,但是考虑到dx,dy的值不一样,当画Y轴的箭头时,需要交换dx和dy的位置
//纵坐标线 dc.MoveTo(L+dx*2,B-dy*3); 
dc.LineTo(L+dx*2,B-dy*77); 
// 
dc.MoveTo(L+dx*2,B-dy*77); 
//交换了dx,dy的位置
dc.LineTo(L+dx*2-dy,B-dy*77+dx); 
dc.MoveTo(L+dx*2,B-dy*77); 
//交换了dx,dy的位置
dc.LineTo(L+dx*2+dy,B-dy*77+dx);
绘制完结果如图:
一个简单的MFC柱状图显示程序

第四步:画柱状图,这里主要根据前面计算dx,dy时,划分的数量来计算每个柱的宽度,以及柱间的间隔
解释的并不多,代码如下
//第一个柱状体的左下坐标
int x = L+dx*3;
int y = B-dy*3;
for(int i=0;i
CRect rc;
rc.left=x+i*dx*9;
rc.right=rc.left+dx*7;
rc.bottom=y;
rc.top=rc.bottom-dy*answer[index][i+1];
//这里把柱状图的信息输出,这里输出的是一个数字,因为要转换成字符串,比较麻烦
//处理了一下,肯定有简洁的处理方式,但是我也懒得去想了,我很懒的 一个简单的MFC柱状图显示程序
dc.SetBkMode(TRANSPARENT);//设置透明背景,要不然输出文字之后会有一块白,难看
char num[10];
sprintf(num,"%d",answer[index][i+1]);
CString strnum(num);
dc.TextOutW((rc.left+rc.right)/2-dx,rc.bottom-dy*(answer[index][i+1]+3),strnum);
//画刷是我之前就定义好的,直接拿来用
dc.FillRect(&rc,brushs+i);
}

第五步:画的问题已经解决,添加控件消息响应函数
维护一个全局变量index来保存当前题号
创建重绘函数updateInfo
void CEnglishReportDlg::updateInfo(){
int count = choose_c[index];
int i;
//选项存在,赋值,L是宏命令与TEXT()相同功能
for(i=0;i
m_strLable[i] = choose[index][i];
}
//无此选项,置空
for(;i<5;i++)
m_strLable[i] = L"";
m_strTopic = topics[index];
//获取GroupBox区域,并转换成对话框坐标
CRect rect;
((CWnd*)GetDlgItem(IDC_STATIC_CHART))->GetWindowRect(rect);
ScreenToClient(rect);
      //重绘此区域
InvalidateRect(rect);
//将控件变量更新到前台
UpdateData(FALSE);
}
函数1:响应ListBox的SelChange事件
void CEnglishReportDlg::OnLbnSelchangeListTopic()
{
// TODO: 在此添加控件通知处理程序代码
index = m_listtopic.GetCurSel();
updateInfo();
}
函数2:上一页按钮的Click事件
void CEnglishReportDlg::OnBnClickedButtonPre()
{
// TODO: 在此添加控件通知处理程序代码
if(index>0)
index--;
updateInfo();
m_listtopic.SetCurSel(index);
}
函数3:下一页按钮的Clicl事件
void CEnglishReportDlg::OnBnClickedButtonNext()
{
// TODO: 在此添加控件通知处理程序代码
if(index<19)
index++;
updateInfo();
m_listtopic.SetCurSel(index);
}
至此基本的功能都已经实现了,还差最后一步:
第六步:初始化对话框
for(int i=0;i<20;i++){
m_listtopic.AddString(topics[i]);
}
//index初始化为0,直接刷新
updateInfo();
m_listtopic.SetCurSel(index);
结束!!看看结果吧。

一个简单的MFC柱状图显示程序

一个简单的MFC柱状图显示程序

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值