yang
  • 220

GoJS

 阅读约 23 分钟

GoJS是用于实现交互式图的JavaScript库。
GoJS是依赖HTML5功能的JavaScript库,

使用

<!DOCTYPE html>   <!-HTML5文档类型-> 
< html > 
< head > 
  <!-开发时使用go-debug.js,部署时使用go.js-> 
  < script  src = “ go-debug .js“ > </ script >

直接链接到CDN提供的GoJS库:

 <script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/1.7.8/go-debug.js"></script>

每个GoJS图表都包含在<div>您的HTML页面的HTML元素中,您可以提供明确的大小:

<!-图表的DIV需要明确的尺寸,否则我们将看不到任何内容。
     在这种情况下,我们还添加了背景色,以便我们可以看到该区域。-> 
< div  id = “ myDiagramDiv” 
     style = “ width:400px; height:150px; background-color:#DAE4E4;” > </ div >

在JavaScript代码您传递<div>id制作图表时:

var $ = go.GraphObject.make;
var myDiagram =
  $(go.Diagram,“ myDiagramDiv”);

注意,这go是所有GoJS类型所在的“名称空间”。GoJS类的所有代码用法(例如图或节点或面板或Shape或TextBlock)都将以“go.”作为前缀。
本文将通过示例向您展示如何go.GraphObject.make用于构建GoJS对象。有关更多详细信息,请阅读GoJS中的Building Objects。使用$作为一个缩写,go.GraphObject.make是那么得心应手,我们将假设从现在开始使用它。如果你使用$你的代码别的东西,你总是可以选择一个不同的短变量名称,如$$MAKEGO

图表和模型

图的节点和链接是由模型管理的数据的可视化。GoJS具有模型视图架构,其中模型保存描述节点和链接的数据(JavaScript对象的数组),而图作为视图使用实际的Node和Link对象可视化此数据。在编辑后加载然后保存的是模型而不是图。您可以在模型的数据对象上添加应用所需的任何属性;您不向Diagram和GraphObject类添加属性或修改其原型。

这是一个模型和图的示例,后面是它生成的实际图:

var $ = go.GraphObject.make;
var myDiagram = 
  $(go.Diagram,“ myDiagramDiv”,
    { “ undoManager.isEnabled”:true //启用Ctrl-Z撤消和Ctrl-Y重做 
    }); var myModel = $(go.Model);
//在模型数据中,每个节点都由一个JavaScript对象表示: 
myModel.nodeDataArray = [ 
  { key:“ Alpha” },
  { key:“ Beta” },
  { key:“ Gamma” } 
]; 
myDiagram.model = myModel;
       
       显示了模型中的三个节点。已经可以进行一些交互:

*   单击并拖动上图中的背景以平移视图。
*   单击一个节点以将其选中,或者按下并拖动一个节点以将其移动。
*   要创建选择框,请单击并按住背景,然后开始拖动。
*   使用CTRL-C和CTRL-V或按住Control并拖放来制作所选内容的副本。
*   按Delete键删除选定的节点。(了解有关更多[键盘命令的信息](https://gojs.net/latest/intro/commands.html)。)
*   由于启用了撤消管理器,因此CTRL-Z和CTRL-Y将撤消和重做移动以及复制和删除操作。
       

样式节点

通过创建由GraphObject组成的模板并在这些对象上设置属性来设置节点的样式。要创建Node,我们可以使用几个构建基块类:

  • Shape,以显示带有颜色的预定义或自定义几何
  • TextBlock,以显示各种字体的文本(可能可编辑)
  • 图片,显示图像
  • Panel,用于容纳其他对象集合的容器,这些对象可以根据Panel的类型以不同的方式放置和调整大小(例如桌子,垂直堆栈和拉伸容器)

所有这些构建块均来自GraphObject抽象类,因此我们随便将它们称为GraphObjects或对象或元素。请注意,GraphObject_不是_HTML DOM元素,因此在创建或修改此类对象时没有太多开销。

我们希望模型数据属性影响我们的节点,这是通过数据绑定来完成的。数据绑定使我们可以通过将GraphObject上的属性自动设置为从模型数据中获取的值来更改GraphObject在Nodes中的外观和行为。模型数据对象是普通的JavaScript对象。您可以选择在模型的节点数据上使用所需的任何属性名称。

默认的Node模板很简单:一个包含一个TextBlock的Node。TextBlock的text属性和模型数据的key属性之间存在数据绑定。在代码中,模板看起来像这样:

myDiagram.nodeTemplate =
  $(go.Node,
    $(go.TextBlock,
      // TextBlock.text is bound to Node.data.key
      new go.Binding("text", "key"))
  );

TextBlocks,Shape和Pictures是GoJS的原始构建块。TextBlocks不能包含图像。形状不能包含文本。如果要让节点显示一些文本,则必须使用TextBlock。如果要绘制或填充一些几何图形,则必须使用“形状”。

更一般地,Node模板的框架看起来像这样:

myDiagram.nodeTemplate =
  $(go.Node, "Vertical", //节点/面板的第二个参数可以是面板类型
    / *在此处设置节点属性* / 
    { // Node.location点将位于每个节点
      locationSpot: go.Spot.Center
    },

 / *在此处添加绑定* / //示例节点绑定将Node.location设置为Node.data.loc的值
    new go.Binding("location", "loc"),

  / *添加包含在Node中的GraphObjects * / //此Shape将垂直位于TextBlock 
    $(go.Shape,
      "RoundedRectangle", //字符串参数可以命名预定义的图形 
       { / *在这里设置Shape属性* / },
       //示例Shape绑定将Shape.figure设置为Node.data.fig的值
      new go.Binding("figure", "fig")),

    $(go.TextBlock,
      "default text",   //字符串参数可以是初始文本字符串 
      { / *在这里设置TextBlock属性* / },
      //示例TextBlock绑定将TextBlock.text设置为Node.data的值.key
      new go.Binding("text", "key"))
  );

Panel中GraphObjects的嵌套可以任意深,每个类都有其自己独特的属性集可进行探索,但这表明了基本思想。

既然我们已经了解了如何制作Node模板,那么让我们来看一个实时示例。我们将制作一个在组织结构图中常见的简单模板-名称旁边的图像。考虑以下节点模板:

  • 一个“水平”面板类型的节点,表示其元素将水平并排放置。它包含两个元素:

    • 肖像的图片,已绑定图像源数据
    • 名称的TextBlock,绑定了文本数据
var $ = go.GraphObject.make;
var myDiagram = 
  $(go.Diagram,“ myDiagramDiv”,
    { “ undoManager.isEnabled”:true //启用Ctrl-Z撤消和Ctrl-Y重做 
    }); //定义一个简单的Node模板 
myDiagram.nodeTemplate = 
  $(go.Node,“ Horizo​​ntal”,
     //整个节点将具有浅蓝色背景 
    { background:“#44CCFF” },
    $(go.Picture,//图片通常应具有明确的宽度和高度//此图片具有红色背景,仅在未设置源的情况下可见
       


      
      
      //或图像部分透明时。
      { margin:10,width:50,height:50,background:“ red” },
       // Picture.source是绑定到模型数据的“ source”属性的数据
      new go.Binding(“ source”))),
    $ (go.TextBlock,“ Default Text”,   // TextBlock.text的初始值//文本周围有一些空间,一个较大的字体和一个白色笔画: 
      { margin:12,stroke:
      
      “ white”,font:“ bold 16px sans-serif” },
       // TextBlock.text是绑定到模型数据的name属性的数据
      new go.Binding(“ text”,“ name”))
  )); var model = $(go.Model); 
model.nodeDataArray = 
[ //注意,每个节点数据对象都拥有所需的任何属性;//为此应用程序,我们添加了“ name”和“ source”属性 
  { name:“ Don Meow”,source:“ cat1.png” },
  { name:


  :“” cat2.png“ },
  { name:” Demeter“,   source:” cat3.png“ },
  { / *空节点数据* /   } 
]; 
myDiagram.model =model;

当并非所有信息都存在时,例如当图像未加载或名称未知时,我们可能希望显示一些“默认”状态。此示例中的“空”节点数据用于显示节点模板可以很好地工作,而无需绑定数据上的任何属性。

型号种类

使用自定义节点模板,我们的图变得很漂亮,但是也许我们想展示更多。也许我们希望组织结构图显示Don Meow确实是卡特尔的老板。因此,我们将通过添加一些链接以显示各个节点之间的关系以及一个自动放置节点的布局来创建完整的组织结构图。

为了使链接进入我们的图表,基本Model不会删除它。我们将不得不在GoJS中选择其他两个模型之一,它们都支持Links。这些是GraphLinksModelTreeModel。(在此处阅读有关模型的更多信息。)

在GraphLinksModel中,model.linkDataArray除了model.nodeDataArray。它包含一个JavaScript对象数组,每个JavaScript对象都通过指定“ to”和“ from”节点键来描述链接。这是一个示例,其中节点A链接到节点B,节点B链接到节点C:

var model = $(go.GraphLinksModel); 
model.nodeDataArray = 
[ 
  { key:“ A” },
  { key:“ B” },
  { key:“ C” } 
]; 
model.linkDataArray = 
[ 
  { from:“A” ,to:“B” },
  { from:“B” ,to:“C” } 
]; 
myDiagram.model =model;

TreeModel比GraphLinksModel简单,但是它不能建立任意的链接关系,例如同一两个节点之间的多个链接或具有多个父级。我们的组织结构图是一个简单的分层树状结构,因此在此示例中将选择TreeModel。

首先,我们将通过使用TreeModel添加更多的节点并在数据中指定键和父级来完成数据。

var $ = go.GraphObject.make;
var myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "undoManager.isEnabled": true // enable Ctrl-Z to undo and Ctrl-Y to redo
    });

// the template we defined earlier
myDiagram.nodeTemplate =
  $(go.Node, "Horizontal",
    { background: "#44CCFF" },
    $(go.Picture,
      { margin: 10, width: 50, height: 50, background: "red" },
      new go.Binding("source")),
    $(go.TextBlock, "Default Text",
      { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
      new go.Binding("text", "name"))
  );

var model = $(go.TreeModel);
model.nodeDataArray =
[ // the "key" and "parent" property names are required,
  // but you can add whatever data properties you need for your app
  { key: "1",              name: "Don Meow",   source: "cat1.png" },
  { key: "2", parent: "1", name: "Demeter",    source: "cat2.png" },
  { key: "3", parent: "1", name: "Copricat",   source: "cat3.png" },
  { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
  { key: "5", parent: "3", name: "Alonzo",     source: "cat5.png" },
  { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" }
];
myDiagram.model = model;
      

图表布局

如您所见,TreeModel自动创建必要的Links来关联Node,但是很难确定谁是谁。

图具有默认布局,该布局采用所有没有位置的节点并将其分配给它们,然后将它们排列在网格中。我们可以显式地为每个节点提供一个位置,以解决这种组织混乱的情况,但是,在我们的案例中,作为一种更简单的解决方案,我们将使用一种布局,该布局可以自动为我们提供良好的位置。

我们想要显示一个层次结构,并且已经在使用TreeModel,因此最自然的布局选择是TreeLayout。TreeLayout默认为从左到右流动,因此要使其从上到下流动(这在组织图中是常见的),我们将angle属性设置为90。

GoJS中使用布局通常很简单。每种布局都有许多影响结果的属性。每个布局都有一些示例(例如TreeLayout Demo)来展示其属性。

//定义从上到下流动的 
TreeLayout myDiagram.layout = 
  $(go.TreeLayout,
    { angle:90,layerSpacing:35 });

GoJS还有其他几种布局,您可以在此处阅读。

到目前为止,将布局添加到图和模型中,我们可以看到结果:

var $ = go.GraphObject.make;
var myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "undoManager.isEnabled": true, // enable Ctrl-Z to undo and Ctrl-Y to redo
      layout: $(go.TreeLayout, // specify a Diagram.layout that arranges trees
                { angle: 90, layerSpacing: 35 })
    });

// the template we defined earlier
myDiagram.nodeTemplate =
  $(go.Node, "Horizontal",
    { background: "#44CCFF" },
    $(go.Picture,
      { margin: 10, width: 50, height: 50, background: "red" },
      new go.Binding("source")),
    $(go.TextBlock, "Default Text",
      { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
      new go.Binding("text", "name"))
  );

var model = $(go.TreeModel);
model.nodeDataArray =
[
  { key: "1",              name: "Don Meow",   source: "cat1.png" },
  { key: "2", parent: "1", name: "Demeter",    source: "cat2.png" },
  { key: "3", parent: "1", name: "Copricat",   source: "cat3.png" },
  { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
  { key: "5", parent: "3", name: "Alonzo",     source: "cat5.png" },
  { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" }
];
myDiagram.model = model;
      

我们的图表开始看起来像是正确的组织结构图,但是我们可以通过链接做得更好。

链接模板

我们将构建一个新的Link模板,该模板将更适合我们宽阔的Boxy节点。一个链接是一种不同的部分,而不是像一个节点。链接的主要元素是链接的形状,并且必须是一个形状,其形状将由GoJS动态计算。我们的链接将仅由这种形状组成,其笔触比正常的笔触要粗一些,并且深灰色而不是黑色。与默认链接模板不同,我们将没有箭头。然后,将“链接”routing属性从“法线”更改为“正交”,并为其赋予一个corner值,以使直角转角变圆。

// define a Link template that routes orthogonally, with no arrowhead
myDiagram.linkTemplate =
  $(go.Link,
    // default routing is go.Link.Normal
    // default corner is 0
    { routing: go.Link.Orthogonal, corner: 5 },
    $(go.Shape, { strokeWidth: 3, stroke: "#555" }) // the link shape

    // if we wanted an arrowhead we would also add another Shape with toArrow defined:
    // $(go.Shape, { toArrow: "Standard", stroke: null }
    );
      

将我们的Link模板与Node模板,TreeModel和TreeLayout结合在一起,我们终于有了完整的组织图。下面重复完整的代码,结果图如下:

var $ = go.GraphObject.make;

var myDiagram =
  $(go.Diagram, "myDiagramDiv",
    {
      "undoManager.isEnabled": true, // enable Ctrl-Z to undo and Ctrl-Y to redo
      layout: $(go.TreeLayout, // specify a Diagram.layout that arranges trees
                { angle: 90, layerSpacing: 35 })
    });

// the template we defined earlier
myDiagram.nodeTemplate =
  $(go.Node, "Horizontal",
    { background: "#44CCFF" },
    $(go.Picture,
      { margin: 10, width: 50, height: 50, background: "red" },
      new go.Binding("source")),
    $(go.TextBlock, "Default Text",
      { margin: 12, stroke: "white", font: "bold 16px sans-serif" },
      new go.Binding("text", "name"))
  );

// define a Link template that routes orthogonally, with no arrowhead
myDiagram.linkTemplate =
  $(go.Link,
    { routing: go.Link.Orthogonal, corner: 5 },
    $(go.Shape, { strokeWidth: 3, stroke: "#555" })); // the link shape

var model = $(go.TreeModel);
model.nodeDataArray =
[
  { key: "1",              name: "Don Meow",   source: "cat1.png" },
  { key: "2", parent: "1", name: "Demeter",    source: "cat2.png" },
  { key: "3", parent: "1", name: "Copricat",   source: "cat3.png" },
  { key: "4", parent: "3", name: "Jellylorum", source: "cat4.png" },
  { key: "5", parent: "3", name: "Alonzo",     source: "cat5.png" },
  { key: "6", parent: "2", name: "Munkustrap", source: "cat6.png" }
];
myDiagram.model = model;

本文来源:https://gojs.net/latest/learn...

阅读 2.3k更新于 11月25日
推荐阅读
木易杨@
用户专栏

积极向上的程序员

672 人关注
102 篇文章
专栏主页
目录