# 欢迎来到 Spring FLO 维基！

Spring FLO 是用于图表编辑器的一组[Angular JS](https://angularjs.org/)指令，该编辑器能够以图形方式表示 DSL 并同步该 DSL 的图形和文本表示。图形表示是用[Joint JS](http://jointjs.com/)图形对象完成的，文本表示可以是普通的 HTML 元素（例如`<textarea>`），也可以是基于[CodeMirror](https://codemirror.net/)的功能丰富的编辑器，可通过 FLO 指令获得。

## 如何在应用程序中嵌入 Spring FLO！
Spring FLO 可以通过`flo-editor`指令在任何有角的应用程序中使用。该指令的控制器创建/填充`flo`（[Flo](#flo)）和`definition`（[Definition](#definition)）对象。这些对象是消费客户机与 FLO 进行互操作的方式。`definition`对象是用于读/写 DSL 文本表示的双向绑定。`flo`对象是一个双向绑定，用于处理 DSL 的图形表示（包括控制编辑器功能，例如缩放、网格、布局等）。

在 Spring-FLOrepo:https://github.com/spring-projects/spring-flo/tree/master/samples/spring-flo-sample 的 samples 子文件夹中有一个示例项目-这个示例将在下面的文档中被引用，以提供一个指针来指示每个特性的实际使用情况。

将 FLO 嵌入到 Angular 应用程序中的第一步是简单地在页面或 Angular 模板中使用`flo-editor`指令。
```html
<flo-editor></flo-editor>
```
上面的结果是一个带有编辑器框架的页面：空的调色板和空的画布。有关更复杂的配置，请参见[样本使用情况](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/index.html)。FLO 为编辑器和图形交互定义了 UI，但需要客户端的领域知识才能真正有用。实际上，消费客户端可以提供三种服务来控制 FLO 的行为，其中只有一种是强制性的：

1. 定义由图形表示的元素类型并在域 DSL 文本格式和图形格式之间进行双向转换的服务（必需的）
2. 定义图上节点和链接的可视化表示的服务
3. 控制图形编辑功能的服务

实现应该由客户机以角服务的形式提供，并遵守[延伸点](https://github.com/spring-projects/spring-flo/wiki#all-the-extension-points)中详细说明的特定契约。这些服务是：[元模型服务](#metamodel-service)（必需的），[渲染服务](#render-service)和[编辑服务](#editor-service)。

许多服务功能都有合理的缺省值。在这一节中，我们将讨论一些重要的问题，其中只有一些是强制性的。

为了在调色板中填充内容，FLO 需要了解你的域。在你的图表中，你要连接在一起的“事物”是什么？实现[元模型服务](#metamodel-service)[load()](#load)函数将向 FLO 提供该信息。
```javascript
app.factory('MyPageMetamodelService', ['$log', function($log) {
  return {
    load: function() { $log.info('Return descriptions of the domain specific model elements'); }
  };
}]);
```
样本包括更完整的[元模型服务](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/metamodel-service.js)。一旦定义，服务可以通过名称提供给父作用域（通过父控制器`$scope.metamodelServiceName = 'MyPageMetamodelService';`.）或直接提供给`flo-editor`指令（通过`metamodel-service-name``<flo-editor>`元素上的属性）。让我们修改`flo-editor`指令：
```html
<flo-editor metamodel-service-name="MyPageMetamodelService">
</flo-editor>
```
这也是样本[index.html](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/index.html)的工作方式。将元模型服务连接到编辑器后，将基于从元模型服务获得的元模型对象填充调色板。然后，你应该能够在画布上放置节点，用链接连接节点，并移动它们。请注意，节点和链接的可视化表示可能与期望的相去甚远。实现[渲染服务](#render-service)使你能够自定义该外观和感觉（在没有提供的呈现服务的情况下，FLO 执行一些非常基本的呈现）。一个基本的呈现服务将实现[createnode（）](#createnodemetadata-properties-optional)和[createlink（）](#createlinksource-target-metadata-properties-optional)函数（另见[JS API 联合 DOCS](http://jointjs.com/api)），以获得调色板和画布上形状的正确外观和感觉。
```javascript
app.factory('MyPageRenderService', ['$log', function($log) {
  return {
    createNode: function(metadata) { $log.info('Create and return new Joint JS joint.dia.Element for a graph node'); },
    createLink: function(source, target, metadata, props) { $log.info('Create and return new Joint JS joint.dia.Link for a link between graph nodes'); }
  };
}]);
```
样本包括更完整的[渲染服务](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/render-service.js)。与元模型服务一样，将其连接到`flo-editor`指令
```html
<flo-editor
  metamodel-service-name="MyPageMetamodelService" 
  render-service-name="MyPageRenderService">
</flo-editor>
```
有了基本的渲染处理，我们可以进一步定制：

- 当形状被选中时，在形状周围添加“句柄”。“句柄”是通常放置在形状交互周围的小形状，它将对相关形状执行一些编辑操作，例如删除、调整大小或编辑属性。
- 在节点和链接上提供带有验证指示器（错误/警告）的图形验证。
- 编辑器操作工具栏可能很不错。

在 Render-Service 上实现更多功能可以支持这些特性中的一些特性，但有些特性需要实现最终的键服务[编辑服务](#editor-service):

```javascript
app.factory('MyPageEditorService', ['$log', function($log) {
  return {
    createHandles: function(flo, createHandle, selected) { $log.info('Create handles around selected element'); },
    validateLink: function(flo, cellViewS, portS, cellViewT, portT, end, linkView) { $log.info('Validate link');},
    validateNode: function(flo, node) { $log.info('Validate Node'); },
    preDelete: function(flo, deletedElement) { $log.info('Delete links incident with element being deleted '); },
    interactive: true, /* Consult Joint JS Paper #interactive property doc. Make elements interactive */
    allowLinkVertexEdit: false /* Disallow creation and editing of 'bend-points' in links */
  };
}]);
```
样本包括更完整的[编辑服务](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/editor-service.js)。呈现句柄和验证标记（装饰）必须由呈现服务提供，因为它们是编辑器服务所需要的。在 Spring-FLO 中没有定义用于呈现句柄和错误标记装饰形状的开箱即用呈现。因此，如果在编辑器服务中定义`validateNode()`和`createHandles()`，则必须在呈现服务中实现`createDecoration()`和`createHandle`。
```javascript
app.factory('MyPageRenderService', ['$log', function($log) {
  return {
    createHandle: function(kind, parent) { $log.info('Implement handle node creation'); },
    createDecoration: function(kind, parent) { $log.info('Implement error decoration node creation'); },
    createNode: function(metadata) { $log.info('Create and return new Joint JS joint.dia.Element for a graph node'); },
    createLink: function(source, target, metadata, props) { $log.info('Create and return new Joint JS joint.dia.Link for a link between graph nodes'); }
  };
}]);
```
可以通过 Transclusion 在`flo-editor`指令中以 HTML 形式添加新的工具栏操作，这可能是我们的编辑器服务也插入的情况：
```html
<flo-editor
  metamodel-service-name="MyPageMetamodelService" 
  render-service-name="MyPageRenderService"
  editor-service-name="MyPageEditorService">
  <div>
    <button ng-click="flo.deleteSelectedNode()" ng-disabled="!flo.getSelection()">Delete</button>
    <button ng-click="flo.noPalette = !flo.noPalette" ng-class="{on:!flo.noPalette}">Palette</button>
  </div>
</flo-editor>
```
注意 HTML 中各种处理程序属性中的`flo`对象引用。`flo-editor`指令的控制器将使用用于操作 FLO 编辑器内容的函数填充`flo`对象。

在这个阶段，图形编辑器应该是功能齐全的，但是文本 DSL 呢？

将图形转换为文本 DSL，将文本 DSL 转换为图形的功能必须由客户机提供，这样才能正常工作。这两个函数（[GraphToText（）](#graphtotextflo-definition)和[texttograph（）](#texttographflo-definition)）必须在元模型服务中实现，让我们将它们添加到前面的定义中：
```javascript
app.factory('MyPageMetamodelService', ['$log', function($log) {
  return {
    load: function() { $log.info('Implement load and return metamodel object!'); },
    textToGraph: function(flo, definition) { $log.info('Convert text (definition.text) to graph (flo.getGraph())'); },
    graphToText: function(flo, definition) { $log.info('Convert graph (flo.getGraph()) to text (definition.text)'); }
  };
}]);
```
该示例包括用于“demo”DSL 的[图到文本](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/graph-to-text.js)和[文本到图形](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/text-to-graph.js)的基本实现，这些实现由[元模型服务示例](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/metamodel-service.js)使用。FLO 编辑器在内部维护`definition`对象中的文本 DSL，它只保留在 UI 中公开。文本 DSL 可以通过普通 HTML 元素显示，例如`<textarea>`或基于`dsl-editor`指令的高级[CodeMirror](https://codemirror.net/)。让我们在`dsl-editor`指令的帮助下修改 HTML，使其具有文本 DSL UI。
```html
<flo-editor
  metamodel-service-name="MyPageMetamodelService" 
  render-service-name="MyPageRenderService"
  editor-service-name="MyPageEditorService">
  <div>
    <button ng-click="flo.deleteSelectedNode()" ng-disabled="!flo.getSelection()">Delete</button>
    <button ng-click="flo.noPalette = !flo.noPalette" ng-class="{on:!flo.noPalette}">Palette</button>
  </div>
  <textarea dsl-editor></textarea>
</flo-editor>
```

上面的 HTML 转换为一个页面，其中包含用于按钮（布局和显示/隐藏调色板）的工具栏，用于 DSL 的文本区和用于 DSL 的图形表示的 FLO 编辑器。

## 所有的扩展点：

### 元模型服务
该服务支持使用 FLO 的域来指定在图中连接在一起的元素的种类，以及图应该如何转换为文本表示形式。[样例元模型服务在这里](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/metamodel-service.js)。

#### texttograph（FLO，定义）
基于来自`definition`对象的 DSL 的文本表示设置`flo`对象的图形内容。将文本转换为相应的联合 JS 图内容。将通过`flo`对象函数（如`flo.createLink()`和`flo.createNode()`）填充图形，并使用`flo.clearGraph`

#### GraphtoText（FLO，（定义）
将当前从`flo`对象获得的图形转换为文本表示，然后在`definition`对象上设置文本表示（作为`text`属性）。

#### load（）
返回一个 promise，该 promise 解析为`metamodel`对象。`metamodel`对象布局是元素`group`名称的映射到属于这个`group`的元素的映射。属于`group`的元素的映射是元素的`name`和元素的[元数据对象](https://github.com/spring-projects/spring-flo/wiki#element-metadata)之间的映射 

#### 刷新（）_（可选）_
刷新元模型并返回一个 promise，该 promise 被解析为与[load()](#load)相同的结果。刷新也应该触发事件到`metamodel`更改侦听器。

#### encodeTextToDSL(text)_（可选）_
将 DSL 元素属性值的文本编码为 DSL 所需的格式。示例是将多行文本转换为 DSL 格式所需的单行文本。用于以人类可读的格式显示属性值。

#### decodeTextFroMDSL(dsl)_（可选）_
<gtr="94"/>从 DSL 格式中解码 DSL 元素属性值文本。例如，将单行文本转换为多行文本，即替换转义换行符。用于为用户通过 UI 输入的 DSL 元素设置属性值。

#### subscribe(listener)_（可选）_
将一个侦听器添加到`metamodel`事件。（参见[元模型侦听器]
(#metamodel-listener)）

#### unsubscribe（listener）_（可选）_
删除`metamodel`事件监听器。（参见[元模型侦听器](#metamodel-listener)）

#### isvalidPropertyValue(element, key, value)_（可选）_
检查是否允许为指定元素上的键指定该值。例如：如果键取整数，则不允许使用字母字符。

### Render Service 
服务负责基于元数据（来自[元模型服务](#metamodel-service)）的图形元素的可视化表示。此服务是**可选的**。[示例呈现服务在这里](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/render-service.js).

#### createNode(metadata, properties) _(可选)_
创建联合 JS 图节点模型对象的实例（`joint.dia.Element`）。可能影响节点模型对象类型的参数是元素的[metadata](#element-metadata)和属性映射（如果有传入的话）。

#### createLink(source, target, metadata, properties)_（可选）_
创建一个联合 JS Graph 链接模型对象的实例（`joint.dia.Link`）。可能影响链接模型对象类型的参数是元素的[metadata](#element-metadata)、属性映射（如果有传入）、源元素和目标元素 

#### createHandle(kind, parent) _（可选）_
创建联合 JS 图节点模型对象的实例（`joint.dia.Element`）。句柄的一个示例是显示在与父形状交互的旁边的形状，该形状导致在父形状上进行一些编辑操作。可能影响句柄模型对象类型的参数是`kind`类型的`string`（用户定义，i。e.`delete`，`resize`等。）和句柄的`parent`元素。只有在实现了 Editor Service`createHandles()`函数的情况下，框架才调用该函数。

#### createDecoration(kind, parent) _（可选）_
创建一个联合 JS 图节点模型对象的实例（`joint.dia.Element`）。装饰的一个例子是显示在父形状上的验证标记。可能影响装饰模型对象种类的参数是`kind`类型的`string`和装饰的`parent`元素。注意，`kind`参数来自框架（与`createHandle`函数不同）。只有在实现了 Editor Service`validateNode()`函数的情况下，框架才调用该函数。（目前装饰只是验证错误标记）。

#### initializeNewNode(node, context) _（可选）_
对新创建的图`node`执行任何附加的初始化，当`node`已经添加到联合 JS 图中并在画布上呈现时，E。g.元素的 SVG DOM 结构是可用的。`context`参数是一个对象，其`paper`和`graph`属性适用于`node`。当 SVG DOM 附加到页面 DOM 时，在节点上执行任何类型的初始化都是有用的。例如：将字符串标签放入形状中，在形状上使用角度指示，添加 DOM 侦听器等。

#### initializeNewLink(link, context)_（可选）_
在`link`已经添加到联合 JS 图并在画布上呈现时，执行新创建的图`link`的任何附加初始化。g.元素的 SVG DOM 结构是可用的。`context`参数是一个对象，其`paper`和`graph`属性适用于`link`。当链接的 SVG DOM 附加到页面 DOM 时，在链接上执行任何类型的初始化都是有用的。例如：在形状上使用角度指令，添加 DOM 侦听器等。

#### initializeNewHandle(handle, context) _（可选）_
在`handle`已添加到联合 JS 图并在画布上呈现时，对新创建的图`handle`执行任何附加的初始化。g.元素的 SVG DOM 结构是可用的。`context`参数是一个对象，其`paper`和`graph`属性适用于`handle`。当一个句柄形状的 SVG DOM 被追加到页面 DOM 时，对它执行任何类型的初始化都是有用的。例如：将字符串标签放入形状中，在形状上使用角度指示，添加 DOM 侦听器等。

#### initializeNewDecoration(decoration, context) _（可选）_
在`decoration`已添加到联合 JS 图并在画布上呈现时，对新创建的图`decoration`执行任何附加的初始化。g.元素的 SVG DOM 结构是可用的。`context`参数是一个对象，其`paper`和`graph`属性适用于`decoration`。当装饰形状的 SVG DOM 附加到页面 DOM 时，对它执行任何类型的初始化都是有用的。例如：将字符串标签放入形状中，在形状上使用角度指示，添加 DOM 侦听器等。

#### getNodeView() _（可选）_
返回`joint.dia.ElementView`的实例。它也可以是`function(element)`形式的函数，该函数接受一个元素模型，并应该返回一个负责将该模型呈现到屏幕上的对象。在正常情况下，这个功能不需要实现，由框架创建的联合 JS 视图对象应该足够了。如果不同的节点需要不同的联合 JS 视图，或者视图有一些特殊的呈现（I。e.嵌入的 HTML 元素）。参见[联合 JS 文件选项](http://jointjs.com/api#joint.dia.Paper:options)

#### getLinkView() _（可选）_
返回联合 js 的实例`joint.dia.LinkView`。默认值为`joint.dia.LinkView`。它也可以是`function(link)`窗体的函数，它接受一个链接模型，并且应该返回一个负责将该模型呈现到屏幕上的对象。在正常情况下，这个功能不需要实现，由框架创建的联合 JS 视图对象应该足够了。如果不同的链接需要不同的联合 JS 视图，或者视图有一些特殊的呈现（I。e.模式应用于行-`joint.shapes.flo.PatternLinkView`）。参见[联合 JS 文件选项](http://jointjs.com/api#joint.dia.Paper:options)

#### layout(paper) _（可选）_
负责布局可以从传入`paper`参数（`paper.model`）中派生出的联合 JS 图。

#### handleLinkEvent(paper, event, link) _（可选）_
负责处理`event`上发生的、属于在联合 JS 中传递的`link`对象的`paper`。`event`参数是一个`string`，具有可能值：`'add'`、`'remove'`或联合 JS 本地链接更改事件，例如`'change:source'`、`'change:target'`等。参见[联合 JS Link 活动](http://jointjs.com/api#joint.dia.Link:events)

#### isSemanticProperty(propertyPath, element) _（可选）_
对于`string`属性路径`propertyPath`在`element`上如果图形需要执行一些基于`propertyPath`值变化的可视化更新（对于`props`下的属性不需要`true`在`element`上）。可视更新由[RefreshVisuals（）](#refreshVisuals)执行。属性路径`propertyPath`是相对于联合 JS 元素`attrs`属性 

#### refreshVisuals(element, propertyPath, paper) _（可选）_
执行一些图形的可视化更新，或者更有可能，传入的`element`基于`propertyPath`指定的变更属性显示在联合 js 上`paper`<

#### getLinkAnchorPoint(linkView, view, port, reference) _（可选）_
此函数允许你自定义链接的锚点是什么。函数必须返回一个点（带有`x`和`y`属性），链接在这个点上锚定到元素。该函数获取链接视图、元素视图、链接应该粘贴的`port`（SVG 元素）和一个参考点（链接另一侧的最近顶点或锚点）。

### 编辑器服务
负责为 FLO 编辑器提供丰富的编辑功能的服务，例如围绕选定形状的句柄、自定义的拖放行为、实时和静态验证。此服务是**可选的**。[示例编辑服务在这里](https://github.com/spring-projects/spring-flo/blob/master/samples/spring-flo-sample/src/main/resources/static/js/editor-service.js)

#### createHandles(flo, createHandle, selected) _（可选）_
当节点被选中并且可以显示句柄时调用。句柄通常是`selected`编辑器交互中`flo`联合 JS 节点周围的小形状，用于修改`selected`节点上的属性，即调整大小或删除句柄。调用`createHandle(selected, kind, clickHandlerFunction, coordinate)`函数创建一个句柄。`kind`参数是一种`string`类型的句柄，`clickHandlerFunction`是在单击句柄时执行的，`coordinate`是放置句柄形状的位置。注意，如果实现了这个函数，那么 Render Service`createHandle(...)`函数也必须实现。当需要时，框架将自动删除句柄，因此在客户端无需担心这一点。

#### validatePort(paper, view, portView)_（可选）_
如果用户单击端口，请决定是否创建链接。`portView`是表示端口的 DOM 元素，`view`是端口的父联合 JS 视图对象，在联合 JS`paper`中显示 

#### validateLink(flo, cellViewS, portS, cellViewT, portT, end, linkView) _（可选）_
决定是否允许或不允许源视图/端口（`cellViewS`/`portS`）和目标视图/端口（`cellViewT`/`portT`）之间的连接。`end`要么是`'source'`要么是`'target'`，它告诉我们拖动链接的哪一端。这对于定义例如从元素 A 的端口输出开始的链接是否可以指向 Elmement B 的端口引脚很有用。

#### calculateDragDescriptor(flo, draggedView, targetUnderMouse, coordinate, context) _（可选）_
在`coordinate`上拖动一个节点`draggedView`时调用。还有`flo`Object 参数和`context`Object，它目前仅具有`boolean`属性`palette`来表示是否在调色板或画布上进行拖放。函数应该返回一个[拖动描述符对象](#drag-descriptor)。

#### handleNodeDropping(flo, dragDescriptor) _（可选）_
在拖动的节点被拖放时执行必要的图形操作。`dragDescriptor`[拖动描述符](#drag-descriptor)应该具有强制信息，说明正在拖动的内容和正在丢弃的位置。`flo`对象参数将有助于对图进行必要的修改 

#### showDragFeedback(flo, dragDescriptor) _（可选）_
当将一个节点拖过某个图元素（节点或链接）时，任何自定义的视觉反馈都可以由该函数绘制。`dragDescriptor`参数有一个[拖动描述符对象](#drag-descriptor)，其中包含有关正在进行拖动的完整信息，并且`flo`对象将有助于使用联合 JS

#### hideDragFeedback(flo, dragDescriptor) _（可选）_
删除由[showdragfeedback（）](#show-drag-feedback)绘制的任何自定义视觉反馈。具有相同的参数。

#### validateNode(flo, node) _（可选）_
返回一个`javascript`数组的`string`错误消息，这些错误消息是在`node`编辑器 

#### preDelete(flo, deletedElement) _（可选）_
之前调用的指定删除`deletedElement`允许在此之前进行额外的 tidyup。例如：删除与将要删除的元素相关的任何依赖的联合 JS 图元素。

#### interactive _（可选）_
如果设置为`false`，则禁用与元素和链接的交互。如果它是一个函数，那么它将在单元格视图的作用下被调用，并调用它在（`'pointerdown'`，`'pointermove'`，...）中求值的方法的名称。如果这样的函数返回的值是假的，则将禁用该操作的交互。对于链接，交互对象的一些特殊属性对于禁用默认行为非常有用。这些性质是：`vertexAdd`，`vertexMove`，`vertexRemove`和`arrowheadMove`。通过将这些属性中的任何一个设置为 false，你可以禁用链接上的相关默认操作。

#### allowLinkVertexEdit _（可选）_
如果设置为`false`链接顶点（或弯曲点）的创建或编辑（例如移动）在编辑器中是不允许的。

## 数据结构引用：

### FLO 
这个对象是由`flo-editor`指令控制器创建的，它包含各种特定于编辑器的属性和函数。

#### scheduleUpdateGraphRepresentation()
基于文本 DSL 表示，调度图 DSL 表示的异步更新。####UpdateGraphRepresentation（）基于文本 DSL 表示异步更新图形 DSL 表示。将返回一个承诺，当更新完成时，该承诺将得到解决。

#### updateGraphRepresentation()
基于图形 DSL 表示异步更新文本 DSL 表示（`definition`对象）。将返回一个承诺，该承诺在更新完成时得到解决。####PerformLayout（）在画布上排列图形的节点和链接。

#### updateTextRepresentation()
基于图的DSL表示法，异步更新文本DSL表示法（`definition`对象）。当更新完成时，会返回一个承诺，这个承诺会被解决。

#### performLayout()
在画布上安排图形的节点和链接。

#### ClearGraph（）
清除了所有节点和链接的画布。与此同步还会导致文本 DSL 表示被清除。

#### getgraph（）
返回对画布内容的`joint.dia.Graph`对象实例的引用（图形模型，请参见[联合 JS 图形 API ](http://jointjs.com/api#joint.dia.Graph)

#### getpaper（）
返回对画布的 joint.dia.paper 对象实例的引用（图形视图对象，参见[联合 JS 纸 API ](http://jointjs.com/api#joint.dia.Paper)

#### enableSyncing(enable)
基于传递的`boolean`参数`enable`启用或禁用文本和图形 DSL 表示同步机制。当文本 DSL 表示 UI 折叠时非常有用。

#### getSelection（）
返回画布上当前选择的图形模型元素（节点或链接）

#### zoomPercent(percent)
画布上的缩放值的Angular getter/setter函数。如果提供了整数`number`参数，则设置缩放百分比值。如果缺少参数，返回整数百分比值（getter模式）。

#### gridSize(gridSize)
角度 getter/setter 函数，用于画布上的缩放值。如果提供了整数`number`参数，则设置 zoom% 值。如果参数丢失（getter 模式）#####GridSize 角度 getter/setter 函数，则返回整数 % 值，用于画布网格大小（以像素为单位）。如果提供了整数`number`参数`gridSize`，则设置网格宽度值。如果参数丢失（getter 模式），则返回当前网格大小值.请注意，将网格宽度设置为`1`会关闭网格。无效的`gridSize`值被忽略 

#### getMinZoom()
返回整数`number`缩放百分比的最小允许值。用于设置缩放控件的适当范围。画布上的缩放控件所需的（如果设置为显示的话）.默认情况下，该值等于`5`（5%）。

#### getMaxZoom()
返回整数`number`最大允许缩放百分比的值。用于设置缩放控件的适当范围。画布上的缩放控件所需的（如果设置为显示的话）.默认情况下，该值等于`400`（400%）。

#### getZoomStep()
返回整数`number`缩放 % 递增/递减步骤。画布上的缩放控件所需的（如果设置为显示的话）.默认情况下，该值等于`5`（5% 的递增/递减值）。

#### fitToPage()
将整个图形放入画布的视口中（即不需要滚动来寻找画布上的内容）。适当地调整缩放级别和滚动位置

#### readOnlyCanvas(newValue)
将整个图形适合 Canvas 的视口（即无需滚动来查找 Canvas 上的内容）。为画布“只读”属性调整缩放级别和滚动位置 ####readonlycanvas 角度 getter/setter 函数。只读画布不允许任何用户编辑画布上任何形状的交互。根据传入的`newValue`参数设置只读属性，结果画布立即切换只读状态的行为。如果参数丢失（getter 模式），则返回当前的“只读”状态值。

#### createNode(metadata, properties, location)
基于图节点`metadata`对象（参见[元素元数据](#element-metadata)）、`properties`键-值对映射和画布上的位置（对象带有`x`和`y`属性）创建并返回新创建的联合 JS 图节点（对象）。新的节点还被添加到 FLO 画布联合 JS，因此也被添加到联合 JS，并在此函数返回结果之前立即出现在画布上。####CREATELINK（源、目标、元数据、属性）；基于图形链接`source`和`target`之间创建并返回新创建的 JS 联合图形链接（实例`joint.dia.Link`）（类型为`joint.dia.Element`的节点）`metadata`对象（参见[元素元数据](#element-metadata)），`properties`键值对映射。新的链接还被添加到 FLO 画布联合 JS，因此也被添加到联合 JS，并在此函数返回结果之前立即出现在画布上。

#### createLink(source, target, metadata, properties);
根据图形链接的`metadata'对象（见[Element Metadata](#element-metadata)）、`properties'键值对地图，在`source'和`target'节点（类型为`joint.dia.Element'）之间创建并返回新的Joint JS图形链接（`joint.dia.Link`实例）。新的链接也被添加到Flo画布的Joint JS`graph`中，因此也被添加到Joint JS`paper`中，并在此函数返回结果之前立即出现在画布上。

	
### 定义
此对象保存与 DSL 的文本表示相关的数据。通常，对于 DSL 文本，这个对象至少应该具有`text`类型的`string`属性，但是它也可以具有其他属性，这些属性可以由客户机的元模型服务图-文本转换函数添加。

### 元模型侦听器
通常通过 HTTP 请求异步加载元模型对象。如果服务缓存了元数据，那么注册侦听器可能会很有用。如果元模型发生了变化，FLO 编辑器调色板将自动重建自身。
```javascript
{
  metadataError: function(data) {
    /* Error loading metadata has occurred */
  },
  metadataRefresh: function() {
    /* Metadata is about to be refreshed */
  },
  metadataChanged: function(data) {
    /* New metadata is available */
  }
}
```
### 拖动描述符 
API 客户机可以自由地向此对象添加额外的属性（即可能有助于绘制视觉反馈）
```javascript
{
  context: context, /* String 'palette' or 'canvas' */
  source: {
    cell: draggedNode, /* Joint JS graph node being dragged */
    selector: selector, /* Optional. Joint JS CSS class selector for the subelement of the dragged node*/,
    port: portType /* Optional. Involved port DOM element type attribute value == port Joint JS markup 'type' property */
 },
 target: {
   cell: targetNode, /* Joint JS graph node target under mouse element */
   selector: selector, /* Optional. Joint JS CSS class selector for the element under mouse within the targetNode */
   port: portType /* Optional. Sub-element under mouse is a port. Port DOM element type attribute value == port Joint JS markup 'type' property */
 },
};
```

### 联合 JS 图节点标记
```javascript
model: /* Joint JS model object for a module shape */
  ...
  attributes:
    ...    
    angle:  0,  /* Joint JS property - rotation angle */
            
    id:     "02be8001-ea1e-4f30-a94e-9503da5964b5"  /* Joint JS property - element model UUID
            
    position:       /* Joint JS property - coordinates of the shape's bounding rectangle */
      x:  119                                     
      y:  46
                
    size:           /* Joint JS property - size of the shape's bounding rectangle */
      height: 40                                  
      width:  120
                
    type:   "sinspctr.IntNode"  /* Flo property - internal, type (node, link, handle, decoration, etc) */
            
    z:      1   /* Joint JS property - z-index of the shape
            
    ports:              /* Joint JS property - internal, ports available on the shape */
      input:
        id: "input"
      output:
        id: "output"
      tap:
        id: "tap"
                    
      attrs:  /* Joint JS property - user defined rendering constructs and semantic properties */
            
        .               /*\                                                                 */
        .border         /* \                                                                */
        .box            /*  \                                                               */
        .input-port     /*   \                                                              */
        .label1         /*    \___User defined rendering constructs implied by the markup   */ 
        .label2         /*    /                                                             */
        .output-port    /*   /                                                              */
        .shape          /*  /                                                               */
        .stream-label   /* /                                                                */
        .tap-port       /*/                                                                 */
                                 
        metadata:                   /* Flo property. Node metadata supplied by Metamodel Service */
                                    
        props:                      /* Flo property. Semantic properties of the element. Name <-> value pair map */
          dir:    "/Users/x/tmp"
          file:   "temp.tmp"
          debug:  true
                    
      ...
  ...
...
```

### 元素元数据
由元模型服务提供的图形元素元数据
```javascript
metadata: {
                
  get:    function(), /* function taking property key string as a parameter */ 
                      /* Returns promise that resolves to the metadata object of the property */
                      /* See snippet below showing the format of a property metadata */
                                                            
  group:  "source",   /* Category/Group of an element. Translates into palette groups of elements */

  name:   "file",     /* Name or Type of an element (should be unique within its group) */
                                                                                
  metadata:  { /* Additional metadata for the element */
    titleProperty: 'props/title', /* Property to be displayed at the top of all properties in properties Div */
    noEditableProps: false, /* If true then element doesn't have properties to edit and properties Div is not shown */
    allow-additional-properties: true, /* Allows user to create new properties for element in the properties Div */
  }

}
```
元素的属性元数据应该如下所示
```javascript
  properties: {
        info: {
            defaultValue:       null,
            description:        "General information about the file",
            id:                 "info",
            name:               "info",
            shortDescription:   "File Info"
        },
            
        language: {
            defaultValue:       "English"
            description:        "Language of the file contents",
            id:                 "language",
            name:               "language",
            shortDescription:   "Text Language"
        },
        ...
```