Rose18 Rose18 - 2 months ago 46
AngularJS Question

Drag & zoom charts with d3

I am drawing charts and trying to make it zoom and drag with d3 as below.

export class LineGraphDirective {

private host;
private svg;
private margin;
private width;
private height;
private xScale; // D3 scale in X
private yScale; // D3 scale in Y
private zScale; // D3 color scale
private xAxis;
private yAxis;
private htmlElement:HTMLElement;
private parseDate;
private ds;
private zoom;

constructor(private element:ElementRef) {
this.htmlElement = this.element.nativeElement;
this.host = d3.select(this.element.nativeElement);
this.parseDate = d3.timeParse('%Y-%m-%d');

let data = [];

this.ngOnChanges(data);

}

ngOnChanges(data):void {
this.setup(data);
this.initData(data);
this.buildSVG();
this.scaleAxis(data);
this.populate();
this.drawXAxis();
this.drawYAxis();
}

private setup(data):void {
this.margin = {top: 50, right: 100, bottom: 100, left: 100};
this.width = 600;
this.height = 400;
this.xScale = d3.scaleTime().range([0, this.width]);
this.yScale = d3.scaleLinear().range([this.height, 0]);
this.zScale = d3.scaleOrdinal(d3.schemeCategory10);

this.zScale.domain(d3.keys(data[0]).filter(function (key) {
return key !== "date";
}));
}

private initData(data) {

}

/**
* build SVG element using the configurations
**/
private buildSVG():void {
this.host.html('');
this.zoom = d3.zoom().scaleExtent([1, 2]).translateExtent([[0, -100], this.width + 90, this.height + 100]).on("zoom", this.zoomed());

this.svg = this.host.append('svg')
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')')
.call(this.zoom);

this.svg.append('rect')
.attr('class', 'view')
.attr('x', 0.5)
.attr('y', 0.5)
.attr('width', this.width)
.attr('height', this.height)
.style('fill', '#EEEEEE')
.style('stroke-width', '0px');
}

private scaleAxis(data) {
}

/**
* Create x axis
**/
private drawXAxis():void {
this.xAxis = d3.axisBottom()
.scale(this.xScale)
.tickPadding(15);

this.svg.append('g')
.attr('class', 'x-axis')
.attr('transform', 'translate(0,' + this.height + ')')
.call(this.xAxis);
}

/**
*create y axis
**/
private drawYAxis():void {

this.yAxis = d3.axisLeft()
.scale(this.yScale)
.tickPadding(10);

this.svg.append('g')
.attr('class', 'y-axis')
.call(this.yAxis)
.append('text')
.attr('transform', 'rotate(-90)');
}

/**
* Populate the graphs
**/
private populate():void {
}

private zoomed() {
console.log('Zoomed');
}
}


When the application is running it creates the charts and calls zoomed() function so that it prints zoomed on console log. But when trying to zoom or drag it doesn't fire those events.

d3 version is 4 and am using Angular 2.

Any suggestions?

Thanks you

Answer

Try to change

.on("zoom", this.zoomed())

to

.on("zoom", () => this.zoomed())