Expand and Collapse D3 collapsible indented tree globally in Angular using buttons
StackBlitz Demo
- Collapsible Indented Tree in Angular Example
- Editor URL
I already have the Tree up and running where all my logic is written within ngAfterViewInit()
Hook.
The code works well. However I wish to add Collapse All
and Expand All
button globally so that a User can use them accordingly without painstakingly click on all the nodes either to collapse or expand the complete tree.
Unfortunately, I have no class methods or variables that are public within the component. This limits the method calls to the buttons:
<button (click)="expandAll()"></button> <!-- expandAll() has nothing to trigger as a parameter-->
hello.component.ts
export class HelloComponent {
@Input() name: string;
ngAfterViewInit(): void {
let margin = {top: 30, right: 10, bottom: 30, left: 20};
let width = 960;
let barHeight = 20;
let barWidth = (width - margin.left - margin.right) * 0.8;
let i = 0, duration = 400, root;
let diagonal = d3.linkHorizontal()
.x((d) => { return d.y; })
.y((d) => { return d.x; });
let svg = d3.select(".tree").append("svg")
.attr("width", width) //+ margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = d3.hierarchy(flares);
root.x0 = 0;
root.y0 = 0;
moveChildren(root);
update(root);
function update(source) {
// Compute the flattened node list.
let nodes = root.descendants();
let height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);
d3.select("svg").transition()
.duration(duration)
.attr("height", height);
d3.select(self.frameElement).transition()
.duration(duration)
.style("height", height + "px");
// Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
let index = -1;
root.eachBefore(function(n) {
n.x = ++index * barHeight;
n.y = n.depth * 20;
});
// Update the nodes…
let node = svg.selectAll(".node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.style("opacity", 0);
// Enter any new nodes at the parent's previous position.
nodeEnter.append("rect")
.attr("y", -barHeight / 2)
.attr("height", barHeight)
.attr("width", barWidth)
.style("fill", color)
.on("click", click);
nodeEnter.append("text")
.attr("dy", 3.5)
.attr("dx", 5.5)
.text(function(d) { return d.data.name; });
// Transition nodes to their new position.
nodeEnter.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1);
node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1)
.select("rect")
.style("fill", color);
// Transition exiting nodes to the parent's new position.
node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.style("opacity", 0)
.remove();
// Stash the old positions for transition.
root.each(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
function moveChildren(node) { // https://stackoverflow.com/questions/19423396/d3-js-how-to-make-all-the-nodes-collapsed-in-collapsible-indented-tree
if(node.children) {
node.children.forEach(function(c) { moveChildren(c); });
node._children = node.children;
node.children = null;
}
}
}
}
References
Expand All/Collapse All d3-tree provides some logic but it requires me to use root
variable which in fact is only local to ngAfterViewInit()
Hook and might not be accessible for other class methods.
How do I achieve this?
angular d3.js
add a comment |
StackBlitz Demo
- Collapsible Indented Tree in Angular Example
- Editor URL
I already have the Tree up and running where all my logic is written within ngAfterViewInit()
Hook.
The code works well. However I wish to add Collapse All
and Expand All
button globally so that a User can use them accordingly without painstakingly click on all the nodes either to collapse or expand the complete tree.
Unfortunately, I have no class methods or variables that are public within the component. This limits the method calls to the buttons:
<button (click)="expandAll()"></button> <!-- expandAll() has nothing to trigger as a parameter-->
hello.component.ts
export class HelloComponent {
@Input() name: string;
ngAfterViewInit(): void {
let margin = {top: 30, right: 10, bottom: 30, left: 20};
let width = 960;
let barHeight = 20;
let barWidth = (width - margin.left - margin.right) * 0.8;
let i = 0, duration = 400, root;
let diagonal = d3.linkHorizontal()
.x((d) => { return d.y; })
.y((d) => { return d.x; });
let svg = d3.select(".tree").append("svg")
.attr("width", width) //+ margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = d3.hierarchy(flares);
root.x0 = 0;
root.y0 = 0;
moveChildren(root);
update(root);
function update(source) {
// Compute the flattened node list.
let nodes = root.descendants();
let height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);
d3.select("svg").transition()
.duration(duration)
.attr("height", height);
d3.select(self.frameElement).transition()
.duration(duration)
.style("height", height + "px");
// Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
let index = -1;
root.eachBefore(function(n) {
n.x = ++index * barHeight;
n.y = n.depth * 20;
});
// Update the nodes…
let node = svg.selectAll(".node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.style("opacity", 0);
// Enter any new nodes at the parent's previous position.
nodeEnter.append("rect")
.attr("y", -barHeight / 2)
.attr("height", barHeight)
.attr("width", barWidth)
.style("fill", color)
.on("click", click);
nodeEnter.append("text")
.attr("dy", 3.5)
.attr("dx", 5.5)
.text(function(d) { return d.data.name; });
// Transition nodes to their new position.
nodeEnter.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1);
node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1)
.select("rect")
.style("fill", color);
// Transition exiting nodes to the parent's new position.
node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.style("opacity", 0)
.remove();
// Stash the old positions for transition.
root.each(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
function moveChildren(node) { // https://stackoverflow.com/questions/19423396/d3-js-how-to-make-all-the-nodes-collapsed-in-collapsible-indented-tree
if(node.children) {
node.children.forEach(function(c) { moveChildren(c); });
node._children = node.children;
node.children = null;
}
}
}
}
References
Expand All/Collapse All d3-tree provides some logic but it requires me to use root
variable which in fact is only local to ngAfterViewInit()
Hook and might not be accessible for other class methods.
How do I achieve this?
angular d3.js
add a comment |
StackBlitz Demo
- Collapsible Indented Tree in Angular Example
- Editor URL
I already have the Tree up and running where all my logic is written within ngAfterViewInit()
Hook.
The code works well. However I wish to add Collapse All
and Expand All
button globally so that a User can use them accordingly without painstakingly click on all the nodes either to collapse or expand the complete tree.
Unfortunately, I have no class methods or variables that are public within the component. This limits the method calls to the buttons:
<button (click)="expandAll()"></button> <!-- expandAll() has nothing to trigger as a parameter-->
hello.component.ts
export class HelloComponent {
@Input() name: string;
ngAfterViewInit(): void {
let margin = {top: 30, right: 10, bottom: 30, left: 20};
let width = 960;
let barHeight = 20;
let barWidth = (width - margin.left - margin.right) * 0.8;
let i = 0, duration = 400, root;
let diagonal = d3.linkHorizontal()
.x((d) => { return d.y; })
.y((d) => { return d.x; });
let svg = d3.select(".tree").append("svg")
.attr("width", width) //+ margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = d3.hierarchy(flares);
root.x0 = 0;
root.y0 = 0;
moveChildren(root);
update(root);
function update(source) {
// Compute the flattened node list.
let nodes = root.descendants();
let height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);
d3.select("svg").transition()
.duration(duration)
.attr("height", height);
d3.select(self.frameElement).transition()
.duration(duration)
.style("height", height + "px");
// Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
let index = -1;
root.eachBefore(function(n) {
n.x = ++index * barHeight;
n.y = n.depth * 20;
});
// Update the nodes…
let node = svg.selectAll(".node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.style("opacity", 0);
// Enter any new nodes at the parent's previous position.
nodeEnter.append("rect")
.attr("y", -barHeight / 2)
.attr("height", barHeight)
.attr("width", barWidth)
.style("fill", color)
.on("click", click);
nodeEnter.append("text")
.attr("dy", 3.5)
.attr("dx", 5.5)
.text(function(d) { return d.data.name; });
// Transition nodes to their new position.
nodeEnter.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1);
node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1)
.select("rect")
.style("fill", color);
// Transition exiting nodes to the parent's new position.
node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.style("opacity", 0)
.remove();
// Stash the old positions for transition.
root.each(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
function moveChildren(node) { // https://stackoverflow.com/questions/19423396/d3-js-how-to-make-all-the-nodes-collapsed-in-collapsible-indented-tree
if(node.children) {
node.children.forEach(function(c) { moveChildren(c); });
node._children = node.children;
node.children = null;
}
}
}
}
References
Expand All/Collapse All d3-tree provides some logic but it requires me to use root
variable which in fact is only local to ngAfterViewInit()
Hook and might not be accessible for other class methods.
How do I achieve this?
angular d3.js
StackBlitz Demo
- Collapsible Indented Tree in Angular Example
- Editor URL
I already have the Tree up and running where all my logic is written within ngAfterViewInit()
Hook.
The code works well. However I wish to add Collapse All
and Expand All
button globally so that a User can use them accordingly without painstakingly click on all the nodes either to collapse or expand the complete tree.
Unfortunately, I have no class methods or variables that are public within the component. This limits the method calls to the buttons:
<button (click)="expandAll()"></button> <!-- expandAll() has nothing to trigger as a parameter-->
hello.component.ts
export class HelloComponent {
@Input() name: string;
ngAfterViewInit(): void {
let margin = {top: 30, right: 10, bottom: 30, left: 20};
let width = 960;
let barHeight = 20;
let barWidth = (width - margin.left - margin.right) * 0.8;
let i = 0, duration = 400, root;
let diagonal = d3.linkHorizontal()
.x((d) => { return d.y; })
.y((d) => { return d.x; });
let svg = d3.select(".tree").append("svg")
.attr("width", width) //+ margin.left + margin.right)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
root = d3.hierarchy(flares);
root.x0 = 0;
root.y0 = 0;
moveChildren(root);
update(root);
function update(source) {
// Compute the flattened node list.
let nodes = root.descendants();
let height = Math.max(500, nodes.length * barHeight + margin.top + margin.bottom);
d3.select("svg").transition()
.duration(duration)
.attr("height", height);
d3.select(self.frameElement).transition()
.duration(duration)
.style("height", height + "px");
// Compute the "layout". TODO https://github.com/d3/d3-hierarchy/issues/67
let index = -1;
root.eachBefore(function(n) {
n.x = ++index * barHeight;
n.y = n.depth * 20;
});
// Update the nodes…
let node = svg.selectAll(".node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
let nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.style("opacity", 0);
// Enter any new nodes at the parent's previous position.
nodeEnter.append("rect")
.attr("y", -barHeight / 2)
.attr("height", barHeight)
.attr("width", barWidth)
.style("fill", color)
.on("click", click);
nodeEnter.append("text")
.attr("dy", 3.5)
.attr("dx", 5.5)
.text(function(d) { return d.data.name; });
// Transition nodes to their new position.
nodeEnter.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1);
node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
.style("opacity", 1)
.select("rect")
.style("fill", color);
// Transition exiting nodes to the parent's new position.
node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.style("opacity", 0)
.remove();
// Stash the old positions for transition.
root.each(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
function color(d) {
return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
}
function moveChildren(node) { // https://stackoverflow.com/questions/19423396/d3-js-how-to-make-all-the-nodes-collapsed-in-collapsible-indented-tree
if(node.children) {
node.children.forEach(function(c) { moveChildren(c); });
node._children = node.children;
node.children = null;
}
}
}
}
References
Expand All/Collapse All d3-tree provides some logic but it requires me to use root
variable which in fact is only local to ngAfterViewInit()
Hook and might not be accessible for other class methods.
How do I achieve this?
angular d3.js
angular d3.js
asked Nov 16 '18 at 16:10
Shan-DesaiShan-Desai
856933
856933
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53341585%2fexpand-and-collapse-d3-collapsible-indented-tree-globally-in-angular-using-butto%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53341585%2fexpand-and-collapse-d3-collapsible-indented-tree-globally-in-angular-using-butto%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown