user7422128
user7422128

Reputation: 932

d3.nest() not a function

I'm using d3 v4 in angular and below is my d3graphcomponent.ts file. It is working fine if i run it on python local server but as soon as i run it in angular it shows nest is not a function

I have <script src="https://d3js.org/d3.v4.min.js"></script> in my index.html as well.

Please do comment of further info about files and packages needed.

d3graphcomponent.ts

import { Component, OnInit, Input } from '@angular/core';

import * as d3 from 'd3-selection';
import * as d3Scale from 'd3-scale';
import * as d3Shape from 'd3-shape';
import * as d3Array from 'd3-array';
import * as d3Axis from 'd3-axis';



@Component({
  selector: 'app-d3graph',
  template: `
    <h2>{{subtitle}}</h2>
    <svg width="900" height="500"></svg>
  `
})
export class D3graphComponent implements OnInit {
  @Input()  storeIntraffic: string;
  @Input() dateForD3: string;
  @Input() peopleInSumStr: string;
  // storeIntraffic:any= [
  // {date: new Date("2010-01-01"), value: 210.73},
  // {date: new Date("2010-01-04"), value: 214.01},
  // {date: new Date("2010-01-05"), value: 214.38},
  // {date: new Date("2010-01-06"), value: 210.97},
  // {date: new Date("2010-01-07"), value: 10.58},
  // {date: new Date("2010-01-08"), value: 211.98}];

  title: string = 'D3.js with Angular 6!';
  subtitle: string = 'Line Chart';
  peopleInSumArr: any[];
  private margin = {top: 20, right: 20, bottom: 30, left: 50};
  private width: number;
  private legendSpace: number;
  private height: number;
  private x: any;
  private y: any;
  private svg: any;
  private line: d3Shape.Line<[number, number]>;
  d3Data: any;
  data:any;
  dashboard_date:any;
  constructor() {
    this.width = 900 - this.margin.left - this.margin.right;
    this.height = 500 - this.margin.top - this.margin.bottom;

  }

  ngOnInit() { }
  ngAfterViewChecked() {
    if (this.storeIntraffic !== undefined && typeof this.storeIntraffic === 'string') {
      this.d3Data = JSON.parse(this.storeIntraffic);

      this.dashboard_date = this.dateForD3;   
      console.log("value ",);

      console.log('d3 this.peopleInSumArr', this.peopleInSumStr);
      this.peopleInSumArr = JSON.parse(this.peopleInSumStr);
      console.log('d3 this.peopleInSumArr jajdjhdhjd', this.peopleInSumArr);
      console.log('this.dateForD3', this.dateForD3);
      this.drawgraph();
      //this.initSvg();
      //this.initAxis();
      //this.drawAxis();
      //this.drawLine();
    }
  }
  private drawgraph()
  {

  // Set the dimensions of the canvas / graph
var margin = {top: 30, right: 20, bottom: 70, left: 50},
    width = 600 - margin.left - margin.right,
    height = 300 - margin.top - margin.bottom;

// Parse the date / time
//var parseDate = d3.timeParse("%b %Y");

// Set the ranges
var x = d3Scale.scaleTime().range([0, width]);  
var y = d3Scale.scaleLinear().range([height, 0]);

// Define the line
var priceline = d3Shape.line()  
    .x(function(d) { return x(d.date); })
    .y(function(d) { return y(d.peoplesum); });

// Adds the svg canvas
var svg = d3.select("body")
    .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
    .append("g")
        .attr("transform", 
              "translate(" + margin.left + "," + margin.top + ")");

// Get the data
    this.data = JSON.parse(this.peopleInSumStr);
    var mindate = new Date(2016,12,1),
            maxdate = new Date(2017,4,4);
    x.domain(d3Array.extent([mindate, maxdate]));
    // Scale the range of the data

    y.domain(d3Array.extent(this.data, (d) => d.value ));

    // Nest the entries by symbol
    console.log(typeof this.data[0])
    var dataNest = d3.nest()
        .key(function(d) {return d.storeid;})
        .entries(this.data);


    // set the colour scale
    var color = svg.scaleOrdinal(svg.schemeCategory10);

    this.legendSpace = width/dataNest.length; // spacing for the legend

    // Loop through each symbol / key
    dataNest.forEach(function(d,i) { 

        svg.append("path")
            .attr("class", "line")
            .style("stroke", function() { // Add the colours dynamically
                return d.color = color(d.key); })
            .attr("d", priceline(d.values));

        // Add the Legend
        svg.append("text")
            .attr("x", (this.legendSpace/2)+i*this.legendSpace)  // space legend
            .attr("y", height + (margin.bottom/2)+ 5)
            .attr("class", "legend")    // style the legend
            .style("fill", function() { // Add the colours dynamically
                return d.color = color(d.key); })
            .text(d.key); 

    });

  // Add the X Axis
  svg.append("g")
      .attr("class", "axis")
      .attr("transform", "translate(0," + height + ")")
      .call(svg.axisBottom(x));

  // Add the Y Axis
  svg.append("g")
      .attr("class", "axis")
      .call(svg.axisLeft(y));

}}

Upvotes: 7

Views: 13113

Answers (4)

Youth overturn
Youth overturn

Reputation: 417

It needs some modification if you want to replace nest to group method. It's like the following for my project:

Array.from(d3
      .group(rawData, d => d.year)) // replace original nest method with d3.group with rawData as first parameter and callback as second that called by d3.nest().key method. And convert it to array by Array.from method so that it has map method called next step.
      // .key(d => d.year)
      // .entries(rawData)
      .map(d => { // replace previous rollup method
        // d[1] as object to replace d directly
        const pairs = d[1].map(v => [v.salaryInflated, v[stat]]);
        ...
        // d[0] as key and d[1] as values those maybe the object structure by nest() 
        return {
          key: d[0],
          values: d[1],
          ...
        };
      })

Upvotes: 3

Daniel Tkach
Daniel Tkach

Reputation: 736

Quoting from source: https://github.com/GeriLife/wellbeing/issues/562

"It seems that D3 version 6.x has replaced the nest() method with group(). Update code that relies on nest to use the new method."

https://github.com/d3/d3-array/blob/master/README.md#group

Upvotes: 7

0xFK
0xFK

Reputation: 2718

I would recommend to import just what you need, so keep the size of your production small as possible

import {nest} from 'd3-collection';

.... later on use directly

var dataNest = nest()
        .key(function(d) {return d.storeid;})
        .entries(this.data);

Upvotes: 5

Mark
Mark

Reputation: 108512

Looks like you are missing d3-collection which defines nest.

import * as d3Collection from 'd3-collection';

and refer to it as:

d3Collection.nest();

I have <script src="https://d3js.org/d3.v4.min.js"></script> in my index.html as well

But you've overrode that with import * as d3 from 'd3-selection'

Upvotes: 2

Related Questions