From 5e91071f6dd6a6b311b7d4cdbb0c24c4bfe33324 Mon Sep 17 00:00:00 2001 From: "Abdallah A. Zaqout" <26047413+zaqoutabed@users.noreply.github.com> Date: Mon, 26 May 2025 16:33:34 +0300 Subject: [PATCH 1/4] feat: enable user to export chart data --- .../public/js/frappe/widgets/chart_widget.js | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index 57f7a6e03e..e5a0f3fc65 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -311,6 +311,30 @@ export default class ChartWidget extends Widget { this.make_chart(); }, }, + { + label: __("Export {0}", [__(this.chart_doc.chart_name)]), + action: "action-export", + handler: () => { + let data = []; + const datasets = this.data?.datasets || []; + const labels = (this.data?.labels || []).map(label => label || "None"); + if (datasets.length > 0) { + datasets.forEach((element) => { + const name = element.name; + const values = element.values || []; + if (values.length > 0) { + data.push([name || this.chart_doc.chart_name]); + data.push(labels); + data.push(values); + } + }); + } else { + data.push([this.chart_doc.chart_name]); + data.push(labels); + } + frappe.tools.downloadify(data, null, this.chart_doc.chart_name); + }, + } ]; if (this.chart_doc.document_type) { From 4f2997bfae33a9d7eb46c699dc3cb3737462684a Mon Sep 17 00:00:00 2001 From: "Abdallah A. Zaqout" <26047413+zaqoutabed@users.noreply.github.com> Date: Tue, 27 May 2025 10:19:16 +0300 Subject: [PATCH 2/4] refactor: handle multi dataset --- .../public/js/frappe/widgets/chart_widget.js | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index e5a0f3fc65..c6d55fed2b 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -315,26 +315,42 @@ export default class ChartWidget extends Widget { label: __("Export {0}", [__(this.chart_doc.chart_name)]), action: "action-export", handler: () => { - let data = []; + const data = [[this.chart_doc.chart_name]]; + data.push([]); + data.push([]); + const datasets = this.data?.datasets || []; - const labels = (this.data?.labels || []).map(label => label || "None"); - if (datasets.length > 0) { + const labels = (this.data?.labels || []).map((label) => label || "None"); + if (datasets.length > 1) { + const csv_labels = []; + const csv_values = []; + labels.forEach((label, idx) => { + datasets.forEach((element) => { + csv_labels.push(`${element.name} (${label})`); + const values = element.values || []; + if(idx < values.length){ + csv_values.push(values[idx]); + } else { + csv_values.push(''); + } + }); + }); + data.push(["", ...csv_labels]); + data.push(["", ...csv_values]); + } else if (datasets.length === 1) { datasets.forEach((element) => { - const name = element.name; const values = element.values || []; if (values.length > 0) { - data.push([name || this.chart_doc.chart_name]); - data.push(labels); - data.push(values); + data.push(["", ...labels]); + data.push(["", ...values]); } }); } else { - data.push([this.chart_doc.chart_name]); - data.push(labels); + data.push(["", ...labels]); } frappe.tools.downloadify(data, null, this.chart_doc.chart_name); }, - } + }, ]; if (this.chart_doc.document_type) { From 23e44ae8eed369a1cad2bc3516a6a31df7b19988 Mon Sep 17 00:00:00 2001 From: "Abdallah A. Zaqout" <26047413+zaqoutabed@users.noreply.github.com> Date: Tue, 3 Jun 2025 12:19:59 +0300 Subject: [PATCH 3/4] refactor: fix pre-commit issues --- frappe/public/js/frappe/widgets/chart_widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index c6d55fed2b..e48d84b7dc 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -328,10 +328,10 @@ export default class ChartWidget extends Widget { datasets.forEach((element) => { csv_labels.push(`${element.name} (${label})`); const values = element.values || []; - if(idx < values.length){ + if (idx < values.length) { csv_values.push(values[idx]); } else { - csv_values.push(''); + csv_values.push(""); } }); }); From 244a986cb9952fbb9ae827c6bc227fb8742bb5ea Mon Sep 17 00:00:00 2001 From: "Abdallah A. Zaqout" <26047413+zaqoutabed@users.noreply.github.com> Date: Thu, 5 Jun 2025 11:24:01 +0300 Subject: [PATCH 4/4] refactor: remove chart name from the label --- frappe/public/js/frappe/widgets/chart_widget.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js index e48d84b7dc..7130506ae0 100644 --- a/frappe/public/js/frappe/widgets/chart_widget.js +++ b/frappe/public/js/frappe/widgets/chart_widget.js @@ -312,7 +312,7 @@ export default class ChartWidget extends Widget { }, }, { - label: __("Export {0}", [__(this.chart_doc.chart_name)]), + label: __("Export"), action: "action-export", handler: () => { const data = [[this.chart_doc.chart_name]];