Reputation: 72
Still can't find out how to use d3.drag() in Angular2 component.
Trying:
d3.selectAll(".node").call(d3.drag().on("start", started));
But getting "Unresolved function or method drag()".
I have installed d3, it is working quite well. I have imported d3 using import * as d3 from 'd3'. Here is an example of my code:
import {Component, OnInit} from '@angular/core';
import * as d3 from 'd3';
// some other imports
@Component({
selector: 'model-detail-d3',
inputs: ['modelData'],
templateUrl: 'app/shared/templates/d3.html',
//styleUrls: ['app/replication-model/d3.css']
providers: [DataModel]
})
export class ModelDetailD3Component implements OnInit {
private modelData : ModelData;
constructor(private someModel: SomeModel) {
this.someModel= someModel;
}
ngOnInit() {
this.someModel.setInstanceData(this.modelData);
var someItems: someItems[];
someItems = [];
if (this.someModel.getInstances()) someInstances = this.someModel.getInstances();
// d3 container
var svgContainer = d3.select("#d3-model")
.append("svg")
.attr("width", 600)
.attr("height", 300);
var d3Items = svgContainer.selectAll("rect")
.data(someInstances)
.enter()
.append("rect");
var defaultX = 10;
var defaultY = 10;
var spiAttributes = spiItems
.attr("x", function (spiItem, i) { return 10 + (someItem.d3.x || 10*i*defaultX); })
.attr("y", function (spiItem, i) { return 10 + (someItem.d3.y || 10*i*defaultY); })
.attr("height", function (someItem) { return (50); })
.attr("width", function (someItem) { return (80); })
.style("fill", function(someItem) { return "red"; })
// Add event to each item
.on('mouseover', (someItem) => {
this.onMouseOn(someItem);
})
.on('mouseout', (someItem) => {
this.onMouseOut();
})
.append('rect');
// HERE IS THE PROBLEM: "Unresolved function or method drag()"
svgContainer
.call(d3.drag()
.container(svgContainer)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
// d3.selectAll("rect").call(d3.drag().on("start", started));
};
So I can use D3 in Angular2 to draw some items according to some data, but I am not able to make some behavior as drag or zoom, even if it is working in some js examples as here http://bl.ocks.org/enjalot/1378144 or https://bl.ocks.org/mbostock/6123708 , but not in Angular2.
Upvotes: 1
Views: 2895
Reputation: 19
Because D3 is not implemented in typescript. Which follows strict typings.we need to typecast d3.drag() to (< any>d3).drag()
Hope it works.
Upvotes: 0
Reputation: 1096
For an example of how to use d3-drag
in a component, have a look at the following drag-zoom-2 Angular component example. While the example uses d3-ng2-service
it should give you a basic idea:
d3
, this could possibly your own customizationd3-drag
event handling,As an important consideration, be aware that, by design, the this
scope of a d3-drag
callback is the selected element, not the this
scope of your Angular component! So, if you require access to members of the Angular component in the callback, use a drag event handler returned from a closure providing you access to the Angular component.
This could mean adding a private Angular component method, like:
private getDragHandler() {
const self = this;
return function dragged(this: SVGCircleElement, d: PhyllotaxisPoint) {
let e: D3DragEvent<SVGCircleElement, PhyllotaxisPoint, PhyllotaxisPoint> = d3.event;
// Use self.foo to access the foo member of the Angular component.
d3.select(this).attr('cx', d.x = e.x).attr('cy', d.y = e.y);
}
}
Note that the code snippet here is an alternative to the implementation details in "drag-zoom-2".
Upvotes: 2
Reputation: 72
So I haven't found out how to use the function drag() of D3 in Angular2 with version 4 of D3, but it works well with version 3 of D3.
Upvotes: -2
Reputation: 71911
In order to use d3.drag() you have to install the d3-drag
package:
npm install d3-drag
Upvotes: 2