Merge pull request #8587 from prssanna/group-by-dashboard
feat(Dashboards): Add group by dashboard chart type
This commit is contained in:
commit
0f62dcae04
6 changed files with 207 additions and 603 deletions
|
|
@ -17,7 +17,7 @@
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.chart-loading-state {
|
||||
.chart-loading-state, .chart-empty-state {
|
||||
height: 100%;
|
||||
margin-top: 160px;
|
||||
text-align: center;
|
||||
|
|
|
|||
|
|
@ -226,23 +226,26 @@ class DashboardChart {
|
|||
"Line": "line",
|
||||
"Bar": "bar",
|
||||
};
|
||||
let chart_args = {
|
||||
title: this.chart_doc.chart_name,
|
||||
data: this.data,
|
||||
type: chart_type_map[this.chart_doc.type],
|
||||
truncateLegends: 1,
|
||||
colors: [this.chart_doc.color || "light-blue"],
|
||||
axisOptions: {
|
||||
xIsSeries: this.chart_doc.timeseries,
|
||||
shortenYAxisNumbers: 1
|
||||
}
|
||||
};
|
||||
this.chart_container.find('.chart-loading-state').addClass('hide');
|
||||
|
||||
if(!this.chart) {
|
||||
this.chart = new frappe.Chart(this.chart_container.find(".chart-wrapper")[0], chart_args);
|
||||
this.chart_container.find('.chart-loading-state').addClass('hide');
|
||||
if (!this.data) {
|
||||
this.chart_container.find('.chart-empty-state').removeClass('hide');
|
||||
} else {
|
||||
this.chart.update(this.data);
|
||||
let chart_args = {
|
||||
title: this.chart_doc.chart_name,
|
||||
data: this.data,
|
||||
type: chart_type_map[this.chart_doc.type],
|
||||
colors: [this.chart_doc.color || "light-blue"],
|
||||
axisOptions: {
|
||||
xIsSeries: this.chart_doc.timeseries,
|
||||
shortenYAxisNumbers: 1
|
||||
}
|
||||
};
|
||||
if (!this.chart) {
|
||||
this.chart = new frappe.Chart(this.chart_container.find(".chart-wrapper")[0], chart_args);
|
||||
} else {
|
||||
this.chart.update(this.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ frappe.ui.form.on('Dashboard Chart', {
|
|||
// set timeseries based on chart type
|
||||
if (['Count', 'Average', 'Sum'].includes(frm.doc.chart_type)) {
|
||||
frm.set_value('timeseries', 1);
|
||||
} else {
|
||||
frm.set_value('timeseries', 0);
|
||||
}
|
||||
frm.set_value('document_type', '');
|
||||
},
|
||||
|
|
@ -38,6 +40,7 @@ frappe.ui.form.on('Dashboard Chart', {
|
|||
|
||||
timespan: function(frm) {
|
||||
const time_interval_options = {
|
||||
"Select Date Range": ["Quarterly", "Monthly", "Weekly", "Daily"],
|
||||
"Last Year": ["Quarterly", "Monthly", "Weekly", "Daily"],
|
||||
"Last Quarter": ["Monthly", "Weekly", "Daily"],
|
||||
"Last Month": ["Weekly", "Daily"],
|
||||
|
|
@ -55,10 +58,14 @@ frappe.ui.form.on('Dashboard Chart', {
|
|||
{label: __('Last Modified On'), value: 'modified'}
|
||||
];
|
||||
let value_fields = [];
|
||||
let group_by_fields = [];
|
||||
let aggregate_function_fields = [];
|
||||
let update_form = function() {
|
||||
// update select options
|
||||
frm.set_df_property('based_on', 'options', date_fields);
|
||||
frm.set_df_property('value_based_on', 'options', value_fields);
|
||||
frm.set_df_property('group_by_based_on', 'options', group_by_fields);
|
||||
frm.set_df_property('aggregate_function_based_on', 'options', aggregate_function_fields);
|
||||
frm.trigger("show_filters");
|
||||
}
|
||||
|
||||
|
|
@ -72,6 +79,10 @@ frappe.ui.form.on('Dashboard Chart', {
|
|||
}
|
||||
if (['Int', 'Float', 'Currency', 'Percent'].includes(df.fieldtype)) {
|
||||
value_fields.push({label: df.label, value: df.fieldname});
|
||||
aggregate_function_fields.push({label: df.label, value: df.fieldname});
|
||||
}
|
||||
if (['Link', 'Select'].includes(df.fieldtype)) {
|
||||
group_by_fields.push({label: df.label, value: df.fieldname});
|
||||
}
|
||||
});
|
||||
update_form();
|
||||
|
|
|
|||
|
|
@ -1,703 +1,212 @@
|
|||
{
|
||||
"allow_copy": 0,
|
||||
"allow_events_in_timeline": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:chart_name",
|
||||
"beta": 0,
|
||||
"creation": "2019-01-10 12:28:06.282875",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"chart_name",
|
||||
"chart_type",
|
||||
"source",
|
||||
"document_type",
|
||||
"based_on",
|
||||
"value_based_on",
|
||||
"group_by_type",
|
||||
"group_by_based_on",
|
||||
"aggregate_function_based_on",
|
||||
"number_of_groups",
|
||||
"column_break_6",
|
||||
"timespan",
|
||||
"from_date",
|
||||
"to_date",
|
||||
"time_interval",
|
||||
"timeseries",
|
||||
"filters_section",
|
||||
"filters_json",
|
||||
"chart_options_section",
|
||||
"type",
|
||||
"width",
|
||||
"column_break_2",
|
||||
"color",
|
||||
"section_break_10",
|
||||
"last_synced_on"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "chart_name",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Chart Name",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "chart_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Chart Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Count\nSum\nAverage\nCustom",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Count\nSum\nAverage\nCustom\nGroup By"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.chart_type === 'Custom'",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "source",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Chart Source",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Dashboard Chart Source",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Dashboard Chart Source"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.chart_type !== 'Custom'",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "document_type",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Document Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "DocType"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.chart_type !== 'Custom'",
|
||||
"fetch_if_empty": 0,
|
||||
"depends_on": "eval: ['Count', 'Sum', 'Average'].includes(doc.chart_type)",
|
||||
"fieldname": "based_on",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Time Series Based On",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Time Series Based On"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: ['Sum', 'Average'].includes(doc.chart_type)",
|
||||
"fetch_if_empty": 0,
|
||||
"depends_on": "eval: ['Sum', 'Average'].includes(doc.chart_type)\n",
|
||||
"fieldname": "value_based_on",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Value Based On",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Value Based On"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_6",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "timeseries",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "timespan",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Timespan",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Last Year\nLast Quarter\nLast Month\nLast Week",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Last Year\nLast Quarter\nLast Month\nLast Week\nSelect Date Range"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "timeseries",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "time_interval",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Time Interval",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Quarterly\nMonthly\nWeekly\nDaily",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"options": "Quarterly\nMonthly\nWeekly\nDaily"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"default": "0",
|
||||
"depends_on": "eval:doc.chart_type !== 'Group By'",
|
||||
"fieldname": "timeseries",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Time Series",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Time Series"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "filters_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Filters",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Filters"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "",
|
||||
"depends_on": "",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "filters_json",
|
||||
"fieldtype": "Code",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Filters JSON",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "JSON",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "chart_options_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Chart Options",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Chart Options"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Line\nBar",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "width",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Width",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Half\nFull",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "column_break_2",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "color",
|
||||
"fieldtype": "Color",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Color",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"label": "Color"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_in_quick_entry": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "last_synced_on",
|
||||
"fieldtype": "Datetime",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Last Synced On",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"translatable": 0,
|
||||
"unique": 0
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.chart_type === 'Group By'",
|
||||
"fieldname": "group_by_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Group By Based On"
|
||||
},
|
||||
{
|
||||
"default": "Count",
|
||||
"depends_on": "eval:doc.chart_type === 'Group By'",
|
||||
"fieldname": "group_by_type",
|
||||
"fieldtype": "Select",
|
||||
"label": "Group By Type",
|
||||
"options": "Count\nSum\nAverage"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: ['Sum', 'Average'].includes(doc.group_by_type)",
|
||||
"fieldname": "aggregate_function_based_on",
|
||||
"fieldtype": "Select",
|
||||
"label": "Aggregate Function Based On"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.chart_type === 'Group By'",
|
||||
"fieldname": "number_of_groups",
|
||||
"fieldtype": "Int",
|
||||
"label": "Number of Groups"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.timespan === 'Choose Time Span'",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "From Date"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.timespan === 'Choose Time Span'",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
"label": "To Date"
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-04-09 15:04:02.434131",
|
||||
"modified": "2019-10-29 02:26:14.838057",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Desk",
|
||||
"name": "Dashboard Chart",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"cancel": 0,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0,
|
||||
"track_views": 0
|
||||
"track_changes": 1
|
||||
}
|
||||
|
|
@ -12,19 +12,30 @@ from frappe.model.document import Document
|
|||
|
||||
@frappe.whitelist()
|
||||
@cache_source
|
||||
def get(chart_name = None, chart = None, no_cache = None, from_date=None, to_date=None, refresh = None):
|
||||
def get(chart_name = None, chart = None, no_cache = None, from_date = None, to_date = None, refresh = None):
|
||||
if chart_name:
|
||||
chart = frappe.get_doc('Dashboard Chart', chart_name)
|
||||
else:
|
||||
chart = frappe._dict(frappe.parse_json(chart))
|
||||
|
||||
timespan = chart.timespan
|
||||
from_date = chart.from_date
|
||||
to_date = chart.to_date
|
||||
timegrain = chart.time_interval
|
||||
filters = frappe.parse_json(chart.filters_json)
|
||||
|
||||
# don't include cancelled documents
|
||||
filters['docstatus'] = ('<', 2)
|
||||
|
||||
if chart.chart_type == 'Group By':
|
||||
chart_config = get_group_by_chart_config(chart, filters)
|
||||
else:
|
||||
chart_config = get_chart_config(chart, filters, timespan, timegrain, from_date, to_date)
|
||||
|
||||
return chart_config
|
||||
|
||||
|
||||
def get_chart_config(chart, filters, timespan, timegrain, from_date, to_date):
|
||||
if not from_date:
|
||||
from_date = get_from_date_from_timespan(to_date, timespan)
|
||||
if not to_date:
|
||||
|
|
@ -32,7 +43,6 @@ def get(chart_name = None, chart = None, no_cache = None, from_date=None, to_dat
|
|||
|
||||
# get conditions from filters
|
||||
conditions, values = frappe.db.build_conditions(filters)
|
||||
|
||||
# query will return year, unit and aggregate value
|
||||
data = frappe.db.sql('''
|
||||
select
|
||||
|
|
@ -63,7 +73,7 @@ def get(chart_name = None, chart = None, no_cache = None, from_date=None, to_dat
|
|||
# add missing data points for periods where there was no result
|
||||
result = add_missing_values(result, timegrain, from_date, to_date)
|
||||
|
||||
return {
|
||||
chart_config = {
|
||||
"labels": [formatdate(r[0].strftime('%Y-%m-%d')) for r in result],
|
||||
"datasets": [{
|
||||
"name": chart.name,
|
||||
|
|
@ -71,11 +81,53 @@ def get(chart_name = None, chart = None, no_cache = None, from_date=None, to_dat
|
|||
}]
|
||||
}
|
||||
|
||||
return chart_config
|
||||
|
||||
|
||||
def get_group_by_chart_config(chart, filters):
|
||||
conditions, values = frappe.db.build_conditions(filters)
|
||||
data = frappe.db.sql('''
|
||||
select
|
||||
{aggregate_function}({value_field}) as count,
|
||||
{group_by_field} as name
|
||||
from `tab{doctype}`
|
||||
where {conditions}
|
||||
group by {group_by_field}
|
||||
order by count desc
|
||||
'''.format(
|
||||
aggregate_function = get_aggregate_function(chart.group_by_type),
|
||||
value_field = chart.aggregate_function_based_on or '1',
|
||||
field = chart.aggregate_function_based_on or chart.group_by_based_on,
|
||||
group_by_field = chart.group_by_based_on,
|
||||
doctype = chart.document_type,
|
||||
conditions = conditions,
|
||||
), values, as_dict = True)
|
||||
|
||||
if data:
|
||||
if chart.number_of_groups and chart.number_of_groups < len(data):
|
||||
other_count = 0
|
||||
for i in range(chart.number_of_groups - 1, len(data)):
|
||||
other_count += data[i]['count']
|
||||
data = data[0: chart.number_of_groups - 1]
|
||||
data.append({'name': 'Other', 'count': other_count})
|
||||
|
||||
chart_config = {
|
||||
"labels": [item['name'] if item['name'] else 'Not Specified' for item in data],
|
||||
"datasets": [{
|
||||
"name": chart.name,
|
||||
"values": [item['count'] for item in data]
|
||||
}]
|
||||
}
|
||||
return chart_config
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def get_aggregate_function(chart_type):
|
||||
return {
|
||||
"Sum": "SUM",
|
||||
"Count": "COUNT",
|
||||
"Average": "AVG"
|
||||
"Average": "AVG",
|
||||
}[chart_type]
|
||||
|
||||
def convert_to_dates(data, timegrain):
|
||||
|
|
@ -210,7 +262,14 @@ class DashboardChart(Document):
|
|||
self.check_required_field()
|
||||
|
||||
def check_required_field(self):
|
||||
if not self.based_on:
|
||||
frappe.throw(_("Time series based on is required to create a dashboard chart"))
|
||||
if not self.document_type:
|
||||
frappe.throw(_("Document type is required to create a dashboard chart"))
|
||||
frappe.throw(_("Document type is required to create a dashboard chart"))
|
||||
|
||||
if self.chart_type == 'Group By':
|
||||
if not self.group_by_based_on:
|
||||
frappe.throw(_("Group By field is required to create a dashboard chart"))
|
||||
if self.group_by_type in ['Sum', 'Average'] and not self.aggregate_function_based_on:
|
||||
frappe.throw(_("Aggregate Function field is required to create a dashboard chart"))
|
||||
else:
|
||||
if not self.based_on:
|
||||
frappe.throw(_("Time series based on is required to create a dashboard chart"))
|
||||
|
|
|
|||
|
|
@ -129,3 +129,25 @@ class TestDashboardChart(unittest.TestCase):
|
|||
self.assertEqual(result.get('datasets')[0].get('values')[2], 0)
|
||||
|
||||
frappe.db.rollback()
|
||||
|
||||
def test_group_by_chart_type(self):
|
||||
if frappe.db.exists('Dashboard Chart', 'Test Group By Dashboard Chart'):
|
||||
frappe.delete_doc('Dashboard Chart', 'Test Group By Dashboard Chart')
|
||||
|
||||
frappe.get_doc({"doctype":"ToDo", "description": "test"}).insert()
|
||||
|
||||
frappe.get_doc(dict(
|
||||
doctype = 'Dashboard Chart',
|
||||
chart_name = 'Test Group By Dashboard Chart',
|
||||
chart_type = 'Group By',
|
||||
document_type = 'ToDo',
|
||||
group_by_based_on = 'status',
|
||||
filters_json = '{}',
|
||||
)).insert()
|
||||
|
||||
result = get(chart_name ='Test Group By Dashboard Chart', refresh = 1)
|
||||
todo_status_count = frappe.db.count('ToDo', {'status': result.get('labels')[0]})
|
||||
|
||||
self.assertEqual(result.get('datasets')[0].get('values')[0], todo_status_count)
|
||||
|
||||
frappe.db.rollback()
|
||||
Loading…
Add table
Reference in a new issue