title: Integrating Angular 4 with GoJs
body: <p>Can somebody help me to convert this code to Angular 4? I have tried for minimal it's working fine but when it comes to flowchart something is missing and I am unable to find that.</p>
  
  <p>Here is my Component.ts file I have attached.</p>
  
  <p>Functions such as Save() and Load() are not working. Because of document.getelementbyid.</p>
  
  <p>How to change this to angular 4 service.</p>
  
  <p>HTML Code:</p>
  
  <pre><code>  &lt;div id="sample"&gt;
          &lt;div style="width: 100%; white-space: nowrap;"&gt;
              &lt;span style="display: inline-block; vertical-align: top; width: 100px"&gt;
                  &lt;div id="myPaletteDiv" style="border: solid 1px black; height: 720px"&gt;&lt;/div&gt;
              &lt;/span&gt; &lt;span style="display: inline-block; vertical-align: top; width: 80%"&gt;
                  &lt;h1&gt;Hello {{name}}&lt;/h1&gt;
                  &lt;div align="center" #myDiagramDiv
                      style="border: solid blue 1px; width: 1000px; height: 1000px"&gt;&lt;/div&gt;
              &lt;/span&gt;
          &lt;/div&gt;
          &lt;p&gt;
  
          &lt;/p&gt;
          &lt;button id="SaveButton" (click)="save()"&gt;Save&lt;/button&gt;
          &lt;button (click)="load()"&gt;Load&lt;/button&gt;
          Diagram Model saved in JSON format:
          &lt;p&gt;
  
          &lt;/p&gt;
          &lt;textarea id="mySavedModel" style="width: 100%; height: 300px"&gt;{ "class": "go.GraphLinksModel",
       "linkFromPortIdProperty": "fromPort",
       "linkToPortIdProperty": "toPort",
       "nodeDataArray": [ 
      {"key":-1, "category":"Start", "loc":"175 0", "text":"Start"},
      {"key":1, "loc":"175 100", "text":"Entity: Amount"},
      {"key":6, "loc":"175.13616240146848 297.0937263794408", "text":"Entity: Account Number"},
      {"key":-2, "category":"End", "loc":"159.17859842349642 758.71806500378", "text":"End"},
      {"text":"Amount == 100", "figure":"Diamond", "key":-3, "loc":"174.8125 189.4553503941259"},
      {"text":"Account Number == 123456", "figure":"Diamond", "key":-6, "loc":"173.084824802937 389.8656732534283"},
      {"key":-7, "loc":"173.40848720440562 527.7383651873449", "text":"Entity: Pin Number"},
      {"text":"Pin Number &lt;= 1234", "figure":"Diamond", "key":-8, "loc":"173.94866240146834 653.3361408055284"}
      ],
       "linkDataArray": [ 
      {"from":-1, "to":1, "fromPort":"B", "toPort":"T", "points":[175,24.773340092148892,175,34.77334009214889,175,54.16780789397485,175.0000000000001,54.16780789397485,175.0000000000001,73.5622756958008,175.0000000000001,83.5622756958008]},
      {"from":1, "to":-3, "fromPort":"B", "toPort":"T", "points":[175.0000000000001,116.43772430419924,175.0000000000001,126.43772430419924,175.0000000000001,136.75881304496335,174.8125,136.75881304496335,174.8125,147.07990178572746,174.8125,157.07990178572746]},
      {"from":-3, "to":6, "fromPort":"B", "toPort":"T", "visible":true, "points":[174.8125,221.83079900252432,174.8125,231.83079900252432,174.8125,247.27453838678335,175.13616240146848,247.27453838678335,175.13616240146848,262.7182777710424,175.13616240146848,272.7182777710424]},
      {"from":6, "to":-6, "fromPort":"B", "toPort":"T", "points":[175.13616240146848,321.46917498783927,175.13616240146848,331.46917498783927,175.13616240146848,331.54197551223535,173.084824802937,331.54197551223535,173.084824802937,331.61477603663144,173.084824802937,341.61477603663144]},
      {"from":-6, "to":-7, "fromPort":"B", "toPort":"T", "visible":true, "points":[173.084824802937,438.11657047022516,173.084824802937,448.11657047022516,173.084824802937,474.70860567668547,173.40848720440562,474.70860567668547,173.40848720440562,501.3006408831457,173.40848720440562,511.3006408831457]},
      {"from":-6, "to":1, "fromPort":"R", "toPort":"R", "visible":true, "points":[328.8833477521557,389.8656732534283,338.8833477521557,389.8656732534283,338.8833477521557,100.00000000000003,292.4533048880408,100.00000000000003,246.0232620239259,100.00000000000003,236.0232620239259,100.00000000000003], "text":"No"},
      {"from":-3, "to":-7, "fromPort":"L", "toPort":"L", "visible":true, "points":[53.215850830078125,189.4553503941259,43.215850830078125,189.4553503941259,44,189.4553503941259,44,189.4553503941259,4,189.4553503941259,4,452,36,452,36,527.7383651873449,88.93497646221812,527.7383651873449,98.93497646221812,527.7383651873449], "text":"No"},
      {"from":-7, "to":-8, "fromPort":"B", "toPort":"T", "points":[173.40848720440562,544.1760894915442,173.40848720440562,554.1760894915442,173.40848720440562,582.568390844337,173.94866240146834,582.568390844337,173.94866240146834,610.96069219713,173.94866240146834,620.96069219713]},
      {"from":-8, "to":-7, "fromPort":"R", "toPort":"R", "visible":true, "points":[330.5989919913121,653.3361408055284,340.5989919913121,653.3361408055284,340.5989919913121,527.7383651873449,299.2404949689526,527.7383651873449,257.8819979465931,527.7383651873449,247.88199794659312,527.7383651873449], "text":"No"},
      {"from":-8, "to":-2, "fromPort":"B", "toPort":"T", "visible":true, "points":[173.94866240146834,685.7115894139268,173.94866240146834,695.7115894139268,173.94866240146834,711.9038126785827,159.1785984234963,711.9038126785827,159.1785984234963,728.0960359432383,159.1785984234963,738.0960359432383]}
      ]}
        &lt;/textarea&gt;
  
      &lt;/div&gt;
  </code></pre>
  
  <p>Typescript Code :</p>
  
  <pre><code>import {Component, ElementRef, AfterViewInit, ViewChild} from '@angular/core';
  import * as go from "gojs";
  
  @Component({
    selector: 'app-flowchart',
    templateUrl: './flowchart.component.html',
    styleUrls: ['./flowchart.component.css']
  })
  export class FlowchartComponent implements AfterViewInit {
  
    name = 'GoJS';
  
    @ViewChild('myDiagramDiv')
    element: ElementRef;
  
    ngAfterViewInit() {
  
      const $ = go.GraphObject.make;
  
      const myDiagram: go.Diagram = $(go.Diagram, this.element.nativeElement,
        {
          initialContentAlignment: go.Spot.Center,  // center the content
          "undoManager.isEnabled": true  // enable undo &amp; redo
        });
  
  
      const myPalette: go.Palette =
        $(go.Palette, "myPaletteDiv",  // must name or refer to the DIV HTML element
          {
            "animationManager.duration": 800, // slightly longer than default (600ms) animation
            nodeTemplateMap: myDiagram.nodeTemplateMap,  // share the templates used by myDiagram
            model: new go.GraphLinksModel([  // specify the contents of the Palette
              {category: "Start", text: "Start"},
              {text: "Step"},
              {text: "???", figure: "Diamond"},
              {category: "End", text: "End"},
              {category: "Comment", text: "Comment"}
            ])
          });
  
  
      myDiagram.nodeTemplate =
        $(go.Node, "Auto",
          $(go.Shape, "RoundedRectangle", {strokeWidth: 0},
            new go.Binding("fill", "color")),
          $(go.TextBlock,
            {margin: 8},
            new go.Binding("text", "key"))
        );
  
  
      myDiagram.addDiagramListener("Modified", function(e) {
        const button = &lt;HTMLInputElement&gt;document.getElementById("SaveButton");
        if (button) {
          button.disabled = !myDiagram.isModified;
        }
        const idx = document.title.indexOf("*");
        if (myDiagram.isModified) {
          if (idx &lt; 0) {
            document.title += "*";
          }
        } else {
          if (idx &gt;= 0) {
            document.title = document.title.substr(0, idx);
          }
        }
      });
  
  
      function nodeStyle() {
        return [
          // The Node.location comes from the "loc" property of the node data,
          // converted by the Point.parse static method.
          // If the Node.location is changed, it updates the "loc" property of the node data,
          // converting back using the Point.stringify static method.
          new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          {
            // the Node.location is at the center of each node
            locationSpot: go.Spot.Center,
            // isShadowed: true,
            // shadowColor: "#888",
            //  handle mouse enter/leave events to show/hide the ports
            mouseEnter: function(e, obj) {showPorts(obj.part, true);},
            mouseLeave: function(e, obj) {showPorts(obj.part, false);}
          }
        ];
      }
  
      function makePort(name, spot, output, input) {
        // the port is basically just a small circle that has a white stroke when it is made visible
        return $(go.Shape, "Circle",
          {
            fill: "transparent",
            stroke: null,  // this is changed to "white" in the showPorts function
            desiredSize: new go.Size(8, 8),
            alignment: spot, alignmentFocus: spot,  // align the port on the main Shape
            portId: name,  // declare this object to be a "port"
            fromSpot: spot, toSpot: spot,  // declare where links may connect at this port
            fromLinkable: output, toLinkable: input,  // declare whether the user may draw links to/from here
            cursor: "pointer"  // show a different cursor to indicate potential link point
          });
      }
  
  
      const lightText = 'whitesmoke';
      myDiagram.nodeTemplateMap.add("",  // the default category
        $(go.Node, "Spot", nodeStyle(),
          // the main object is a Panel that surrounds a TextBlock with a rectangular Shape
          $(go.Panel, "Auto",
            $(go.Shape, "Rectangle",
              {fill: "#00A9C9", stroke: null},
              new go.Binding("figure", "figure")),
            $(go.TextBlock,
              {
                font: "bold 11pt Helvetica, Arial, sans-serif",
                stroke: lightText,
                margin: 8,
                maxSize: new go.Size(160, NaN),
                wrap: go.TextBlock.WrapFit,
                editable: true
              },
              new go.Binding("text").makeTwoWay())
          ),
          // four named ports, one on each side:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, true, true),
          makePort("R", go.Spot.Right, true, true),
          makePort("B", go.Spot.Bottom, true, false)
        ));
  
      myDiagram.nodeTemplateMap.add("Start",
        $(go.Node, "Spot", nodeStyle(),
          $(go.Panel, "Auto",
            $(go.Shape, "Circle",
              {minSize: new go.Size(40, 40), fill: "#79C900", stroke: null}),
            $(go.TextBlock, "Start",
              {font: "bold 11pt Helvetica, Arial, sans-serif", stroke: lightText},
              new go.Binding("text"))
          ),
          // three named ports, one on each side except the top, all output only:
          makePort("L", go.Spot.Left, true, false),
          makePort("R", go.Spot.Right, true, false),
          makePort("B", go.Spot.Bottom, true, false)
        ));
  
      myDiagram.nodeTemplateMap.add("End",
        $(go.Node, "Spot", nodeStyle(),
          $(go.Panel, "Auto",
            $(go.Shape, "Circle",
              {minSize: new go.Size(40, 40), fill: "#DC3C00", stroke: null}),
            $(go.TextBlock, "End",
              {font: "bold 11pt Helvetica, Arial, sans-serif", stroke: lightText},
              new go.Binding("text"))
          ),
          // three named ports, one on each side except the bottom, all input only:
          makePort("T", go.Spot.Top, false, true),
          makePort("L", go.Spot.Left, false, true),
          makePort("R", go.Spot.Right, false, true)
        ));
  
      myDiagram.nodeTemplateMap.add("Comment",
        $(go.Node, "Auto", nodeStyle(),
          $(go.Shape, "File",
            {fill: "#EFFAB4", stroke: null}),
          $(go.TextBlock,
            {
              margin: 5,
              maxSize: new go.Size(200, NaN),
              wrap: go.TextBlock.WrapFit,
              textAlign: "center",
              editable: true,
              font: "bold 12pt Helvetica, Arial, sans-serif",
              stroke: '#454545'
            },
            new go.Binding("text").makeTwoWay())
          // no ports, because no links are allowed to connect with a comment
        ));
  
  
      myDiagram.linkTemplate =
        $(go.Link,  // the whole link panel
          {
            routing: go.Link.AvoidsNodes,
            curve: go.Link.JumpOver,
            corner: 5, toShortLength: 4,
            relinkableFrom: true,
            relinkableTo: true,
            reshapable: true,
            resegmentable: true,
            // mouse-overs subtly highlight links:
            mouseEnter: function(e, link) {link.findObject("HIGHLIGHT").stroke = "rgba(30,144,255,0.2)";},
            mouseLeave: function(e, link) {link.findObject("HIGHLIGHT").stroke = "transparent";}
          },
          new go.Binding("points").makeTwoWay(),
          $(go.Shape,  // the highlight shape, normally transparent
            {isPanelMain: true, strokeWidth: 8, stroke: "transparent", name: "HIGHLIGHT"}),
          $(go.Shape,  // the link path shape
            {isPanelMain: true, stroke: "gray", strokeWidth: 2}),
          $(go.Shape,  // the arrowhead
            {toArrow: "standard", stroke: null, fill: "gray"}),
          $(go.Panel, "Auto",  // the link label, normally not visible
            {visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5},
            new go.Binding("visible", "visible").makeTwoWay(),
            $(go.Shape, "RoundedRectangle",  // the label shape
              {fill: "#F8F8F8", stroke: null}),
            $(go.TextBlock, "Yes",  // the label
              {
                textAlign: "center",
                font: "10pt helvetica, arial, sans-serif",
                stroke: "#333333",
                editable: true
              },
              new go.Binding("text").makeTwoWay())
          )
        );
  
      function showPorts(node, show) {
        const diagram = node.diagram;
        if (!diagram || diagram.isReadOnly || !diagram.allowLink) {
          return;
        }
        node.ports.each(function(port) {
          port.stroke = (show ? "white" : null);
        });
      }
  
      function save() {
        (&lt;HTMLInputElement&gt;document.getElementById("mySavedModel")).value = myDiagram.model.toJson();
        myDiagram.isModified = false;
      }
      function load() {
        myDiagram.model = go.Model.fromJson((&lt;HTMLInputElement&gt;document.getElementById("mySavedModel")).value);
      }
  
      function showLinkLabel(e) {
        const label = e.subject.findObject("LABEL");
        if (label !== null) {
          label.visible = (e.subject.fromNode.data.figure === "Diamond");
        }
      }
      // temporary links used by LinkingTool and RelinkingTool are also orthogonal:
      myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;
      myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;
      load();  // load an initial diagram from some JSON text
      // initialize the Palette that is on the left side of the page
  
      // The following code overrides GoJS focus to stop the browser from scrolling
      // the page when either the Diagram or Palette are clicked or dragged onto.
      function customFocus() {
        const x = window.scrollX || window.pageXOffset;
        const y = window.scrollY || window.pageYOffset;
        go.Diagram.prototype.doFocus.call(this);
        window.scrollTo(x, y);
      }
      myDiagram.doFocus = customFocus;
      myPalette.doFocus = customFocus;
  
      throw new Error("Method not implemented.");
    }
  
    // Show the diagram's model in JSON format that the user may edit
  
   }
  </code></pre>