question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

d3.graphviz not a function

See original GitHub issue

Hey, New to your package, super excited to render animated SVG like your demo. Having some kind of a trouble setting it up in my react+typescript app though, not sure if related. Here’s what I’m doing at the moment:

Inside index.html:

<head>
    ...
    <script src="./node_modules/viz.js/viz.js" type='javascript/worker'></script>
    <script src="./node_modules/d3/build/d3.js"></script>
    <script src="./node_modules/d3-graphviz/build/d3-graphviz.js"></script>

then inside my component :

export class DotViewer extends React.Component<DotViewerProps,DotViewerState>{
  // ...
 render(){
    return <div className='DotViewer'>
      <div className={'dot_view_port_'+this.state.uniqueid}></div>
    </div>
  }
  renderGraph(){
     d3.graphviz(".dot_view_port_"+this.state.uniqueid)
     .renderDot(
      this.props.dotString
    );
  }
  componentDidMount(){this.renderGraph()}

Which throws the following error : DotViewer.tsx:31 Uncaught TypeError: d3.graphviz is not a function at DotViewer.renderGraph I’ve tried using the other syntax I saw around too : d3.select(...).graphviz().renderDot( but I get the same issue : d3.select(...).graphviz() is not a function

I’m assuming it means I’m not properly setting up d3-graphviz as a plugin of d3, but it seems to never be done explicitly in the examples I saw so I’m a bit confused here. Also, I get no other error prior to this one, nothing at all If I do not call renderGraph.

Here’s are some probably/maybe relevant package versions:

    "d3": "^4.13.0",
    "d3-graphviz": "^2.5.1",
    "d3-array": "^1.2.1",
    "d3-axis": "^1.0.8",
    "d3-brush": "^1.0.4",
    "d3-geo": "^1.9.1",
    "d3-scale": "^2.0.0",
    "d3-selection": "^1.3.0",
    "d3-shape": "^1.2.0",
    "d3-svg-legend": "^2.25.6",
    "d3-tip": "^0.7.1",
    "d3-transition": "^1.1.1",
    "viz.js": "^2.0.0"

Any idea? Thanks in advance, Antoine

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:11 (3 by maintainers)

github_iconTop GitHub Comments

7reactions
AntoineTBcommented, Sep 6, 2018

Hey, thanks for the quick reply! I was making good headway so I closed it to make sure you wouldn’t work on it also and lose your time. I just managed to make it work and learned a few things along the way. Hopefully this can be useful to someone else.

My approach was first to remove all the loading in the index.html except for viz.js as I wanted the worker, and let webpack&friends manage imports, as I would normally do with other dependancies. This led to the following discoveries/understandings:

First, npm wasn’t very bright on this as I had conflicting requirements between d3-graphviz dependancies and explicit dependancies and it didn’t make it obvious to me. For example, viz.js was at 2.0.0 in my package.json, which didn’t work with d3-graphviz (requesting ^1.8.2) and led to an obscure error : Uncaught Cannot call a class as a function (worker.onmessage @ d3-graphviz.js:1178) .

To debug this I created a bare project and made the most simple package.json until I could get it to work, then compared the package-lock.json with my main project. By begin very careful about this I found the viz.js discrepancies but also that my main d3 was still on major version 4, plus some minor versions for various d3 packages. With some manual work and by running a few npm updates I eventually got close enough that I could render using this syntax d3Graphviz.graphviz(".graph").renderDot() but it would still fail with the same error as above when using d3 directly with this syntax : d3.select(".graph").graphviz().renderDot(). So that was the first headway.

Then (and please excuse my limited vocabulary as I’m not familar with the jargon here), there’s something about webpack not eagerly loading packages that are imported in the file. I spent a good chunk of time wondering why it would work on my minimal debug project, but not on my main project, which used the “same” code. For reference, code would look more or less like this:

import * as React          from 'react'
import * as d3             from 'd3'
import * as d3Graphviz     from 'd3-graphviz'
class DotViewer extends React.component<any,any>{
  //...
  render(){
    const className = 'dot_view_port_'+this.state.uniqueid
    return <div className='DotViewer'>
      <div key={className+this.props.dotString} className={className}></div>
    </div>
  }
  renderGraph(){
    console.log("rendering dot string")
    //console.log(d3Graphviz.graphviz) // object, contains a function named graphviz
    d3.select(".dot_slide_view_port_"+this.state.uniqueid).graphviz().renderDot(this.props.dotString)
    console.log("done rendering dot string")
  }
  componentDidMount(){this.renderGraph()}
  //...

Which wouldn’t work, it turns out, because d3Graphviz was simply never bundled in the application, as it was never referenced. In my working minimal project the console.log(d3Graphviz.graphviz) was not commented out, which meant it got bundled. To force d3-graphviz to be bundled I added the following line in my index.tsx :

const _ = d3Graphviz.graphviz //Preload d3Graphiz so it register itself in d3 as a plugin

Which did the trick.

The minimal project can be found here : https://github.com/AntoineTB/debugD3GraphViz, with a similar summary of problems encountered and solutions found.

Thanks again for the quick reply, i’ll probably be back on SO with some actual API questions next time!

2reactions
ashrao94commented, Jun 19, 2020

@magjac @AntoineTB , I am facing the same issue while trying to call d3.graphviz() . Tried adding const _ = d3Graphviz.graphviz. It didn’t solve the problem. Still the error says d3.graphviz() is not a function.

Read more comments on GitHub >

github_iconTop Results From Across the Web

D3 Graphviz d3.select.graphviz is not a function - Stack Overflow
I am trying to run this below ReactJs code and I am getting an error: d3.select.graphviz() ...
Read more >
[Solved]-D3 Graphviz d3.select.graphviz is not a function-d3.js
For d3-graphviz@2.6.1, you can use graphviz(`xxx`).renderDot(`digraph{a->b}`) . Example: import React, { Component } from "react"; import {graphviz} from ...
Read more >
d3-graphviz - npm
d3 -graphviz. Renders SVG from graphs described in the DOT language using the @hpcc-js/wasm port of Graphviz and does animated transitions between graphs....
Read more >
Is there a less-hacky way of using d3-graphviz with svelte?
I'd like to incorporate the d3-graphviz module into a svelte app to enable visualizations like this . ... graphviz is not a function...
Read more >
d3-graphviz/README.md - UNPKG
The CDN for d3-graphviz. ... However, there is one d3-graphviz function, ... If the *selector* is not a string, instead creates a new...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found