This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Click here to see
To view all translated materials including this page, select Country from the country navigator on the bottom of this page.

Customize Metrics Dashboard Layout and Functionality

You can use model metric APIs to customize the Metrics Dashboard. Customizing the dashboard extends your ability to use model metrics to assess that your model and code comply with size, complexity, and readability requirements. This example shows how to perform these Metrics Dashboard customizations:

  • Configure compliance metrics to obtain compliance and issues metric data on your Model Advisor configuration.

  • Customize the dashboard layout by adding custom metrics, removing widgets, and configuring existing widgets.

  • Categorize metric data as compliant, warning, and noncompliant by specifying metric threshold values.

Configure Compliance Metrics

Use the Metrics Dashboard and metric APIs to obtain compliance and issues metric data on your Model Advisor configuration. To set up your Model Advisor configuration, see Organize Checks and Folders Using the Model Advisor Configuration Editor. You can also use an existing check group such as the MISRA checks. After you have set up your Model Advisor configuration, follow these steps to specify the check groups for which you want to obtain compliance and issues metric data:

  1. Open the default configuration:

    metricconfig=slmetric.config.Configuration.open();
  2. Create a cell array consisting of the Check Group IDs that correspond to those check groups. Obtain a Check Group ID by opening the Model Advisor Configuration Editor and selecting the folder that contains the group of checks. The folder contains a Check Group ID parameter.

    values = {'maab', 'hisl_do178', '_SYSTEM_By Task_misra_c'};

    The previous cell array specifies MAAB, High-Integrity, and MISRA check groups. The values maab and hisl_do178 correspond to a subset of all MAAB and High-Integrity System checks. To include all checks, specify the value for the Check Group ID parameter from the Model Advisor Configuration Editor.

  3. To set the configuration, pass the values cell array into the setMetricFamilyParameterValues method. The 'ModelAdvisorStandard' string is a standard string that you must supply to the setMetricFamilyParameterValues method.

    setMetricFamilyParameterValues(metricconfig,'ModelAdvisorStandard', values);
  4. Open the default configuration for the Metrics Dashboard layout.

    dashboardconfig = slmetric.dashboard.Configuration.open();
  5. Obtain the slmetric.dashboard.Layout object from the slmetric.dashboard.Configuration object.

    layout = getDashboardLayout(dashboardconfig);
  6. Obtain widget objects that are in the layout object.

    layoutWidget = getWidgets(layout);
  7. At the highest level, the default Metrics Dashboard contains an slmetric.dashboard.Container object. This object contains an slmetrics.dashboard.Container object and three slmetrics.dashboard.Group objects. The red numbers on the diagram show their order in the layoutWidget array. Obtain the compliance group from the layout.

    complianceGroup = layoutWidget(3);

  8. The compliance group contains two containers. The first container contains the High Integrity and MAAB Compliance and Check Issues widgets. The red numbers in the preceding diagram also show the order of the three widgets that are in the first container. Remove the High Integrity Compliance widget.

    complianceContainers = getWidgets(complianceGroup);
    complianceContainerWidgets = getWidgets(complianceContainers(1));
    complianceContainers(1).removeWidget(complianceContainerWidgets(1)); 
    setMetricIDs(complianceContainerWidgets(1),...
    ({'mathworks.metrics.ModelAdvisorCompliance._SYSTEM_By Task_misra_c'}));
    complianceContainerWidgets(1).Labels={'MISRA'};
    
  9. Create a custom widget for visualizing MISRA check issues metrics.

    misraWidget = complianceContainers(1).addWidget('Custom', 1); 
    misraWidget.Title=('MISRA'); 
    misraWidget.VisualizationType = 'RadialGauge'; 
    misraWidget.setMetricIDs...
    ('mathworks.metrics.ModelAdvisorCheckCompliance._SYSTEM_By Task_misra_c'); 
    misraWidget.setWidths(slmetric.dashboard.Width.Medium);
  10. The bar chart widget visualizes the High Integrity and MAAB check groups. This widget is third in the compliance group. Point this widget to the MISRA and MAAB check groups.

    setMetricIDs(complianceContainerWidgets(3),...
    ({'mathworks.metrics.ModelAdvisorCheckIssues._SYSTEM_By Task_misra_c',...
    'mathworks.metrics.ModelAdvisorCheckIssues.maab'}));
    complianceContainerWidgets(3).Labels = {'MISRA', 'MAAB'};
  11. Save the configuration objects. These commands serialize the API information to XML files.

    save(metricconfig,'FileName','MetricConfig.xml');
    save(dashboardconfig,'Filename','DashboardConfig.xml');
  12. Set the active configurations.

    slmetric.config.setActiveConfiguration(fullfile(pwd, 'MetricConfig.xml'));
    slmetric.dashboard.setActiveConfiguration(fullfile(pwd, 'DashboardConfig.xml'));
  13. For your model, open the Metrics Dashboard.

    metricsdashboard sf_car
  14. Click the All Metrics button and run all metrics. The Metrics Dashboard displays results for the MISRA checks instead of the High Integrity checks.

  15. Close the Metrics Dashboard.

Add a Custom Metric to Dashboard

Create a custom metric that counts nonvirtual blocks. To display this metric on the Metrics Dashboard, specify a widget. Add it to the size group.

  1. Create a custom metric class.

    className = 'nonvirtualblockcount';
    slmetric.metric.createNewMetricClass(className);
    

  2. Create the nonvirtual block count metric by adding this code to the nonvirtualblockcount.m file.

    classdef nonvirtualblockcount < slmetric.metric.Metric
        %nonvirtualblockcount calculates number of nonvirtual blocks per level.
        % BusCreator, BusSelector and BusAssign are treated as nonvirtual.
        properties
            VirtualBlockTypes = {'Demux','From','Goto','Ground', ...
                'GotoTagVisiblity','Mux','SignalSpecification', ...
                'Terminator','Inport'};
        end
        
        methods
        function this = nonvirtualblockcount()
            this.ID = 'nonvirtualblockcount';
            this.Name = 'Nonvirtual Block Count';
            this.Version = 1;
            this.CompileContext = 'None';
            this.Description = 'Algorithm that counts nonvirtual blocks per level.';
            this.AggregatedValueName = 'Nonvirtual Blocks (incl. Descendants)';
            this.ValueName = 'Nonvirtual Blocks';
            this.ComponentScope = [Advisor.component.Types.Model, ...
                Advisor.component.Types.SubSystem];
            this.AggregationMode = slmetric.AggregationMode.Sum;
    	    this.AggregateComponentDetails = true;
            this.ResultChecksumCoverage = true;
            this.SupportsResultDetails = true;
                
        end
    
        function res = algorithm(this, component)
            % create a result object for this component
            res = slmetric.metric.Result();	
    
            % set the component and metric ID
            res.ComponentID = component.ID;
            res.MetricID = this.ID;
            
            % Practice
            D1=slmetric.metric.ResultDetail('identifier 1','Name 1');
            D1.Value=0;
            D1.setGroup('Group1','Group1Name');
            D2=slmetric.metric.ResultDetail('identifier 2','Name 2');
            D2.Value=1;
            D2.setGroup('Group1','Group1Name');
            
            
    
            % use find_system to get all blocks inside this component
            blocks = find_system(getPath(component), ...
                'SearchDepth', 1, ...
                'Type', 'Block');
    
            isNonVirtual = true(size(blocks));
    
            for n=1:length(blocks)
                blockType = get_param(blocks{n}, 'BlockType');
    
                if any(strcmp(this.VirtualBlockTypes, blockType))
                    isNonVirtual(n) = false;
                else
                    switch blockType
                        case 'SubSystem'
                            % Virtual unless the block is conditionally executed
                            % or the Treat as atomic unit check box is selected.
                            if strcmp(get_param(blocks{n}, 'IsSubSystemVirtual'), ...
                                    'on')
                                isNonVirtual(n) = false;
                            end
                        case 'Outport'
                            % Outport: Virtual when the block resides within
                            % SubSystem block (conditional or not), and 
                            % does not reside in the root (top-level) Simulink window.
                            if component.Type ~= Advisor.component.Types.Model
                                isNonVirtual(n) = false;
                            end
                        case 'Selector'
                            % Virtual only when Number of input dimensions 
                            % specifies 1 and Index Option specifies Select 
                            % all, Index vector (dialog), or Starting index (dialog).
                            nod = get_param(blocks{n}, 'NumberOfDimensions');
                            ios = get_param(blocks{n}, 'IndexOptionArray');
    
                            ios_settings = {'Assign all', 'Index vector (dialog)', ...
                                'Starting index (dialog)'};
    
                            if nod == 1 && any(strcmp(ios_settings, ios))
                                isNonVirtual(n) = false;
                            end
                        case 'Trigger'
                            % Virtual when the output port is not present.
                            if strcmp(get_param(blocks{n}, 'ShowOutputPort'), 'off')
                                isNonVirtual(n) = false;
                            end
                        case 'Enable'
                            % Virtual unless connected directly to an Outport block.
                            isNonVirtual(n) = false;
    
                            if strcmp(get_param(blocks{n}, 'ShowOutputPort'), 'on')
                                pc = get_param(blocks{n}, 'PortConnectivity');
    
                                if ~isempty(pc.DstBlock) && ...
                                        strcmp(get_param(pc.DstBlock, 'BlockType'), ...
                                        'Outport')
                                    isNonVirtual(n) = true;
                                end
                            end
                    end
                end
            end
    
            blocks = blocks(isNonVirtual);
    
            res.Value = length(blocks);
        end
        end
    end

  3. Register the new metric in the metric repository.

    [id_metric,err_msg] = slmetric.metric.registerMetric(className);
    
  4. Remove the widget that represents the Simulink block count metric. This widget is the first one in the size group. The size group is the second group in the Metrics Dashboard container.

    sizeGroup = layoutWidget(2); 
    sizeGroupWidgets = sizeGroup.getWidgets(); 
    sizeGroup.removeWidget(sizeGroupWidgets(1));
  5. Add a widget that displays the nonvirtual block count metric. For custom widgets, the default visualization type is single value. If you want to use a different visualization technique, specify a different value for the VisualizationType property.

    newWidget = sizeGroup.addWidget('Custom', 1);
    newWidget.Title=('Nonvirtual Block Count'); 
    newWidget.setMetricIDs('nonvirtualblockcount');
    newWidget.setWidths(slmetric.dashboard.Width.Medium);
    newWidget.setHeight(70);
    
  6. Specify whether there are lines separating the custom widget from other widgets in the group. These commands specify that there is a line to the right of the widget.

    s.top = false;
    s.bottom = false;
    s.left= false;
    s.right= true;
    newWidget.setSeparators([s, s, s, s]);

  7. Save the configuration objects. These commands serialize the API information to XML files.

    save(metricconfig,'FileName','MetricConfig.xml');
    save(dashboardconfig,'Filename','DashboardConfig.xml');
  8. Set the active configurations.

    slmetric.config.setActiveConfiguration(fullfile(pwd, 'MetricConfig.xml'));
    slmetric.dashboard.setActiveConfiguration(fullfile(pwd, 'DashboardConfig.xml'));
  9. For your model, open the Metrics Dashboard.

    metricsdashboard sf_car
  10. Click the All Metrics button and run all metrics. The Metrics Dashboard displays results for the Nonvirtual block count metric instead of the Simulink block count metric.

  11. Close the Metrics Dashboard.

Add Metric Thresholds

For the two new custom metrics, specify metric threshold values. Specifying these values enables you to access the quality of your model by categorizing your metric data as follows:

  • Compliant — Metric data that is in an acceptable range.

  • Warning — Metric data that requires review.

  • Noncompliant — Metric data that requires you to modify your model.

  1. Access the slmetric.config.ThresholdConfiguration object in the slmetric.config.Configuration object metricconfig.

    TC=getThresholdConfigurations(metricconfig);
  2. Add two slmetric.config.Threshold objects to TC. Each slmetric.config.Threshold object contains a default slmetric.config.Classification object that is compliant. Specify the compliant metric ranges.

    T1=addThreshold(TC,'mathworks.metrics.ModelAdvisorCheckIssues._SYSTEM_By Task_misra_c',...
     'AggregatedValue');
    C=getClassifications(T1); 
    C.Range.Start=-inf;
    C.Range.End=0;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
    
    T2=addThreshold(TC,'mathworks.metrics.ModelAdvisorCheckCompliance._SYSTEM_By Task_misra_c',...
     'AggregatedValue'); 
    C=getClassifications(T2); 
    C.Range.Start=1;
    C.Range.End=inf;
    C.Range.IncludeStart=1;
    C.Range.IncludeEnd=0;
    

  3. For each slmetric.config.Threshold object, specify the Warning ranges.

    C=addClassification(T1,'Warning');
    C.Range.Start=0;
    C.Range.End=inf;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
    
    C=addClassification(T2,'Warning');
    C.Range.Start=-inf;
    C.Range.End=1;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=0;
    These commands specify that if the MISRA checks have issues, the model status is warning. If there are no issues, the model status is compliant.

  4. Add a third slmetric.config.Threshold object to TC. Specify compliant, warning, and noncompliant ranges for this slmetric.config.Threshold object.

    T3=addThreshold(TC,'nonvirtualblockcount', 'AggregatedValue');
    C=getClassifications(T3); 
    C.Range.Start=-inf;
    C.Range.End=20;
    C.Range.IncludeStart=1;
    C.Range.IncludeEnd=1;
    
    C=addClassification(T3, 'Warning');
    C.Range.Start=20;
    C.Range.End=30;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
    
    C=addClassification(T3, 'NonCompliant');
    C.Range.Start=30;
    C.Range.End=inf;
    C.Range.IncludeStart=0;
    C.Range.IncludeEnd=1;
     

    These commands specify that the compliant range is less than or equal to 20. The warning range is from 20 up to but not including 30. The noncompliant range is greater than 30.

  5. Save the configuration objects. These commands serialize the API information to XML files.

    save(metricconfig,'FileName','MetricConfig.xml');
    save(dashboardconfig,'Filename','DashboardConfig.xml');
  6. Set the active configurations.

    slmetric.config.setActiveConfiguration(fullfile(pwd, 'MetricConfig.xml'));
    slmetric.dashboard.setActiveConfiguration(fullfile(pwd, 'DashboardConfig.xml'));
  7. For your model, open the Metrics Dashboard.

    metricsdashboard sf_car

    For the MISRA check compliance issues, the gauge displays a warning (yellow) because 76% of the checks pass. Any percentage less than 100% is a warning. The bar chart also displays a warning because the model contains three MISRA check issues. Any number greater than zero is a warning.

    The Nonvirtual Block Count widget is in the compliant range because there are 15 nonvirtual blocks.

  8. To reset the configuration and unregister the metric, execute these commands:

    slmetric.metric.unregisterMetric(className); 
    slmetric.dashboard.setActiveConfiguration(''); 
    slmetric.config.setActiveConfiguration('');

See Also

|

Related Topics