Reputation: 932
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
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
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
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
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