How to Add a Chart to Module’s Detail View

Disclaimer: This is a very quick solution and can be adapted/improved to suit your needs.

Charts are helpful for users to view information at a glance. The current problem is that they only appear (on SuiteCRM 7) on dashlets or via Reports (AOR_Reports) module. Wouldn’t it be nice to view a chart within the Detail View of a module AND be able to define parameters specific to that module’s record?

The following tutorial we are going to be doing the following to achieve this:

  • Create a generic Chart with (simple) parameters. Our example will be Show a Pie Chart of an Account’s Opportunities grouped by Sales Stage.
  • Create a non-db field with function attribute
  • Add non-db field to Detail View of a module (e.g Accounts)
  • Create a function that will render a Chart passing in parameters based on the record’s data
  • View the Chart on the record’s Detail View

Steps:

  1. Navigate to Reports module and Create a new Report.

  2. Set the Report Module to Opportunities (e.g)

  3. Add the Fields: Opportunities > Sales Stage and Opportunities > Opportunity Amount

  4. Add the Conditions: Opportunities : Accounts > ID

  5. Set the Conditions for Opportunities : Accounts > ID : Field Operator = Equal To

  6. Set the Conditions for Opportunities : Accounts > ID : Type = Value

  7. Set the Conditions for Opportunities : Accounts > ID : Value =

  8. Set the Conditions for Opportunities : Accounts > ID : Parameter = True

  9. Add a Chart (Name = , Type = Pie chart, X Axis = Opportunities – Sales Stage, Y Axis = Opportunities – Opportunity Amount)

  1. Save the Report and confirm it works using an appropriate Account ID
    Note: This is only an example. As long as the Chart is visible you can render it in the following function.

  2. Create a new vardef in target module. Create a file* in custom/Extension/modules/Accounts/Ext/Vardefs/show_me_chart_c.php
    *This file can be named anything suitable

<?php
$dictionary["Account"]["fields"]["show_me_chart_c"]=
   array(
                'required' => false,
                'name' => 'show_me_chart_c',
                'vname' => 'LBL_SHOW_ME_CHART_C',
                'type' => 'function',
                'source' => 'non-db',
                'massupdate' => 0,
                'importable' => 'false',
                'duplicate_merge' => 'disabled',
                'duplicate_merge_dom_value' => 0,
                'audited' => false,
                'reportable' => false,
                'inline_edit' => false,
                'studio' => true,
                'function' =>
                    array(
                        'name' => 'display_chart',
                        'returns' => 'html',
                        'include' => 'custom/modules/Accounts/display_chart.php'
                    ),
            );

 ?>

Note: The important sections are:

source => non-db
This will define that no value will be saved to this field and be used ad-hoc.

studio => true
If you wish to move this field onto the Detail View via studio, set this to true. Else you will need to add this custom field via viewdefs manually.

function => array()
Ensure that the function include attribute is pointing to the anticipated file that will include the function “display_chart”.

  1. Create the Language file that will Label your new custom field. Create a file* in custom/Extension/modules/Accounts/Ext/Language/en_us.show_me_chart_c.php
    *This file can be named anything suitable (but consider making it the same as the vardefs field name for easy reference)
    Change “en_us” in the filename depending on the languages you use in your instance.
    Ensure that the vardef’s ‘vname’ matches the mod_strings key.
<?php
       $mod_strings['LBL_SHOW_ME_CHART_C'] = 'Chart';
  1. Create the custom function linked to the non-db field. Create the file custom/modules/Accounts/display_chart.php

Below is the copy & paste of the function but steps following will explain specific areas of interest.
:::Start of code explanation:::

<?php
function display_chart($focus, $field, $value, $view){

global $sugar_config, $locale, $app_list_strings, $mod_strings;

    if($view == 'DetailView'){
        
        $aor_Report = BeanFactory::newBean('AOR_Reports'); 
        $aor_Report->retrieve('1a992459-15d4-eef3-e370-625e905e9dcb'); // the ID of the pre-defined report
        // loop through the conditions to find the right parameter
        $condition = getConditionsAsParameters($aor_Report);
        $params = array();
        foreach($condition as $con){
            // My report target condition is:
            // Opportunities : Accounts : ID ==(Equal_To) a specific value_type(Value)
            if($con['operator'] == 'Equal_To' && $con['value_type'] == 'Value' && $con['field_display'] == 'ID') {
            // For the life of me couldn't easily compare $con['module_display'] had to use a reg_ex
            $re = "/\\bOpportunities\\b(.*?)\\bAccounts\\b/"; 
            preg_match($re, $con['module_display'], $matches);
            if(!empty($matches[0])){
            // Let's define this pamater value dynamically
                        $params[$con['id']] = array(
                            'id' => $con['id'],
                            'operator' => $con['operator'],
                            'type' => $con['value_type'],
                            'value' => $focus->id // This is the account's ID which you are viewing
                        );
            }
    
}       
        }
        $aor_Report->user_parameters = $params;
        
        return $aor_Report->build_report_chart(null, AOR_Report::CHART_TYPE_RGRAPH);

    }

}

?>
  1. Add the function which will utilise the $focus to capture the record being viewed. We only want to execute when the passed parameter $view is “DetailView”.
    Once we’ve confirmed it’s in DetailView we must retrieve the target Report (which contains the Chart). Copy the ID of the Report created in Step 10 and set it when retrieving the AOR_Reports bean.

  2. Grab the Report’s Parameters by looping the Report’s conditions to find the specific one we wish to update dynamically.
    Note: There isn’t a clear way to define each condition without checking a combination of values :sob:. Also to note I couldn’t get the ‘module_display’ string to match so I resorted to using a preg_match :sob: :sob:. This preg_match would only work for conditions with a single relationship jump e.g Opportunities : Accounts. Adapt it to suit your needs.

  3. Update the Report’s Parameters and set “Value” = $focus > id (Account ID)

  4. Set new parameters to AOR_Report user_parameters

  5. Return the build_report_chart passing in Report and new Parameters.
    :::End of code explanation:::

  6. Execute a Repair & Rebuild to generate new non-db field.

  7. Add the new non-db field to Account’s Detail View. Navigate to Studio > Accounts > Layouts > Detail View and add your new field where is suitable (I would recommend making it multi columned to give it a wider space).

  8. View any Account’s Detail View to see the new Chart. Well Done. :clap:

5 Likes

This is a great tutorial and it could easily be adapted for the fancy Google Graphs that this post describes for Dashlets: