feat: Export chart option in desktop view
diff --git a/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js b/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
index 694c265..57d34d8 100644
--- a/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
+++ b/erpnext/public/js/hierarchy_chart/hierarchy_chart_desktop.js
@@ -1,3 +1,4 @@
+import html2canvas from 'html2canvas';
 erpnext.HierarchyChart = class {
 	/* Options:
 		- doctype
@@ -11,16 +12,20 @@
 		this.method = method;
 		this.doctype = doctype;
 
+		this.setup_page_style();
+		this.page.main.addClass('frappe-card');
+
+		this.nodes = {};
+		this.setup_node_class();
+	}
+
+	setup_page_style() {
 		this.page.main.css({
 			'min-height': '300px',
 			'max-height': '600px',
 			'overflow': 'auto',
 			'position': 'relative'
 		});
-		this.page.main.addClass('frappe-card');
-
-		this.nodes = {};
-		this.setup_node_class();
 	}
 
 	setup_node_class() {
@@ -84,7 +89,7 @@
 
 					// svg for connectors
 					me.make_svg_markers();
-					me.setup_hierarchy()
+					me.setup_hierarchy();
 					me.render_root_nodes();
 					me.all_nodes_expanded = false;
 				}
@@ -97,6 +102,10 @@
 
 	setup_actions() {
 		let me = this;
+		this.page.add_inner_button(__('Export'), function() {
+			me.export_chart();
+		});
+
 		this.page.add_inner_button(__('Expand All'), function() {
 			me.load_children(me.root_node, true);
 			me.all_nodes_expanded = true;
@@ -113,6 +122,36 @@
 		});
 	}
 
+	export_chart() {
+		this.page.main.css({
+			'min-height': '',
+			'max-height': '',
+			'overflow': 'visible',
+			'position': 'fixed',
+			'left': '0',
+			'top': '0'
+		});
+
+		$('.node-card').addClass('exported');
+
+		html2canvas(document.querySelector('#hierarchy-chart-wrapper'), {
+			scrollY: -window.scrollY,
+			scrollX: 0
+		}).then(function(canvas) {
+			// Export the canvas to its data URI representation
+			let dataURL = canvas.toDataURL('image/png');
+
+			// download the image
+			let a = document.createElement('a');
+			a.href = dataURL;
+			a.download = 'hierarchy_chart';
+			a.click();
+		});
+
+		this.setup_page_style();
+		$('.node-card').removeClass('exported');
+	}
+
 	setup_hierarchy() {
 		if (this.$hierarchy)
 			this.$hierarchy.remove();
@@ -127,33 +166,37 @@
 				</li>
 			</ul>`);
 
-		this.page.main.append(this.$hierarchy);
+		this.page.main
+			.find('#hierarchy-chart-wrapper')
+			.append(this.$hierarchy);
 		this.nodes = {};
 	}
 
 	make_svg_markers() {
 		$('#arrows').remove();
 
-		this.page.main.prepend(`
-			<svg id="arrows" width="100%" height="100%">
-				<defs>
-					<marker id="arrowhead-active" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="6" markerHeight="6" orient="auto" fill="var(--blue-500)">
-						<path d="M 0 0 L 10 5 L 0 10 z"></path>
-					</marker>
-					<marker id="arrowhead-collapsed" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="6" markerHeight="6" orient="auto" fill="var(--blue-300)">
-						<path d="M 0 0 L 10 5 L 0 10 z"></path>
-					</marker>
+		this.page.main.append(`
+			<div id="hierarchy-chart-wrapper">
+				<svg id="arrows" width="100%" height="100%">
+					<defs>
+						<marker id="arrowhead-active" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="6" markerHeight="6" orient="auto" fill="var(--blue-500)">
+							<path d="M 0 0 L 10 5 L 0 10 z"></path>
+						</marker>
+						<marker id="arrowhead-collapsed" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="6" markerHeight="6" orient="auto" fill="var(--blue-300)">
+							<path d="M 0 0 L 10 5 L 0 10 z"></path>
+						</marker>
 
-					<marker id="arrowstart-active" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="8" markerHeight="8" orient="auto" fill="var(--blue-500)">
-						<circle cx="4" cy="4" r="3.5" fill="white" stroke="var(--blue-500)"/>
-					</marker>
-					<marker id="arrowstart-collapsed" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="8" markerHeight="8" orient="auto" fill="var(--blue-300)">
-						<circle cx="4" cy="4" r="3.5" fill="white" stroke="var(--blue-300)"/>
-					</marker>
-				</defs>
-				<g id="connectors" fill="none">
-				</g>
-			</svg>`);
+						<marker id="arrowstart-active" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="8" markerHeight="8" orient="auto" fill="var(--blue-500)">
+							<circle cx="4" cy="4" r="3.5" fill="white" stroke="var(--blue-500)"/>
+						</marker>
+						<marker id="arrowstart-collapsed" viewBox="0 0 10 10" refX="3" refY="5" markerWidth="8" markerHeight="8" orient="auto" fill="var(--blue-300)">
+							<circle cx="4" cy="4" r="3.5" fill="white" stroke="var(--blue-300)"/>
+						</marker>
+					</defs>
+					<g id="connectors" fill="none">
+					</g>
+				</svg>
+			</div>`);
 	}
 
 	render_root_nodes(expanded_view=false) {
@@ -310,7 +353,7 @@
 		let entry = undefined;
 		let node = undefined;
 
-		while(data_list.length) {
+		while (data_list.length) {
 			// to avoid overlapping connectors
 			entry = data_list.shift();
 			node = this.nodes[entry.parent];
@@ -323,7 +366,7 @@
 	}
 
 	render_child_nodes_for_expanded_view(node, child_nodes) {
-		node.$children = $('<ul class="node-children"></ul>')
+		node.$children = $('<ul class="node-children"></ul>');
 
 		const last_level = this.$hierarchy.find('.level:last').index();
 		const node_level = $(`#${node.id}`).parent().parent().parent().index();
diff --git a/erpnext/public/scss/hierarchy_chart.scss b/erpnext/public/scss/hierarchy_chart.scss
index 1c2f942..44288fe 100644
--- a/erpnext/public/scss/hierarchy_chart.scss
+++ b/erpnext/public/scss/hierarchy_chart.scss
@@ -21,6 +21,10 @@
 	}
 }
 
+.node-card.exported {
+	box-shadow: none
+}
+
 .node-image {
 	width: 3.0rem;
 	height: 3.0rem;
@@ -178,9 +182,12 @@
 }
 
 // horizontal hierarchy tree view
+#hierarchy-chart-wrapper {
+	padding-top: 30px;
+}
+
 .hierarchy {
 	display: flex;
-	padding-top: 30px;
 }
 
 .hierarchy li {
@@ -200,6 +207,7 @@
 #arrows {
 	position: absolute;
 	overflow: visible;
+	margin-top: -80px;
 }
 
 .active-connector {
diff --git a/erpnext/utilities/hierarchy_chart.py b/erpnext/utilities/hierarchy_chart.py
index 9b02793..22d3f28 100644
--- a/erpnext/utilities/hierarchy_chart.py
+++ b/erpnext/utilities/hierarchy_chart.py
@@ -3,14 +3,16 @@
 
 from __future__ import unicode_literals
 import frappe
+import os
 from frappe import _
+from frappe.utils.pdf import get_pdf
 
 @frappe.whitelist()
 def get_all_nodes(parent, parent_name, method, company):
 	'''Recursively gets all data from nodes'''
 	method = frappe.get_attr(method)
 
-	if not method in frappe.whitelisted:
+	if method not in frappe.whitelisted:
 		frappe.throw(_('Not Permitted'), frappe.PermissionError)
 
 	data = method(parent, company)