| 构建仪表、图表控件的绘制框架 下载源代码 开发环境: VS2003 + Windows XP SP2 Demo截图 编写图形相关的控件需要完成两部分:1 绘制;2 与窗口类(泛指)集成使之成为控件。本文重点在于“绘制”部分,提出一个较灵活的框架。用VC的GDI+实现框架,并在Demo中简单封装成圆表和直表控件。图一是要实现的目标(圆表、直表等仪表,指示灯,图表,旋钮,滑块等),由这些目标,经需求分析后,设计出框架。 框架的建立 “如果说我比别人看得更远些,那是因为我站在了巨人的肩上”。.Net上开源图表控件比较多,在这里我们分析一下MS Graph Demo。图二 是其绘制Pie图表的类图。 PieSlice表示Pie中的单个扇形,_value用来计算百分比,_color是此扇形的填充颜色。 框架由三个基础类YPaintBase,YShapeBase和YFillBase组成。其中YFillBase是填充基础类(简称“填充”),它负责对象颜色、图像的填充,边框等。YShapeBase是基本图形基础类(简称“形状”),由此类派生出简单的基本图形,如:圆,三角,五角星,特殊指针样式……。YPaintBase是逻辑组合基础类(简称“逻辑”),由YPaintBase把YShapeBase和YFillBase进行组合,构建出复杂图形,而复杂图形可由YPaintBase的派生类再次组合。 由YShapeBase派生出,将YPointer对象的pShape指向YRectangle对象,就可以得到矩形指针。同理将YBackground对象的pShape指向YRectangle对象,就得到了矩形背景(图五)。 如果需要升级,添加新的形状如三角形YTriangle(图六),也就相应得到了三角型指针和三角形背景。 同样由YFillBase派生一种特殊的图片填充YFillImage(图七),其它地方的代码不用修改,就可以得到用这种填充的任意形状指针和背景。 在实际项目中,类似指针,背景的元素很多,应用此框架可以使编码减少,功能倍增,易于升级、维护。 下图演示应用框架构建类似MS Graph Demo的Pie图表和Bar图表,是不是很容易加入填充图像和在Pie图Bar图间转换^_^。 框架的在绘制仪表控件中的应用 1、YFillBase和YShapeBase的配合使用: 2、透明仪表罩的绘制 表罩由2个YRange和1个YEllipes,YRange和YEllipes用特定填充。 FillGradient glassFill;glassFill.Border.Hide();3、刻度的绘制 由于框架的原因,可以非常方便的更改刻度的形状和填充。(加入一个最基本的刻度) YScaleTextCircular是环绕文字。 4、圆表,直表与刻度对应的文字 环绕文字与环形刻度一般同时出现,这就要求环绕文字必须遵循某种规则,使文字和刻度不重叠上,且很自然。 “向下”文字位置的定义 图 "向心"文字位置定义
YScaleTextCircular ScaletextCircular;YTextHelper* pScaletextHelper = NULL;pScaletextHelper = new YTextHelper;pScaletextHelper->SetSize(10.f);pScaletextHelper->FontColor.SetColor(128,128,128);ScaletextCircular.AddText(pScaletextHelper);pScaletextHelper = new YTextHelper;pScaletextHelper->SetBold(TRUE);pScaletextHelper->SetSize(12.f);pScaletextHelper->SetFontName("黑体");pScaletextHelper->FontColor.SetColor(255,44,44);ScaletextCircular.AddText(pScaletextHelper);pScaletextHelper = new YTextHelper;pScaletextHelper->FontColor.SetColor(51,51,255);ScaletextCircular.AddText(pScaletextHelper);ScaletextCircular.SetType(1);ScaletextCircular.AddText("你");ScaletextCircular.AddText("有没有");ScaletextCircular.AddText("想过");ScaletextCircular.AddText("罐头");ScaletextCircular.AddText("的");ScaletextCircular.AddText("感受");ScaletextCircular.AddText("?");ScaletextCircular.SetDefault(FALSE);ScaletextCircular.SetOrigin(point_this.X,point_this.Y);ScaletextCircular.SetRadius((int)(cs_this.Width*0.3f));ScaletextCircular.SetPlacement(Inside);ScaletextCircular.Draw(g);pScaletextHelper = NULL; 绘制线型文字水平文字// ∧// │// Outside │ Inside// │// │ Inside// └───────>// Outside //YScaleTextXY m_ScaleText;YTextHelper* pScaletext_helper = NULL;pScaletext_helper = new YTextHelper;pScaletext_helper->SetSize(8.5f);pScaletext_helper->SetAngle(-30);pScaletext_helper->SetHorizontal(StringAlignmentFar);m_ScaleText.AddText(pScaletext_helper);m_ScaleText.SetMin(0);m_ScaleText.SetMax(600);m_ScaleText.SetBoolY(FALSE);m_ScaleText.SetOrientation(TRUE);m_ScaleText.SetOrigin(30.f,50.f);m_ScaleText.SetLength(380.f);m_ScaleText.Draw(g);m_ScaleText.AddText("一月");m_ScaleText.AddText("二月");m_ScaleText.AddText("三月");m_ScaleText.AddText("四月");m_ScaleText.AddText("五月");m_ScaleText.AddText("六月");m_ScaleText.AddText("七月");m_ScaleText.SetDefault(FALSE);m_ScaleText.SetOrigin(30.f,80.f);m_ScaleText.Draw(g);pScaletext_helper = NULL; |











