4

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

SEB
  • 43
  • 2

1 Answers1

0

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>
  • So, we actually moved to a server-side solution, were we render the DOT file ahead of time and pass it to the frontend as an SVG. I reviewed your answer, and it does seem like a reasonable solution. And in the interest of not leaving a question unanswered. I will accept yours. But just a disclaimer to anyone who might stubble upon this in the future. We did not test the answer. **Mileage may vary** Thank you @Ruud for your response to the stale question. – SEB Jan 28 '22 at 19:18