工控编程吧
标题:
MFC扩展编程实例3D簇状柱形图旋转平移缩放操作
[打印本页]
作者:
qq263946146
时间:
2020-1-13 12:46
标题:
MFC扩展编程实例3D簇状柱形图旋转平移缩放操作
MFC扩展编程实例3D簇状柱形图旋转平移缩放操作
例程实现对3D图表按钮的旋转平移缩放等常见操作。
界面如下:
(, 下载次数: 1)
上传
点击文件名下载附件
例程界面创建的是3D簇状柱形图表,可以通过库自带的图表操作按钮来左右,上下,斜切旋转图表。
也可以通过鼠标交互形式来操作图表。
按住鼠标右键不放,左右上下移动鼠标,可以下载左右旋转三维图表,代码中注释了斜切操作,可选择使用。
图表的缩放与平移操作,可以按钮键盘左边shift键不放,鼠标点住左键平移,鼠标滚轮前后滚动缩放。
下面是创建过程与关键代码。
先创建基于class CMy123View : public CBCGPFormView的单文档工程。
添加 变量与自定义函数
CBCGPChartCtrl m_wndChart;
CBCGPRotationCtrl m_wndRotate;
void RotateChart(CBCGPRotationObject::RotationElement hit, double xDelta = 10., double yDelta = 10., double persperctiveDelta = 0.1);
添加虚函数Create,在函数Create内初始化变量。
下面是两函数代码。
BOOL CMy123View::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
BOOL bRst = CBCGPFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);;
m_wndRotate.SubclassDlgItem(IDC_ROTATE,this);
m_wndRotate.GetRotationObject()->SetAutorepeatMode(100);
m_wndRotate.GetRotationObject()->SetColorTheme(CBCGPRotationObject::BCGP_COLOR_THEME_VISUAL_MANAGER);
m_wndRotate.GetRotationObject()->EnablePart(CBCGPRotationObject::BCGP_ROTATION_CLOCKWISE, FALSE);
m_wndRotate.GetRotationObject()->EnablePart(CBCGPRotationObject::BCGP_ROTATION_COUNTER_CLOCKWISE, FALSE);
m_wndRotate.GetRotationObject()->EnableFlatIcons();
//获取图表指针;
m_wndChart.SubclassDlgItem(IDC_CHART,this);//子类化图表;
CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
pChart->SetChartTitle(_T("3D簇状柱形图"));//图表标题设置;
pChart->SetThemeOpacity(70);//图表主题透明度设置;
pChart->EnableMouseTrackingMode(BCGPChartHitInfo::HIT_DIAGRAM);
BCGPChartCategory category = BCGPChartColumn3D;//图表种类,F12查看全部;
BCGPChartType type = BCGP_CT_SIMPLE;//图表类型,按F12查看全部;
pChart->SetChartType(category, type);//设置图表类别;
pChart->GetDiagram3D()->SetGrouped(TRUE, FALSE);//设置为簇状类型图表;
//设置3D背部与底部;
DWORD dwoFlags = CBCGPChartDiagram3D::DWO_OUTLINE_ALL;
dwoFlags |= (CBCGPChartDiagram3D::DWO_DRAW_ALL_WALLS | CBCGPChartDiagram3D::DWO_DRAW_FLOOR);
pChart->GetDiagram3D()->SetDrawWallOptions((CBCGPChartDiagram3D::DrawWallOptions)dwoFlags);
pChart->GetDiagram3D()->SetThickWallsAndFloor(true);
//创建4个数据系列;
CBCGPChartBarSeries* pBarSeries1 = DYNAMIC_DOWNCAST(CBCGPChartBarSeries, pChart->CreateSeries(_T("能源")));
CBCGPChartBarSeries* pBarSeries2 = DYNAMIC_DOWNCAST(CBCGPChartBarSeries, pChart->CreateSeries(_T("税收")));
CBCGPChartBarSeries* pBarSeries3 = DYNAMIC_DOWNCAST(CBCGPChartBarSeries, pChart->CreateSeries(_T("维护")));
CBCGPChartBarSeries* pBarSeries4 = DYNAMIC_DOWNCAST(CBCGPChartBarSeries, pChart->CreateSeries(_T("其他")));
//向四个数据系列添加数据;
srand((unsigned)time(NULL));
COleDateTime now = COleDateTime::GetCurrentTime();
CString sYear;
for(int i=5;i>0;i--)
{
sYear.Format(_T("%d"), now.GetYear() - i);
pBarSeries1->AddDataPoint(sYear, rand()%20+1);
}
pBarSeries2->AddDataPoint(10);
pBarSeries2->AddDataPoint(12);
pBarSeries2->AddDataPoint(15);
pBarSeries2->AddDataPoint(17);
pBarSeries2->AddDataPoint(12);
pBarSeries3->AddDataPoint(5);
pBarSeries3->AddDataPoint(7);
pBarSeries3->AddDataPoint(11);
pBarSeries3->AddDataPoint(14);
pBarSeries3->AddDataPoint(19);
pBarSeries4->AddDataPoint(2);
pBarSeries4->AddDataPoint(3);
pBarSeries4->AddDataPoint(5);
pBarSeries4->AddDataPoint(3);
pBarSeries4->AddDataPoint(2);
//添加添加到布局管理器统一管理布局;
if (GetLayout() == NULL)
return bRst;
CBCGPStaticLayout* pLayout = (CBCGPStaticLayout*)GetLayout();
if (pLayout == NULL)
return bRst;
pLayout->AddAnchor(m_wndChart.GetDlgCtrlID(), CBCGPStaticLayout::e_MoveTypeNone, CBCGPStaticLayout::e_SizeTypeBoth);
//
return bRst;
}
复制代码
void CMy123View::RotateChart(CBCGPRotationObject::RotationElement hit, double xDelta, double yDelta, double persperctiveDelta)
{
CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
if (pChart == NULL)
return;
ASSERT_VALID(pChart);
CBCGPChartDiagram3D* pDiagram3D = pChart->GetDiagram3D();
if (pDiagram3D == NULL)
return;
double xRotation = pDiagram3D->GetXRotation();
double yRotation = pDiagram3D->GetYRotation();
double dblPerspectivePercent = pDiagram3D->GetPerspectivePercent();
switch (hit)
{
case CBCGPRotationObject::BCGP_ROTATION_RESET:
pDiagram3D->Reset(TRUE);
return;
case CBCGPRotationObject::BCGP_ROTATION_UP:
yRotation += yDelta;
break;
case CBCGPRotationObject::BCGP_ROTATION_DOWN:
yRotation -= yDelta;
break;
case CBCGPRotationObject::BCGP_ROTATION_LEFT:
xRotation -= xDelta;
break;
case CBCGPRotationObject::BCGP_ROTATION_RIGHT:
xRotation += xDelta;
break;
case CBCGPRotationObject::BCGP_ROTATION_NARROW_FIELD_OF_VIEW:
dblPerspectivePercent -= persperctiveDelta;
break;
case CBCGPRotationObject::BCGP_ROTATION_WIDEN_FIELD_OF_VIEW:
dblPerspectivePercent += persperctiveDelta;
break;
}
pDiagram3D->SetPosition(xRotation, yRotation, dblPerspectivePercent);
pChart->SetDirty(TRUE,TRUE);
}
复制代码
在创建函数中有用到控件ID,请要视窗对话框资源中添加两图片控件,修改ID为IDC_ROTATE,IDC_CHART。
还有一个编辑框,ID修改为IDC_EDIT1。
这样变能够正常创建变量,另外可以在构造函数中调用EnableLayout();以开启布局管理器。
然后变可以关联图表操作控件m_wndRotate的点击函数以实现旋转图表等操作。
afx_msg void OnRotate();
ON_BN_CLICKED(IDC_ROTATE, OnRotate)
void CMy123View::OnRotate()
{
RotateChart(m_wndRotate.GetRotationObject()->GetClicked());
}
复制代码
如果还想实现鼠标来操作图表,可以再实现对鼠标点击,移动消息的响应。
afx_msg LRESULT OnMouseTrack(WPARAM wp, LPARAM lp);
afx_msg LRESULT OnMouseDown(WPARAM wp, LPARAM lp);
ON_REGISTERED_MESSAGE(BCGM_ON_CHART_MOUSE_TRACK, OnMouseTrack)
ON_REGISTERED_MESSAGE(BCGM_ON_CHART_MOUSE_DOWN, OnMouseDown)
CPoint ptOrigin;
LRESULT CMy123View::OnMouseDown(WPARAM /*wp*/, LPARAM lp)
{
BCGPChartHitInfo* pHitInfo = (BCGPChartHitInfo*)lp;
if(pHitInfo->m_nMouseButton ==0)
ptOrigin = pHitInfo->m_ptHit;
return false;
}
LRESULT CMy123View::OnMouseTrack(WPARAM /*wp*/, LPARAM lp)
{
CBCGPChartVisualObject* pChart = m_wndChart.GetChart();
if(pChart == NULL)
return false;
BCGPChartHitInfo* pHitInfo = (BCGPChartHitInfo*)lp;
if(pHitInfo->m_ptHit == CBCGPPoint(-1, -1))
return false;
if(0x8000 & GetKeyState(VK_RBUTTON ) )
{
CString sText;
CBCGPPoint pt = pHitInfo->m_ptHit;
double p = sqrt( pow(pt.x-ptOrigin.x,2)+pow(pt.y-ptOrigin.y,2) );
if(p<10)
return false;
double dbAng = asin( (pt.y-ptOrigin.y) /p)*(180.0 / 3.1415926);
//dbAng转换为对应逆时针一圈角度(0-360);
if( pt.x>ptOrigin.x)
{
if(dbAng<0)
dbAng = abs(dbAng);
else
dbAng= abs(360-dbAng);
}
else
{
if(dbAng<0)
dbAng = 180+dbAng;
else
dbAng = 180+dbAng;
}
sText.Format(_T("%.03lf"),dbAng);
SetDlgItemText(IDC_EDIT1,sText);
//
int nDir=0,nDel=360/16;
if(0<=dbAng && dbAng<nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_LEFT;
else if(nDel<=dbAng && dbAng<3*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_NONE;//BCGP_ROTATION_NARROW_FIELD_OF_VIEW;
else if(3*nDel<=dbAng && dbAng<5*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_DOWN;
else if(5*nDel<=dbAng && dbAng<7*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_NONE;//BCGP_ROTATION_CLOCKWISE;
else if(7*nDel<=dbAng && dbAng<9*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_RIGHT;
else if(9*nDel<=dbAng && dbAng<11*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_NONE;//BCGP_ROTATION_WIDEN_FIELD_OF_VIEW;
else if(11*nDel<=dbAng && dbAng<13*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_UP;
else if(13*nDel<=dbAng && dbAng<15*nDel)
nDir = CBCGPRotationObject::BCGP_ROTATION_NONE;//BCGP_ROTATION_COUNTER_CLOCKWISE;
else if(15*nDel<=dbAng && dbAng<360)
nDir = CBCGPRotationObject::BCGP_ROTATION_LEFT;
RotateChart((CBCGPRotationObject::RotationElement)nDir,10.0,10.0);
}
if(0x8000 & GetKeyState(VK_LSHIFT ))
pChart->SetZoomScrollConfig(BCGPChartMouseConfig::ZSO_WHEEL_PAN);
else
pChart->SetZoomScrollConfig(BCGPChartMouseConfig::ZSO_NONE);
ptOrigin = pHitInfo->m_ptHit;
return false;
}
复制代码
例程中还有对标签显示位置及渐变样式设置,可以选择使用。
例程中使用有MFC扩展库,可以网站下载使用。
例程源代码下载:
(, 下载次数: 0)
上传
点击文件名下载附件
[weixinlianxi]1[/weixinlianxi]
欢迎光临 工控编程吧 (https://www.gkbc8.com/)
Powered by Discuz! X3.4