[英]D3 svg components not resizable
I'm creating a app with Angular 4
and D3
.我正在使用Angular 4
和D3
创建一个应用程序。 When I create a svg
component from inside of a component by injecting the component to another component, it shows the component, but resizing and moving functions aren't working (Even resize and move cursors aren't show on hovering).当我通过将组件注入另一个组件来从组件内部创建一个svg
组件时,它会显示该组件,但调整大小和移动功能不起作用(甚至在悬停时也不显示调整大小和移动光标)。 If I use the same component and navigate to the component with routing, resizing and moving functions work.如果我使用相同的组件并导航到具有路由、调整大小和移动功能的组件。 Any idea why.知道为什么。
Following is the component I use.以下是我使用的组件。
import { Component, OnInit } from '@angular/core';
import * as d3 from 'd3';
@Component({
selector: 'app-function-box',
templateUrl: './function-box.component.html',
styleUrls: ['./function-box.component.css']
})
export class FunctionBoxComponent implements OnInit {
constructor() { }
ngOnInit() {
}
w = 500;
h = 350;
r = 120;
width = 200;
height = 100;
dragbarw = 10;
svg = d3.select("body").append("svg")
.attr("width", this.w)
.attr("height", this.h);
newg = this.svg.append("g")
.data([{x: 400, y: 100}]); //position
dragrect = this.newg.append("rect")
.attr("id", "active")
.attr("x", (d) => { return d.x; })
.attr("y", (d) => { return d.y; })
.attr("height", this.height)
.attr("width", this.width)
.attr("fill-opacity", .5)
.attr("cursor", "move")
.call(d3.drag()
.on("drag", this.dragmove.bind(this)));
dragbarleft = this.newg.append("rect")
.attr("x", (d) => { return d.x - (this.dragbarw/2); })
.attr("y", (d) => { return d.y + (this.dragbarw/2); })
.attr("height", this.height - this.dragbarw)
.attr("id", "dragleft")
.attr("width", this.dragbarw)
.attr("fill", "lightblue")
.attr("fill-opacity", .5)
.attr("cursor", "ew-resize")
.call(d3.drag()
.on("drag", this.ldragresize.bind(this)));
dragbarright = this.newg.append("rect")
.attr("x", (d) => { return d.x + this.width - (this.dragbarw/2); })
.attr("y", (d) => { return d.y + (this.dragbarw/2); })
.attr("id", "dragright")
.attr("height", this.height - this.dragbarw)
.attr("width", this.dragbarw)
.attr("fill", "lightblue")
.attr("fill-opacity", .5)
.attr("cursor", "ew-resize")
.call(d3.drag()
.on("drag", this.rdragresize.bind(this)));
dragbartop = this.newg.append("rect")
.attr("x", (d) => { return d.x + (this.dragbarw/2);})
.attr("y", (d) => { return d.y - (this.dragbarw/2); })
.attr("height", this.dragbarw)
.attr("id", "dragleft")
.attr("width", this.width - this.dragbarw)
.attr("fill", "lightgreen")
.attr("fill-opacity", .5)
.attr("cursor", "ns-resize")
.call(d3.drag()
.on("drag", this.tdragresize));
dragbarbottom = this.newg.append("rect")
.attr("x", (d) => { return d.x + (this.dragbarw/2); })
.attr("y", (d) => { return d.y + this.height - (this.dragbarw/2); })
.attr("id", "dragright")
.attr("height", this.dragbarw)
.attr("width", this.width - this.dragbarw)
.attr("fill", "lightgreen")
.attr("fill-opacity", .5)
.attr("cursor", "ns-resize")
.call(d3.drag()
.on("drag", this.bdragresize.bind(this)));
dragmove(d) {
this.dragrect
.attr("x", d.x = Math.max(0, Math.min(this.w - this.width, d3.event.x)));
this.dragbarleft
.attr("x", (d) => { return d.x - (this.dragbarw/2); });
this.dragbarright
.attr("x", (d) => { return d.x +this.width - (this.dragbarw/2); });
this.dragbartop
.attr("x", (d) => { return d.x + (this.dragbarw/2); });
this.dragbarbottom
.attr("x", (d) => { return d.x + (this.dragbarw/2); })
this.dragrect
.attr("y", d.y = Math.max(0, Math.min(this.h - this.height, d3.event.y)));
this.dragbarleft
.attr("y", (d) => { return d.y + (this.dragbarw/2); });
this.dragbarright
.attr("y", (d) => { return d.y + (this.dragbarw/2); });
this.dragbartop
.attr("y", (d) => { return d.y - (this.dragbarw/2); });
this.dragbarbottom
.attr("y", (d) => { return d.y + this.height - (this.dragbarw/2); });
}
ldragresize(d) {
let oldx = d.x;
//Max x on the right is x + width - dragbarw
//Max x on the left is 0 - (dragbarw/2)
d.x = Math.max(0, Math.min(d.x + this.width - (this.dragbarw / 2), d3.event.x));
this.width = this.width + (oldx - d.x);
this.dragbarleft
.attr("x", (d) => { return d.x - (this.dragbarw / 2); });
this.dragrect
.attr("x", (d) => { return d.x; })
.attr("width", this.width);
this.dragbartop
.attr("x", (d) => { return d.x + (this.dragbarw/2); })
.attr("width", this.width - this.dragbarw)
this.dragbarbottom
.attr("x", (d) => { return d.x + (this.dragbarw/2); })
.attr("width", this.width - this.dragbarw)
};
rdragresize(d) {
//Max x on the left is x - width
//Max x on the right is width of screen + (dragbarw/2)
let dragx = Math.max(d.x + (this.dragbarw/2), Math.min(this.w, d.x + this.width + d3.event.dx));
//recalculate width
this.width = dragx - d.x;
//move the right drag handle
this.dragbarright
.attr("x", (d) => { return dragx - (this.dragbarw/2) });
//resize the drag rectangle
//as we are only resizing from the right, the x coordinate does not need to change
this.dragrect
.attr("width", this.width);
this.dragbartop
.attr("width", this.width - this.dragbarw)
this.dragbarbottom
.attr("width", this.width - this.dragbarw)
}
tdragresize(d) {
let oldy = d.y;
//Max x on the right is x + width - dragbarw
//Max x on the left is 0 - (dragbarw/2)
d.y = Math.max(0, Math.min(d.y + this.height - (this.dragbarw / 2), d3.event.y));
this.height = this.height + (oldy - d.y);
this.dragbartop
.attr("y", (d) => { return d.y - (this.dragbarw / 2); });
this.dragrect
.attr("y", (d) => { return d.y; })
.attr("height", this.height);
this.dragbarleft
.attr("y", (d) => { return d.y + (this.dragbarw/2); })
.attr("height", this.height - this.dragbarw);
this.dragbarright
.attr("y", (d) => { return d.y + (this.dragbarw/2); })
.attr("height", this.height - this.dragbarw);
}
bdragresize(d) {
//Max x on the left is x - width
//Max x on the right is width of screen + (dragbarw/2)
let dragy = Math.max(d.y + (this.dragbarw/2), Math.min(this.h, d.y + this.height + d3.event.dy));
//recalculate width
this.height = dragy - d.y;
//move the right drag handle
this.dragbarbottom
.attr("y", (d) => { return dragy - (this.dragbarw/2) });
//resize the drag rectangle
//as we are only resizing from the right, the x coordinate does not need to change
this.dragrect
.attr("height", this.height);
this.dragbarleft
.attr("height", this.height - this.dragbarw);
this.dragbarright
.attr("height", this.height - this.dragbarw);
}
}
Answer to your question can be achieved using ViewChild in Angular to access a Child Component, Directive or DOM Element.可以使用Angular中的ViewChild访问子组件、指令或 DOM 元素来回答您的问题。
If given component is your child component then you can add some reference variable to your html code something like this (here #chartbar)如果给定的组件是你的子组件,那么你可以在你的 html 代码中添加一些引用变量,就像这样(这里是 #chartbar)
<div #chartbar class="someclass"></div>
Now you need to use ViewChild in your Child Component现在你需要在你的子组件中使用 ViewChild
import { Component, OnInit, ViewChild, ElementRef} from '@angular/core'; //Imported ViewChild, ElementRef
import * as d3 from 'd3';
@Component({
selector: 'app-function-box',
templateUrl: './function-box.component.html',
styleUrls: ['./function-box.component.css']
})
export class FunctionBoxComponent implements OnInit {
@ViewChild('chartbar') private chartContainer: ElementRef; //Provider defined here
constructor() { }
ngOnInit() {
}
w = 500;
h = 350;
r = 120;
const element = that.chartContainer.nativeElement; //To use DOM element of html
width = 200;
height = 100;
dragbarw = 10;
svg = d3.select(element).append("svg") //select DOM element instead of body
.attr("width", this.w)
.attr("height", this.h);
For resize You will get good options here .对于调整大小,您将在此处获得不错的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.