angulargraphvizd3-graphviz

Using d3-graphviz results in can't read property '__graphviz__' of null


I'm just trying to get a DOT diagram to render. I have followed the documentation (https://github.com/magjac/d3-graphviz) to add the package and use it but when I try to run the application and access the DOT diagram, nothing renders and the the following error is thrown:

ERROR TypeError: Cannot read property '__graphviz__' of null. console error message

The app is an Angular 12 project here is the dependency list that is used

"dependencies": {
    "@angular/animations": "^12.1.4",
    "@angular/cdk": "^12.1.4",
    "@angular/common": "^12.0.5",
    "@angular/compiler": "^12.0.5",
    "@angular/core": "^12.1.4",
    "@angular/flex-layout": "^12.0.0-beta.34",
    "@angular/forms": "^12.0.5",
    "@angular/material": "^12.1.4",
    "@angular/platform-browser": "^12.0.5",
    "@angular/platform-browser-dynamic": "^12.0.5",
    "@angular/router": "^12.0.5",
    "angular2-uuid": "^1.1.1",
    "chart.js": "^3.5.0",
    "d3": "^7.0.0",
    "d3-graphviz": "^4.0.0",
    "git-describe": "^4.0.4",
    "monaco-editor": "^0.26.1",
    "ng2-charts": "^3.0.0-rc.4",
    "ngx-monaco-editor": "^12.0.0",
    "ngx-toastr": "^14.0.0",
    "rxjs": "~6.6.0",
    "tslib": "^2.1.0",
    "xml2js": "^0.4.23",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^12.0.5",
    "@angular-eslint/builder": "12.2.0",
    "@angular-eslint/eslint-plugin": "12.2.0",
    "@angular-eslint/eslint-plugin-template": "12.2.0",
    "@angular-eslint/schematics": "12.3.1",
    "@angular-eslint/template-parser": "12.2.0",
    "@angular/cli": "^12.1.4",
    "@angular/compiler-cli": "^12.0.5",
    "@types/chart.js": "^2.9.34",
    "@types/d3": "^7.0.0",
    "@types/d3-graphviz": "^2.6.7",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.20.17",
    "@typescript-eslint/eslint-plugin": "^4.28.5",
    "@typescript-eslint/parser": "^4.28.5",
    "eslint": "^7.31.0",
    "eslint-config-airbnb-typescript": "^12.3.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-import": "^2.23.4",
    "eslint-plugin-prettier": "^3.4.0",
    "jasmine-core": "~3.7.0",
    "karma": "^6.3.4",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.7.0",
    "prettier": "2.3.2",
    "source-map-explorer": "^2.5.2",
    "typescript": "^4.2.4"
  }

Inside the ngOnInit:

ngOnInit(): void {
    wasmFolder('/assets/@hpcc-js/wasm/dist/');
    console.log('file-viewer init');
}

The code looks at the filename of the file it was handed and acts based on the extension. When we have a DOT file we do the following:

else if (originalFile.filename.toLocaleLowerCase().includes('.dot')) {
      console.log('dot file was given');
      // this.activeType = TypeCode.DOT;
      // this.dotRenderer.renderDot(contents);
      // d3.select('#dotViewerElement').graphviz().renderDot(contents);
      graphviz('#dotViewerElement').renderDot(contents);
      // graphviz.graphviz('#dotViewerElement').renderDot(contents);
    }

The commented lines are all the different attempts made to access the 'renderDot(...)' function.

The wasmFolder has been added to the project directory located

app-project

-- node_modules

-- src

---- app

---- assets

------ @hpcc-js

-------- wasm


Solution

  • UPDATE: I found the answer. The error is being thrown because the dom object (div) is not rendered yet when rendering the diagram. When I use ngAfterViewInit instead of ngOnInit it works!


    I'm facing the same problem. If I don't use the the typescript but just copy the script tags and example script in the body of my html file (so replace the angular app root) it works fine, but if I use it in the body alongside my app root it throws this error. Have you maybe found a solution?

    As an example:

    this works in my index.html

    <body>
    <script src="//d3js.org/d3.v5.min.js"></script>
    <script src="https://unpkg.com/@hpcc-js/wasm@0.3.11/dist/index.min.js"></script>
    <script src="https://unpkg.com/d3-graphviz@3.0.5/build/d3-graphviz.js"></script>
    <div id="graph" style="text-align: center;"></div>
    <script>
    
    d3.select("#graph").graphviz()
        .renderDot('digraph  {a -> b}');
    
    </script>
    

    this doesn't work:

    <head>
      <script src="//d3js.org/d3.v5.min.js"></script>
      <script src="https://unpkg.com/@hpcc-js/wasm@1.12.8/dist/index.min.js"></script>
      <script src="https://unpkg.com/d3-graphviz@4.0.0/build/d3-graphviz.js"></script>
      <script>
        d3.select("#graph").graphviz()
        .renderDot('digraph  {a -> b}');
    </script>
    </head>
    <body>
      <div id="graph" style="text-align: center;"></div>
      <app-root></app-root>
    </body>