For instance I am running a project with D3.js, importing specific modules and calling on their functions.
Setup:
- TypeScript/ES6
- Importing specific D3 components
- Angular 6
I am having an object, in this case an angular directive, and drawing some circles onto a SVG canvas and want them to trigger a function on a drag event.
Reduced code snippet: Please have a look on drawPoints()
at the bottom of this snippet
import { ElementRef, HostListener, Output, EventEmitter, OnInit, Input, OnChanges, SimpleChanges, Directive } from '@angular/core';
import * as Selection from 'd3-selection';
import * as Shape from 'd3-shape';
import * as Random from 'd3-random';
import * as Drag from 'd3-drag';
import { Config } from './../models/config.model';
import { Point } from './../models/point.model';
import { Param } from './../models/param.model';
@Directive({
selector: '[appCanvas]'
})
export class CanvasDirective implements OnInit, OnChanges {
private canvas: any;
private defs: any;
private gradient: any;
private svg: any;
private expandedPoints: Point[];
private drag: Point;
public config: Config;
@Input()
private param: Param;
@Output()
private emitConfig: EventEmitter<Config>;
@HostListener('window:resize', ['$event'])
private onResize(event) {
this.init();
}
constructor(
private el: ElementRef
) {
this.canvas = el.nativeElement;
this.emitConfig = new EventEmitter();
}
ngOnInit() {
intSvg();
// ..
}
private initSvg() {
if (!this.svg) {
this.svg = Selection.select(this.canvas).append('svg');
}
this.svg
.attr('width', this.config.width)
.attr('height', this.config.height);
}
private drawPoints(points: Point[]) {
points.forEach(point => {
this.svg.append('circle')
.attr('r', point.color ? 20 : 10)
.attr('cx', point.x)
.attr('cy', point.y)
.attr('fill', point.color ? point.color : 'lightgray')
.attr('stroke-width', !point.color ? 2 : 0)
.attr('stroke', !point.color ? 'gray' : '')
.call(Drag.drag()
.on('drag', () => {
// What to call here?
// Selection.select(this) will not work
// So how to target the correct „this“?
}));
});
}
// ...
}
The problem that occures is not beeing able to reach the correct this
inside the drag function of the appended circles.
Multiple examples are out there, but they won't work inside the class, because the this
argument is protected.
Credits to Mike Bostock's example https://bl.ocks.org/mbostock/22994cc97fefaeede0d861e6815a847e