Skip to content

Programming Standards - Visualization

Visualisation

Define Column width

Set an explicit width for each column to ensure consistent layout and prevent unpredictable wrapping or overflow.

Why:
Prevents layout shifts and wrapping in table columns.

❌ Incorrect way

la_columns = [
{
"fieldname": "weekly_capacity",
"label": _("Weekly Capacity"),
"fieldtype": "Int",
},
]

✅ Correct Way

la_columns = [
{
"fieldname": "weekly_capacity",
"label": _("Weekly Capacity"),
"fieldtype": "Int",
"width": 50,// ✅ Correct Way
},
]

Static Key Column

Key columns (e.g., primary identifiers) should remain fixed when scrolling horizontally.

Why: Keeping key columns static ensures users retain context while scrolling, preventing misinterpretation of data in wide tables.

❌ Incorrect way

L_STYLE.innerHTML = `
.dt-instance-1 .dt-cell--col-0 {
display: flex;
text-align: right;
z-index: 2;
left: 0px; /* Adjust this value to match the width of col-1 */
},

✅ Correct Way

L_STYLE.innerHTML = `
.dt-instance-1 .dt-cell--col-0 {
display: flex;
text-align: right;
position: sticky; // ✅ Correct Way
z-index: 2;
left: 30px; /* Adjust this value to match the width of col-1 */
}`;

Mandatory Fields Should Have Default Values

Why: Prevents empty report load and improves user experience.

❌ Incorrect way

{
"fieldname": "from_date",
"label": __("From Date"),
"fieldtype": "Date",
"required": 1
}

✅ Correct Way

{
"fieldname": "from_date",
"label": __("From Date"),
"fieldtype": "Date",
"required": 1,
"default": frappe.datetime.month_start() //✅ Correct Way
}

Use Charts for Large Datasets

Use visual summaries (charts) when the dataset exceeds a manageable number of rows or when trends are more important than individual records.

Why:
Charts help users grasp patterns, exceptions, and trends quickly — especially when tabular data grows too large to scan efficiently.

✅ Correct Way


Avoid break in label

Use single-line, non-breaking labels for fields to maintain visual consistency and avoid misalignment in report headers.

Why: Multi-line labels reduce readability and cause inconsistent UI.

❌ Incorrect Way

{
"fieldname": "sales_order",
"label": _("Sales<br>Order"), //❌ Incorrect Way
"fieldtype": "Link",
"options": "Sales Order",
"width": 140},

✅ Correct Way

{
"fieldname": "sales_order",
"label": __("Sales Order"), // ✅ Correct Way
"fieldtype": "Link",
"options": "Sales Order",
"width": 140,
"label_style": "white-space: nowrap; overflow: hidden; text-overflow: ellipsis;" // ✅ Correct Way
}

Enable rows checkbox

Use checkboxes to allow selection of multiple rows in a report, enabling batch actions or easier comparisons.

Why:
Enabling row checkboxes improves usability for tasks that require selecting multiple entries (e.g., bulk processing, exporting, linking). It provides a familiar and intuitive UI pattern, especially for users dealing with large datasets.

✅ Correct Way

get_datatable_options: function (iOptions) { // ✅ Correct Way
return Object.assign(iOptions, {
checkboxColumn: true,
});
},

Use Meaningful Colors in Charts

Apply distinct, consistent colors to represent categories or metrics in charts.

Why:
Color helps users quickly differentiate data series and understand visual trends. Using random or similar colors confuses interpretation, especially in stacked or multi-series charts.

✅ Correct Way

colors: ["#1abc9c", "#e74c3c", "#3498db", "#f39c12"]

Apply Conditional Formatting for Threshold Violations

Why: Visually alerts users when values exceed limits like weekly capacity.

❌ Incorrect Way

if (idData[col] > weekly_capacity) {
// no formatting
}

✅ Correct Way

if (idData[idColumn.fieldname] > idData["weekly_capacity"]) {
$lValue.addClass("bg-danger text-white");
}

Set Chart Height Explicitly

Why: Prevents layout issues and ensures consistent chart visibility.

❌ Incorrect Way

svg.frappe-chart.chart {
/* no height set */
}

✅ Correct Way

svg.frappe-chart.chart {
height: 320px;
}

Customize Tooltip for Better Readability

Why: Improves clarity in charts by preventing tooltip overflow and misalignment.

❌ Incorrect Way

.graph-svg-tip.comparison {
/* default styles lead to overflow or misalignment */
}

✅ Correct Way

.graph-svg-tip.comparison {
text-align: left;
padding: 0px;
pointer-events: none;
top: -130px !important;
width: 350px !important;
}

Use Tree Grid for Hierarchical

Why: Enables users to visualize nested structures intuitively.

❌ Incorrect Way

frappe.query_reports['BOM Analysis'] = {
// no tree config
}

✅ Correct Way

frappe.query_reports['BOM Analysis'] = {
tree: true,
name_field: "quotation",
parent_field: "parent_quotation",
initial_depth: 1,
}

Visual Percent Change Indicators with Color Coding

Why: Quickly highlights variance between primary BOM and comparison BOM.

❌ Incorrect Way

if (val1 < val2) {
// No formatting or visual clue
}

✅ Correct Way

if (val1 < val2) {
$value = $(value).css("color", "red");
$value.addClass("text-danger");
$value.text("(+" + percent + "%)" + $(value).text());
}