logo GoJS教程 2019 我也要发布文档

坐标系统


GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图,且极大地简化您的JavaScript / Canvas 程序。

GoJS现已更新至最新版本2.0.17发布,修复了一些bug,增强用户体验,赶快下载试试吧~

点击下载GoJS最新试用版

坐标系统

一图使用两个主要的坐标系绘制时部分:文档和查看坐标。此外,每个小组一个内部分具有它的元素使用其自己的坐标系。

GoJS中的所有坐标系都具有Point,其中X的值向右递增,而Y的值向下递减

文件和检视座标

零件的Part.location和GraphObject.actualBounds和GraphObject.position在文档坐标中。因此,可以保存在模型的节点数据中的Point通常位于文档坐标中:

diagram.model.nodeDataArray = [
    { key: "Alpha", loc: "0 0" },
    { key: "Beta", loc: "100 50" }
  ];

但是,在文档坐标中Part.location为(0,0)的Part 并不总是绘制在用户在页面中看到的HTML Div元素的左上角。当用户滚动图时,将需要在画布上的其他位置绘制该零件。并且,如果用户放大以使零件看起来更大,则零件将在画布中的不同点绘制。但是,随着用户滚动或缩放图表,Part.location不会更改值。

画布中的点位于视图坐标中:距左上角的距离(与设备无关的像素)。文档坐标和视图坐标之间的差异主要由两个Diagram属性控制: Diagram.position和Diagram.scale。滚动和平移更改Diagram.position。放大或缩小将更改Diagram.scale。您还可以通过调用Diagram.transformDocToView和Diagram.transformViewToDoc在坐标系之间进行转换。但是,视图坐标中很少有属性和方法参数或返回值-几乎所有内容都在文档坐标或面板坐标中。

该视口是在画布上可见的文档的区域。该区域可作为Diagram.viewportBounds使用。请注意,视口边界在文档坐标中,而不在视图坐标中!视口的左上角在视图坐标中为(0,0),但在文档坐标中为Diagram.position。视口的右下角在视图坐标中位于画布的(宽度,高度)处。文档坐标中视口的右下角取决于Diagram.scale。

作为在整个文档的上下文中显示视口的示例,“ 概述 ”正是这样做的。看一下组织结构图样本中的概述。概述显示了主图的整个文档。洋红色框显示了整个文档中主图的视口。滚动或平移主图时,视口将移动。缩小时,视口会变大。

为了更好地理解文档坐标和视口坐标之间的区别,请查看以下图表:

流程图控件GoJS教程:坐标系统

坐标系示例

本示例显示了文档坐标中三个不同位置的三个零件。将鼠标移到每个零件上,以查看这些位置在视图坐标中的位置。最初,您将看到文档和视图坐标之间的唯一区别是恒定偏移量。该偏移量是由于Diagram.padding导致的,它在画布的边缘和图对象所在的边缘之间留了一些空间。这也是由于Part.locationSpot的位置位于“ +”形状的中心,而不是整个Part的左上角。

// read-only to avoid accidentally moving any Part in document coordinates
  diagram.isReadOnly = true;
 
  diagram.nodeTemplate =
    $(go.Part,  // no links or grouping, so use the simpler Part class instead of Node
      {
        locationSpot: go.Spot.Center, locationObjectName: "SHAPE",
        layerName: "Background",
        mouseOver: function (e, obj) { showPoint(obj.part.location); },
        click: function (e, obj) { showPoint(obj.part.location); }
      },
      new go.Binding("location", "loc", go.Point.parse),
      $(go.Shape, "PlusLine",
        { name: "SHAPE", width: 8, height: 8 }),
      $(go.TextBlock,
        { position: new go.Point(6, 6), font: "8pt sans-serif" },
        new go.Binding("text", "loc"))
    );
 
  diagram.model.nodeDataArray = [
    { loc: "0 0" },
    { loc: "100 0" },
    { loc: "100 50" }
  ];
 
  function showPoint(loc) {
    var docloc = diagram.transformDocToView(loc);
    var elt = document.getElementById("Message1");
    elt.textContent = "Selected node location,\ndocument coordinates: " + loc.x.toFixed(2) + " " + loc.y.toFixed(2) +
                      "\nview coordinates: " + docloc.x.toFixed(2) + " " + docloc.y.toFixed(2);
  }
 
  myDiagram = diagram;  // make accessible to the HTML buttons

然后尝试滚动或放大,然后在视图坐标中查看那些零件的位置。放大将Diagram.scale放大一小部分。即使文档坐标中的位置没有更改,这也会更改视图坐标中的位置。

要“移动”节点,必须在文档坐标中更改其GraphObject.position或Part.location。要“滚动”图,必须更改Diagram.position。无论哪种方式,都会导致节点出现在视口的不同点。

文件范围

图的所有Part都在文档坐标中具有位置和大小(即GraphObject.actualBounds)。所有这些部件actualBounds的联盟构成了Diagram.documentBounds。如果所有部分都靠近在一起,则文档边界可能很小。如果某些或所有部分彼此相距较远,则文档边界可能会很大,即使只有两个部分或只有一个真正很大的部分也是如此。该Diagram.documentBounds值是独立的Diagram.viewportBounds。前者仅取决于零件的界限;前者仅取决于零件的界限。后者仅取决于画布的大小以及图的位置和比例。

Diagram.computeBounds,它负责的范围计算,还增加了Diagram.padding保证金使得没有零件时滚动到一侧直接出现靠在图的边缘。您可能希望保留某些部分,尤其是背景装饰,使其不包含在文档边界计算中。只需将Part.isInDocumentBounds设置为false即可。

更改任何零件或添加或删除零件后, 该图不会立即为Diagram.documentBounds计算新值。因此,直到事务完成之后,Diagram.documentBounds属性值才可能是最新的。

Diagram.documentBounds和Diagram.viewportBounds 的相对大小控制是否需要滚动条。您可以将Diagram.hasHorizontalScrollbar和/或Diagram.hasVerticalScrollbar设置为false,以确保即使在需要时也不会出现滚动条。

如果您不希望Diagram.documentBounds始终反映所有节点和链接的大小和位置,则可以设置Diagram.fixedBounds属性。但是,如果有任何节点位于fixedBounds之外,则用户可能无法滚动图表以查看它们。

如果希望在文档边界发生更改时得到通知,则可以注册“ DocumentBoundsChanged” DiagramEvent侦听器。

视口范围

该Diagram.viewportBounds总是有X和Y值由给定Diagram.position。它始终具有从画布大小和Diagram.scale计算得出的width和height值。

用户可以使用键盘命令,滚动条或平移来滚动文档内容。您可以通过编程方式使用以下几种方式进行滚动:

  • 设置Diagram.position

  • 调用Diagram.scrollToRect或Diagram.centerRect或Diagram.scroll

  • 调用Diagram.alignDocument

  • 设置Diagram.contentAlignment

  • 调用CommandHandler.scrollToPart

此外,随着节点或链接被添加到图中或从图中删除或更改图中的可见性,滚动可能会自动发生。同样,缩放通常也会导致滚动。

滚动时,Diagram.position通常将限制在Diagram.documentBounds指定的范围内。短或“行”滚动距离由Diagram.scrollHorizontalLineChange和Diagram.scrollVerticalLineChange控制。长或“页面”滚动距离由视口的大小控制。如果要控制Diagram.position可能具有的精确值,则可以指定Diagram.positionComputation函数。请参见下面的示例。

用户可以使用键盘命令,鼠标滚轮或捏合来放大或缩小。您可以通过编程方式使用几种方法进行缩放:

  • 设置Diagram.scale

  • 调用Diagram.zoomToFit或Diagram.zoomToRect

  • 设置Diagram.autoScale

  • 调用CommandHandler.decreaseZoom,CommandHandler.increaseZoom,CommandHandler.resetZoom或 CommandHandler.zoomToFit

放大或缩小时,Diagram.scale通常将限制在Diagram.minScale和Diagram.maxScale给出的范围内。如果要控制Diagram.scale可能具有的精确值,则可以指定Diagram.scaleComputation函数。请参见下面的示例。

如果希望在视口边界发生变化时得到通知,则可以注册“ ViewportBoundsChanged” DiagramEvent侦听器。

滚动边距

当文档边界(加上边距)大于视口边界时,Diagram.scrollMargin允许用户滚动到视口边缘的空白区域。当用户在图的边缘需要额外的空间时(例如,有一个区域可以使用ClickCreatingTool创建新节点),这将非常有用。

Diagram.padding就像文档边界的一部分一样被添加,但是scrollMargin确保您可以滚动到文档边界之外的空白区域。因此,scrollMargin如果不需要滚动边缘距离,例如在视口中文档边界很小时,则不会创建额外的可滚动空白空间。

以下是scrollMargin设置为的图表100。拖动到边界时,您会发现由边距创建的额外空间。

流程图控件GoJS教程:坐标系统

滚动模式

Diagram.scrollMode允许用户使用Diagram.DocumentScroll(默认值)滚动到文档绑定的边界,或者使用Diagram.InfiniteScroll无限滚动。

Diagram.positionComputation和Diagram.scaleComputation允许您确定可以滚动到哪些位置和比例。例如,您可以只允许整数位置值,或者仅允许缩放到0.5、1或2的值。

在滚动模式样品显示下面的例子中,其用于切换这三个属性的所有代码。

流程图控件GoJS教程:坐标系统

启用无限滚动,设置Diagram.scrollMode

 myDiagram.scrollMode = checked ? go.Diagram.InfiniteScroll : go.Diagram.DocumentScroll;

启用Diagram.positionComputation函数

 function positionfunc(diagram, pos) {
    var size = diagram.grid.gridCellSize;
    return new go.Point(
      Math.round(pos.x / size.width) * size.width,
      Math.round(pos.y / size.height) * size.height);
  }

启用Diagram.scaleComputation函数

 function scalefunc(diagram, scale) {
    var oldscale = diagram.scale;
    if (scale > oldscale) {
      return oldscale + 0.25;
    } else if (scale < oldscale) {
      return oldscale - 0.25;
    }
    return oldscale;
  }

面板坐标

GraphObject这不是一个零件,但是一个的元件面板具有在面板坐标测量,而不是在文件坐标。这意味着GraphObject.position,GraphObject.actualBounds,GraphObject.maxSize, GraphObject.minSize,GraphObject.measuredBounds,GraphObject.margin和 RowColumnDefinition属性适用于使用同一坐标系的面板的所有元素。

某些GraphObject属性使用具有值的单位,然后对其进行转换以供包含Panel的坐标系使用。特别是,在按GraphObject的值缩放和旋转对象之前,GraphObject.desiredSize(即GraphObject.width和GraphObject.height), GraphObject.naturalBounds,Shape.geometry和Shape.strokeWidth位于“局部”坐标中。 scale和GraphObject.angle。

GraphObject.actualBounds将告诉您元素在面板中的位置和大小。如果要获取某个节点内某个对象的文档位置,请调用GraphObject.getDocumentPoint。

嵌套面板坐标

面板中每个元素的转换与该面板的转换混合在一起。

流程图控件GoJS教程:坐标系统

作为“底部” 的TextBlock具有默认的GraphObject.angle为零,以便将文本竖直绘制。但是该TextBlock是绿色“ Spot” 面板中的一个元素,其GraphObject.angle为30,因此它及其文本应显示为有些倾斜。但是,蓝色“垂直”面板本身的GraphObject.angle为165。由于每个面板都有自己的坐标系,并且由于嵌套元素的变换是复合的,因此绿色面板的有效角度为195度,即这些单独角度的总和(30 + 165),几乎是颠倒的。

该GraphObject.scale属性也会影响到一个物体是如何它的容器面板中的大小。棕色的“位置” 面板相对于其容器的比例为0.8。但是,由于“垂直”面板的缩放比例为1.5,因此其有效比例总体为1.2,即这些单独比例的乘积(0.8 x 1.5)。

=====================================================

想要购买GoJS正版授权的朋友可以咨询慧都官方客服

更多精彩内容,欢迎关注下方的微信公众号,及时获取产品最新资讯▼▼▼

流程图控件GoJS教程:坐标系统