免编码的绘图软件,业务状态可用配置,可灵活组合海量绘图模板 浮云E绘图

浮云E绘图自由免费、简单好用的绘图SDK,可以快速定制开发各类电路原理图、状态图、流程图、平面布局图等。浮云E绘图支持直线、矩形、圆、三角等基础图元任意组合成复合模板图元,(从这个角度说支持海量绘图模板),并支持业务数据通可配置,一次源码开发适用诸多业务图。

本文主要结束浮云复合图元的业务可配置化实现过程。更多前期资料先参考:

浮云E绘图SDK,快速开发电子图纸、逻辑电路图、工业控制图、工艺流程图等绘图项目

浮云绘图CAD编辑器源码开发之直线、方块、圆等基础图元操作和接口定义

浮云绘图编辑器源码定制之文字、图片基础图元操作及接口定义,用于文本描述及拓扑图、平面布局图开发

 

浮云E绘图快速开发绘图项目的具体流程包括:
1. 使用浮云E绘图编辑器(类似viso绘图)画静态图,并保存为本地绘图数据文件
2. 业务状态配置化,适应各类状态图,后期代码免修改
3. 新建第三方C#/VC等工程,集成FYDC.dll(参看Demo项目源码)
4. 调用API接口函数创建加载图形,关联业务对象,动态更新展示效果。
此4步骤在下文链接有详细描述。

免费好用可快速开发的绘图软件,绘图编辑器+状态可配置化,支持各种状态图,后期免维护

复合图元状态配置以25HZ相敏轨道电路图为例,如下图所示,左侧的复合图元有双圈、保险、可调电阻,右侧复合图元有双圈、Z、HFC、二元二位继电器。

灵活组合复合图元模板,电路图状态图业务定义可配置,浮云E绘图软件源码开发


复合图元可能由任意的直线(直线、多点线)、区块(矩形、圆、三角、扇形等)、文字等基础图元组成。比如滑动电阻是由1个矩形+1条直线+1条多点线组合而成。每类图元的属性如下:

直线|多点线:线条宽度、线颜色、虚实风格、端点类型;

矩形|椭圆|三角|四角|扇形:区域(是否填充、填充颜色)、线条(线条宽度、线颜色、虚实风格)、文字(内容、字体类型、字体大小、字体颜色)

可以根据业务需求,定义各图元的状态,并且配置成文件。

 

1. 复合图元通用状态配置定义示例

复合图元通用配置,即同一条配置行,所有模板图元(如继电器、变压器等)的所有图元(直线、矩形、圆等图元)的线条是一致的表现形式,(矩形、圆、三角形等)区域填充也是一致。

;;类型名称: 状态数;状态0线颜色,线宽度,线风格,填充颜色;状态1线颜色,线宽度,线风格,填充颜色......
CMT1:3;12632256,1,1,0;65280,1,0,16777214;255,1,0,16711935
CMT2:5;12632256,1,2,0;65280,1,0,0;255,1,0,0;16711680,2,0,12632256;16711935,2,0,65280

 “CMT1:3;12632256,1,1,0;65280,1,0,16777214;255,1,0,16711935”的定义是CMT1类型复合图元,有3种状态,状态0时线条是灰色(12632256==RGB(C0,C0,C0))-线宽1-虚线(1)-填充黑色(0==RGB(0,0,0));状态1时线条绿色(65280==RGB(0,255,0))-线宽1-实线(0)-填充白色(16777214);状态2时线条红色(255)-线宽1-实线(0)-填充色粉红(16711935),以滑动电阻为例,此3态展示效果如下所示:

 如果把滑动电阻绑定为CMT2状态类型,则有5态,展示效果如下图所示:

浮云E绘图之滑动电阻复合图元5种状态配置定义及展示效果

 根据业务需要定义好了配置文件后,在业务系统里,我们只需要实时更新状态值CMT1(0~2),CMT2(0~4)即可实现图形的实时动态更新展示效果。

CMT1和CMT2都没有配置修改区域“是否填充”这个属性,滑动电阻本身区域一开始是不填充的,所以设置不同的填充颜色也无效。我们把CMT1绑定到一个原本区域填充的复合图元放大器上,效果如下所示:

 该类配置的源码实现如下:

    public class CompParam : BaseParam
    {
        public int LineColor { set; get; }
        public int LineWidth { set; get; }
        public int LineStyle { set; get; }
        public int FillColor { set; get; }

        public CompParam(int lineColor,int lineWidth, int lineStyle, int fillColor)
        {
            this.LineColor = lineColor;
            this.LineWidth = lineWidth;
            this.LineStyle = lineStyle;
            this.FillColor = fillColor;
        }
    }


    public class CompStatus:BaseStatus
    {
        private List<CompParam> staList = new List<CompParam>();
        public List<CompParam> StatusList { get { return staList; } }

        public override void AddStatus(string sParam, char separator)
        {//状态0是否填充,填充颜色
            int lColor;
            int lWidth;
            int lStyle;
            int fColor;
            string[] arr = sParam.Split(separator);
            Debug.Assert(arr.Length == 4);

            lColor = int.Parse(arr[0]);
            lWidth = int.Parse(arr[1]);
            lStyle = int.Parse(arr[2]);
            fColor = int.Parse(arr[3]);

            CompParam param = new CompParam(lColor,lWidth,lStyle, fColor);
            staList.Add(param);
        }

        public override void SetStatus(FYECMDCView dcView, ShapeElement shape, int status)
        {
            dcView.SetLineColor(shape, staList[status].LineColor);
            dcView.SetLineWidth(shape, staList[status].LineWidth);
            dcView.SetLineStyle(shape, staList[status].LineStyle);
            dcView.SetFillColor(shape, staList[status].FillColor);
        }

        public override void Clear()
        {
            staList.Clear();
        }
     }

2. 复合图元专属状态配置定义示例

复合图元状态配置通用定义是一条配置可以适用与所有复合图元,普适性强,但灵活性不够,有时某特定图元,如上文的滑动电阻(1个矩形+1条直线+1条多点线),加入某种状态形态需要定义为矩形边框线蓝色实线、直线是红色实线、多点线是黑色虚线。这样同时线条但颜色虚实不同,此情况需要知道复合图元有几个基础图元组成,并且每个图元该状态具体形态,需要为该特定的图元类型做专属的状态定义。

;;滑动电阻;状态数;状态0矩形的线颜色,矩形的线宽度,矩形填充颜色,直线颜色,直线风格,多点线颜色,多点线风格;......
HDDZT:3;0,1,12632256,255,0,255,0;,65280,1,65280,0,0,255,0;0,1,65280,255,0,255,1

此方式配置可以满足特定图元的状态定义。但由于每个复合图元由几个基础图元组成,每个基础图元有几个属性都不确定,所以普适性不够,如果需要任意复合图元都支持的配置定义和一套代码支持,得有更丰富的配置文件格式定义。可以参考如下定义:

;;复合图元状态定义名称:状态数目;状态0LineColor#颜色值&LineWith#宽度,IsFill#是否填充&FillColor#填充颜色;状态LineColor#颜色值&LineWith#宽度,IsFill#是否填充&FillColor#填充颜色;......

此格式是在以前(“;”作为状态断分割,“,”作为固定好顺序的类型属性值)的基础上做了调整和丰富:
A. “;”作为状态段分割
B. “,”作为复合图元内部基础图元单体之间的分割,有几个“,”就表示该复合图元有几个基础图元组成
C. “&”作为单个基础图元的属性分割。用约定好的统一的属性名定义(线宽LineWidth、线颜色LineColor、填充颜色FillColor......)
D. “#”作为属性名与属性值的分割。

 

3.复合图元状态刷新

 A. 复合图元的配置读取。读取浮云E绘图编辑器生成的物理图形数据,加载生成逻辑图形数据。

        public void Load()
        {
            shapeElementList = new List<ShapeElement>();
            int count = IFYDC.GetShapeCount(hShapeCanvas);
            if (count <= 0) return;

            ShapeElement shape;
            ShapeCompElement comp = null;
            int curGroup = -1;
            for (int i = 0; i < count; i++)
            {
                IntPtr obj = IFYDC.GetShapeAt(hShapeCanvas, i);

                Array.Clear(bys, 0, bys.Length);
                lock (bys)
                {
                    IFYDC.GetShapeType(obj, ref bys[0]);
                }
                String sType = ByteToString(bys);

                Array.Clear(bys, 0, bys.Length);
                lock (bys)
                {
                    IFYDC.GetShapeTitle(obj, ref bys[0]);
                }
                String sTitle = ByteToString(bys);

                Array.Clear(bys, 0, bys.Length);
                lock (bys)
                {
                    IFYDC.GetShapeName(obj, ref bys[0]);
                }
                String sName = ByteToString(bys);

                Array.Clear(bys, 0, bys.Length);
                lock (bys)
                {
                    IFYDC.GetShapeText(obj, ref bys[0]);
                }
                String sText = ByteToString(bys);

                int groupId = IFYDC.GetShapeGroupId(obj);

                // 创建上层图元对象
                EnShapeType enType = GetDiagramEnType(sType);
                shape = new ShapeElement(obj, enType);
                shape.Handle = obj;
                shape.ShapeType = enType;
                shape.Title = sTitle;
                shape.Name = sName;
                shape.Text = sText;
                shape.Group = groupId;
                shape.Index = i;

                if(groupId <=0)  //基础图元
                {
                    shapeElementList.Add(shape);
                }
                else  //复合图元成员
                {
                    if (curGroup != groupId)     // 新复合图元来了
                    {
                        enType = EnShapeType.Group;
                        comp = new ShapeCompElement(obj, enType);
                        comp.ShapeType = enType;
                        comp.Title = sTitle;
                        comp.Name = sName;
                        comp.Text = sText;
                        comp.Group = groupId;
                        shapeElementList.Add(comp);

                        comp.AddElement(shape);  // 新增复合图元组中的第一个单一图元
                        curGroup = groupId;
                    }
                    else    // 同一组复合图元成员
                    {
                        if (comp != null && shape.Group == comp.Group)
                        {
                            //跳过复合图元的最后一个(仅仅为了基准,是隐藏的)矩形
                            IntPtr nextObj = IFYDC.GetShapeAt(hShapeCanvas, i + 1);
                            if(nextObj != IntPtr.Zero)  //复合图元本不是绘图配置文件里的最后一个图元
                            {
                                Array.Clear(bys, 0, bys.Length);
                                lock (bys)
                                {
                                    IFYDC.GetShapeType(nextObj, ref bys[0]);
                                }
                                String nextType = ByteToString(bys);
                                int nextGroupId = IFYDC.GetShapeGroupId(nextObj);

                                // 复合图元里的最后一个图元
                                if (nextGroupId != comp.Group && sType == "rectangle")
                                    continue;   //跳过,不加载复合图元的最后一个隐藏的矩形图元
                            }
                            else   //复合图元本是绘图配置文件里的最后一个图元
                            {
                                if (sType == "rectangle")   
                                    continue;
                            }

                            comp.AddElement(shape);
                        }

                    }
                }
            }

        }

B. 根据业务对象数据,实时刷新图形展示状态

        private Random rand = new Random();
        private void timer1_Tick(object sender, EventArgs e)
        {
            //实际情况是有一套业务系统和绘图系统,本项目是绘图系统。画的图元都是业务系统存在的业务对象,实时状态数据也是来自业务系统。
            //此Demo不构建完整的业务系统,直接随机改变绘图系统状态值,从而更新绘图的线条、区域、文字等展示效果
            List<ShapeElement> shapes = cmdcView.GetShapeList();
            List<BaseStatus> statuss = staCfg.StatusList;
            foreach (ShapeElement shape in shapes)
            {
                foreach(BaseStatus sta in statuss)
                {
                    if(shape.Title == sta.TypeName)
                    {
                        //实际情况浮云绘图编辑器画图配置的状态数据是由业务系统的业务对象状态数决定的
                        //此Demo仅演示绘图系统不构建完整的业务系统,此处的图元实时状态值直接从图元可用状态数随机
                        int curStatus = rand.Next(sta.StatusCount);
                        if(curStatus != shape.Status)
                        {
                            shape.Status = curStatus;
                            staCfg.SetStatus(cmdcView, shape, curStatus);
                        }
                    }
                }
            }
        }

本文示例完整工程源码下载: 

浮云E绘图高级Demo_业务配置化_复合图元动态更新.zip

posted @ 2022-06-21 14:41  浮云绘图  阅读(183)  评论(0编辑  收藏  举报