Search code examples
angulard3.jschartsnvd3.js

Angular v12: Uncaught (in promise): ReferenceError: d3 is not defined ReferenceError: d3 is not defined


Angular v12, try to use d3, nvd3 (not ng2-nvd3). Compile ok, but run time error.

default-node_modules_d3_src_index_js.js:2 ERROR Error: Uncaught (in promise): ReferenceError: d3 is not defined ReferenceError: d3 is not defined at nv.d3.js:18:7 at 75301 (nv.d3.js:15671:2) at webpack_require (bootstrap:19:1) at 89275 (src_app_mypage_module_ts.js:15:62) at webpack_require (bootstrap:19:1) at 13111 (pageone.component.html:2:39) at webpack_require (bootstrap:19:1) at Function.webpack_require (bootstrap:19:1) at _ZoneDelegate.invoke (zone.js:368:26) at resolvePromise (zone.js:1193:31) at resolvePromise (zone.js:1147:17) at zone.js:1260:17 at _ZoneDelegate.invokeTask (zone.js:402:31) at core.mjs:25948:55 at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:25948:36) at _ZoneDelegate.invokeTask (zone.js:401:60) at Object.onInvokeTask (core.mjs:26249:33) at _ZoneDelegate.invokeTask (zone.js:401:60) at Zone.runTask (zone.js:173:47)

Here is what's done:

npm install d3
npm install nvd3
npm install @types/d3 --save-dev
npm install @types/nvd3 --save-dev

Component .HTML:

<div id='chart' class='span4'>
    <svg style='height:500px;width:100%'> </svg>
</div>

.TS:

import * as d3 from 'd3';  
import * as nv from 'nvd3';  

ngOnInit(): void 
{
    this.myservice.subscribe(resp=> {
        this.chartdata = resp.data;
        this.drawchart();
    });
}
  
drawchart()
{
    nv.addGraph(()=> {
    var chart = nv.models.pieChart()
      .x((d) => { return d.label })
      .y((d) => { return d.value })
      .showLabels(true)
      .donut(true)         
      .labelThreshold(0.001) 
      .labelType("key").donutRatio(0.60); 

    d3.select("#chart svg")
        .datum(this.chartdata)
        .call(chart as any);
    ...
    });
}

Update: Thanks to @Naren Murali's solution, I'm not only able to integrate, but it works in a project has mixed d3 versions.

Note: nvd3 v1.8.6 is perfect


Solution

  • Make sure you installed d3 with the below command

    npm i d3@^3.5.17
    

    Because this is the version that nvd3 seems to support well

    If this does not work. Include the script imports as shown below!

    <script src="https://d3js.org/d3.v3.min.js"></script>
    <script src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.min.js"></script>
    <link
      rel="stylesheet"
      href="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.css"
    />
    

    Then we can use the below code, to create a basic chart

    import { Component } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import 'zone.js';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      template: `
        <div id='chart' class='span4'>
            <svg style='height:500px;width:100%'> </svg>
        </div>
      `,
    })
    export class App {
      chartdata!: { label: string; value: number }[];
    
      height = 350;
      width = 350;
      chart2: any;
    
      testdata = [
        { key: 'One', y: 5 },
        { key: 'Two', y: 2 },
        { key: 'Three', y: 9 },
        { key: 'Four', y: 7 },
        { key: 'Five', y: 4 },
        { key: 'Six', y: 3 },
        { key: 'Seven', y: 0.5 },
      ];
    
      ngOnInit(): void {
        this.chartdata = [
          { label: 'test', value: 20 },
          { label: 'test2', value: 20 },
          { label: 'test3', value: 20 },
          { label: 'test4', value: 20 },
        ];
        this.drawchart();
      }
    
      drawchart() {
        const nv = (window as any)['nv'];
        nv.addGraph(() => {
          const chart2 = nv.models
            .pieChart()
            .x(function (d: any) {
              return d.key;
            })
            .y(function (d: any) {
              return d.y;
            })
            //.labelThreshold(.08)
            //.showLabels(false)
            .width(this.width)
            .height(this.height)
            .donut(true)
            .id('donut2')
            .titleOffset(-30)
            .title('woot');
    
          // MAKES IT HALF CIRCLE
          chart2.pie
            .startAngle(function (d: any) {
              return d.startAngle / 2 - Math.PI / 2;
            })
            .endAngle(function (d: any) {
              return d.endAngle / 2 - Math.PI / 2;
            });
          const d3 = (window as any)['d3'];
          d3.select('#chart svg')
            //.datum(historicalBarChart)
            .datum(this.testdata)
            .transition()
            .duration(1200)
            .call(chart2);
    
          return chart2;
        });
      }
    }
    
    bootstrapApplication(App);
    

    Stackblitz Demo