一、选择适合的软件
在绘制功能结构图前,首要任务就是选择合适的软件。主流的功能结构图绘制软件有Visio、Lucidchart、OmniGraffle等。选择软件时需考虑自身使用习惯以及软件的功能性、易用性及价格等,以及该软件是否支持导出多种格式的文件以定制化输出。
二、绘制框架结构
在绘制功能结构图时,需要首先在画布上绘制框架结构,即整个结构的组成部分。这些部分可以是具体的子功能模块或某种设备组件。绘制时可以选用预先设计好的图形模板,也可以自行设计符合自身习惯的自定义模板。这里以Visio为例,给出如下代码示例:
Sub DrawFramework() '新建页面 Set currentPage = Application.ActiveDocument.Pages.Add '设置页面预定义尺寸 Set pageSize = currentPage.PageSheet.Cells("PageWidth") pageSize.Result(VisUnitCodes.visInches) = 8.5 Set pageSize = currentPage.PageSheet.Cells("PageHeight") pageSize.Result(VisUnitCodes.visInches) = 11 '设置页面背景颜色 currentPage.PageSheet.Cells("PageBackColor").FormulaU = """253,253,223""" '在页面上添加基本框架结构 Set myshape = currentPage.DrawRectangle(1.25, 1.25, 2.5, 2.25) myshape.Text = "Function A" Set myshape = currentPage.DrawRectangle(4, 1.25, 5.25, 2.25) myshape.Text = "Function B" Set myshape = currentPage.DrawRectangle(1.25, 8.25, 2.5, 9.25) myshape.Text = "Function C" Set myshape = currentPage.DrawRectangle(4, 8.25, 5.25, 9.25) myshape.Text = "Function D" End Sub
三、绘制功能模块
在框架结构确定后,需要对每个子部分进行细化,即绘制具体的功能模块。在绘制时需考虑该模块的输入、输出及实现方式。不同软件中,绘制功能模块的方式不同,但都需表示清楚模块的功能及其属性。
以Lucidchart为例,给出如下代码示例:
function drawModule(x, y, name, inputs, outputs) { //绘制模块框架 var mod = new joint.shapes.standard.Rectangle(); mod.position(x, y); mod.resize(80, 50); //插入模块名称 var nameLabel = new joint.shapes.standard.TextBlock(); nameLabel.position(x + 40, y + 6); nameLabel.resize(80, 20); nameLabel.attr('text/text', name); //绘制输入输出端口 var inputPorts = []; for (var i = 0; i < inputs; i++) { var input = new joint.shapes.standard.Circle(); input.position(x, y + 15 + i*15); input.resize(10, 10); mod.embed(input); input.ports.item(0).label(Colors.inputLabel); inputPorts.push(input); } var outputPorts = []; for (var i = 0; i < outputs; i++) { var output = new joint.shapes.standard.Circle(); output.position(x + 80, y + 15 + i*15); output.resize(10, 10); mod.embed(output); output.ports.item(0).label(Colors.outputLabel); outputPorts.push(output); } mod.label(0, ' ', { position: { distance: -20 } }); mod.label(1, ' ', { position: { distance: 20 } }); mod.addTo(graph); return {module: mod, inputs: inputPorts, outputs: outputPorts}; }
四、连线
在功能结构图中,每个部分都需明确其与其他组件的联系。连线可以表示数据及传递方向等,使整个结构更加清晰易懂。较为直观的连线方式是使用箭头连接,箭头指向方向一般表示数据流动方向。在连线时需注意线条的粗细、颜色及箭头的大小、颜色等。
以OmniGraffle为例,给出如下代码示例:
function drawLine(fromx, fromy, tox, toy, color, weight) { //绘制连线 var line = new joint.dia.Link({ source: { x: fromx, y: fromy }, target: { x: tox, y: toy }, attrs: { '.connection': { stroke: color, 'stroke-width': weight || 1, 'stroke-dasharray': '0' }, '.marker-target': { fill: color, d: 'M 10 0 L 0 5 L 10 10 z' } }, smooth: true, router: { name: 'orthogonal' }, connector: { name: 'rounded' } }); graph.addCell(line); }
五、调整布局
功能结构图绘制完毕后,为了使它更加美观、易读,在布局方面也有或多或少的调整工作。较为常见的布局方式有左对齐、右对齐、居中等,但需注意不同软件具有不同的布局方式。此外,还需注意控制文字和组件的大小及位置,以使图形比例协调,细节美观。
以Visio为例,给出如下代码示例:
Sub AdjustLayout() '设定组件位置及大小 Set shapeA = currentPage.Shapes.Item("Function A") shapeA.Cells("PinX").Result(VisUnitCodes.visInches) = 2 shapeA.Cells("PinY").Result(VisUnitCodes.visInches) = 2 shapeA.Cells("Width").Result(VisUnitCodes.visInches) = 1.25 shapeA.Cells("Height").Result(VisUnitCodes.visInches) = 1 Set shapeB = currentPage.Shapes.Item("Function B") shapeB.Cells("PinX").Result(VisUnitCodes.visInches) = 5 shapeB.Cells("PinY").Result(VisUnitCodes.visInches) = 2 shapeB.Cells("Width").Result(VisUnitCodes.visInches) = 1.25 shapeB.Cells("Height").Result(VisUnitCodes.visInches) = 1 Set shapeC = currentPage.Shapes.Item("Function C") shapeC.Cells("PinX").Result(VisUnitCodes.visInches) = 2 shapeC.Cells("PinY").Result(VisUnitCodes.visInches) = 8 shapeC.Cells("Width").Result(VisUnitCodes.visInches) = 1.25 shapeC.Cells("Height").Result(VisUnitCodes.visInches) = 1 Set shapeD = currentPage.Shapes.Item("Function D") shapeD.Cells("PinX").Result(VisUnitCodes.visInches) = 5 shapeD.Cells("PinY").Result(VisUnitCodes.visInches) = 8 shapeD.Cells("Width").Result(VisUnitCodes.visInches) = 1.25 shapeD.Cells("Height").Result(VisUnitCodes.visInches) = 1 Set connector1 = currentPage.Shapes.Item("Connector1") connector1.Cells("BeginX").Result(VisUnitCodes.visInches) = 2.25 connector1.Cells("EndX").Result(VisUnitCodes.visInches) = 3.75 connector1.Cells("BeginY").Result(VisUnitCodes.visInches) = 2.5 connector1.Cells("EndY").Result(VisUnitCodes.visInches) = 2.5 Set connector2 = currentPage.Shapes.Item("Connector2") connector2.Cells("BeginX").Result(VisUnitCodes.visInches) = 5.25 connector2.Cells("EndX").Result(VisUnitCodes.visInches) = 6.75 connector2.Cells("BeginY").Result(VisUnitCodes.visInches) = 2.5 connector2.Cells("EndY").Result(VisUnitCodes.visInches) = 2.5 Set connector3 = currentPage.Shapes.Item("Connector3") connector3.Cells("BeginX").Result(VisUnitCodes.visInches) = 2.25 connector3.Cells("EndX").Result(VisUnitCodes.visInches) = 3.75 connector3.Cells("BeginY").Result(VisUnitCodes.visInches) = 8.5 connector3.Cells("EndY").Result(VisUnitCodes.visInches) = 8.5 Set connector4 = currentPage.Shapes.Item("Connector4") connector4.Cells("BeginX").Result(VisUnitCodes.visInches) = 5.25 connector4.Cells("EndX").Result(VisUnitCodes.visInches) = 6.75 connector4.Cells("BeginY").Result(VisUnitCodes.visInches) = 8.5 connector4.Cells("EndY").Result(VisUnitCodes.visInches) = 8.5 '对齐 currentPage.AlignHorizontal VisSelectionTypes.visSelTypeAll, VisHorizontalAlignTypes.visHorzAlignCenter currentPage.AlignVertical VisSelectionTypes.visSelTypeAll, VisVerticalAlignTypes.visVertAlignMiddle End Sub