我正在尝试将D3JS树动画转换为AngularJS2 / Typescript。 我不是打字稿的专家。
创建基本树动画已完成并正常工作。 现在HTML内容需要在Tree Nodes中注入。它类似于表单向导以及何时"完成"和"关闭"按钮命中,应该折叠活动节点,并且应该启用树的下一个节点。
可在此处找到工作插件:https://plnkr.co/edit/cxuzCr?p=preview
export class AppComponent {
name = 'D3!';
public margin = {
top: 20,
right: 120,
bottom: 20,
left: 120
};
width = 1400 - this.margin.right - this.margin.left;
height = 800 - this.margin.top - this.margin.bottom;
public inst: number = 1;
public duration: number = 750;
public rectW: number = 60;
public rectH: number = 30;
public zm: any;
public collapse: Function;
public d: any;
public error: any;
public view: any;
public parent: any;
public visitFn: any;
public childrenFn: any;
public links: any;
public tree: any;
public maxLabelLength: any;
public svg: any;
public drag: any;
public dragmove: any;
// how much horz space to give a flaring of branches (menus, day/night behaviour)
public BRANCH_SPACE = 80;
constructor(private _nodeDataService: NodeDataService) {
}
ngOnInit() {
this.tree = d3.layout.tree().size([this.height, this.width]);
this.drag = d3.behavior.drag()
.on("drag", this.dragmove);
this.dragmove = (d) => {
var x = d3.event.x;
var y = d3.event.y;
d3.select(this).attr("transform", "translate(" + x + "," + y + ")");
};
this.svg = d3.select("#body").append("svg")
.attr("width", this.width + this.margin.right + this.margin.left)
.attr("height", this.height + this.margin.top + this.margin.bottom)
.append("g")
.call(this.drag)
.attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")");
this.getNodes();
//this.zm.translate([350, 20]);
}
diagonal = d3.svg.diagonal().projection((d: any) => {
// return [d.x + this.rectW / 2, d.y + this.rectH / 2];
return [d.y, d.x];
});
// A recursive helper function for performing some setup by walking through all nodes
public visit = (parent: any, visitFn: any, childrenFn: any): void => {
if (typeof childrenFn !== 'function') {
//default childrenFn =
childrenFn = function (node) {
return node.children || null;
};
}
if (!parent) {
return;
}
visitFn(parent);
var children = childrenFn(parent);
if (children) {
for (var i = 0, count = children.length; i < count; i++) {
this.visit(children[i], visitFn, childrenFn);
}
}
}
getNodes() {
this._nodeDataService.getNodes().subscribe(
// the first argument is a function which runs on success
data => {
this._nodeDataService.root = data;
debugger;
this._nodeDataService.root.x0 = 0;
this._nodeDataService.root.y0 = this.height / 2;
console.log("height", this.height);
this.collapse = (d: any) => {
if (d.children) {
d._children = d.children;
d._children.forEach(this.collapse);
d.children = null;
}
};
this._nodeDataService.root.children.forEach(this.collapse);
this.update(this._nodeDataService.root);
// Call visit function to establish maxLabelLength
this.visit(this._nodeDataService.root, (d: any) => {
let totalNodes: number = 0;
totalNodes++;
this.maxLabelLength = Math.max(d.name.length, this.maxLabelLength);
}, (d: any) => {
return d.children && d.children.length > 0 ? d.children : null;
});
},
// the second argument is a function which runs on error
err => console.error(err),
// the third argument is a function which runs on completion
// () => console.log('done loading Nodes', this._nodeDataService.root)
)
};
//necessary so that zoom knows where to zoom and unzoom from
// zm.translate([350, 20]);
selectFrame = d3.select(self.frameElement).style("height", "800px");
update = (source: any) => {
let i: number = 0;
// Compute the new tree layout.
let nodes = this.tree.nodes(this._nodeDataService.root).reverse(),
links = this.tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach((n: any) => {
n.y = n.depth * 180;
});
// Update the nodes…
let node = this.svg.selectAll("g.node")
.data(nodes, function (n: any) {
return n.size || (n.id = ++i);
}
);
// Enter any new nodes at the parent's previous position.
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", (n: any) => {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", this.click);
nodeEnter.append("rect")
.attr("width", this.rectW)
.attr("height", this.rectH)
.attr("stroke", "black")
.attr("stroke-width", 1)
.style("fill", (d) => {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("x", this.rectW / 2)
.attr("y", this.rectH / 2)
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text((d: any) => {
return d.name;
});
// Transition nodes to their new position.
let nodeUpdate = node.transition()
.duration(this.duration)
.attr("transform", (d: any) => {
return "translate(" + d.y + "," + d.x + ")";
});
nodeUpdate.select("rect")
.attr("width", this.rectW)
.attr("height", this.rectH)
.attr("stroke", "black")
.attr("stroke-width", 1)
.style("fill", (d: any) => {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
let nodeExit = node.exit().transition()
.duration(this.duration)
.attr("transform", (n: any) => {
return "translate(" + source.y + "," + source.x + ")";
})
.remove();
nodeExit.select("rect")
.attr("width", this.rectW)
.attr("height", this.rectH)
//.attr("width", bbox.getBBox().width)""
//.attr("height", bbox.getBBox().height)
.attr("stroke", "black")
.attr("stroke-width", 1);
nodeExit.select("text");
// Update the links…
var link = this.svg.selectAll("path.link")
.data(links, function (n: any) {
return n.target.id;
});
// Enter any new links at the parent's previous position.
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("x", this.rectW / 2)
.attr("y", this.rectH / 2)
.attr("d", (d) => {
var o = {
x: source.x0,
y: source.y0
};
return this.diagonal({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(this.duration)
.attr("d", this.diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(this.duration)
.attr("d", (n: any) => {
var o = {
x: source.x,
y: source.y
}
return this.diagonal({
source: o,
target: o
});
})
// Stash the old positions for transition.
nodes.forEach((n: any) => {
n.x0 = n.x;
n.y0 = n.y;
});
};
click = (d): void => {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
this.update(d);
};
redraw = (d) => {
this.svg.attr("transform",
"translate(" + d3.event.translate + ")"
+ " scale(" + d3.event.scale + ")");
}
}
如果有人可以帮助我,这将是一个很大的帮助!!