Skip to main content
Velocity Macro — Classification Distribution Counter The nxCountByEnum macro is a core Nextedy Solutions Velocity component that counts work items by enumeration field value. It aggregates work items into buckets based on enum options (such as ASIL levels, Action Priority, severity ratings, or risk levels) and tracks unclassified items. This macro is essential for generating compliance dashboards, risk summary cards, and distribution matrices across TestAuto2 — Automotive Safety Solution.

Overview

nxCountByEnum processes a collection of work items and produces a count distribution across all valid enum values for a specified field. It returns a LinkedHashMap of counts keyed by enum option ID, plus a separate count of unclassified items (null values). Common Use Cases:
  • ASIL distribution summaries (counts of QM, A, B, C, D hazards)
  • Action Priority classification (counts of H, M, L failure modes)
  • Risk level distribution (counts of low, medium, high, critical)
  • Severity/Likelihood bucketing for matrix reports
  • Compliance readiness metrics

Macro Signature

#nxCountByEnum($items, $fieldName)
ParameterTypeRequiredDescription
$itemsListYesCollection of work items to count (e.g., all hazards, all failure modes)
$fieldNameStringYesEnum field name to count by (e.g., "classification", "actionPriority", "severity")

Output Variables

After calling nxCountByEnum(), the following global Velocity variables are set:
VariableTypeDescription
$nxEnumCountsLinkedHashMap<String, Integer>Map of enum option IDs → count. Keys are the enum reference IDs (e.g., "a", "d", "qm"), values are item counts. Ordered by enum definition.
$nxEnumUnclassifiedIntegerCount of items where the field is null or missing (not yet classified)
$nxEnumTotalIntegerTotal count of all items in the input collection

Usage Pattern

## Query all hazards in the project
#set($allHazards = $transaction.workItems().search()
    .query("project.id:$projectId AND type:hazard").list())

## Count by ASIL classification
#nxCountByEnum($allHazards, "classification")

## $nxEnumCounts now contains:
##   "qm" → count of QM hazards
##   "a" → count of ASIL A hazards
##   "b" → count of ASIL B hazards
##   "c" → count of ASIL C hazards
##   "d" → count of ASIL D hazards
## $nxEnumUnclassified contains count of hazards with no classification

## Render summary cards
#foreach($enumValue in $nxEnumCounts.keySet())
    #set($count = $nxEnumCounts.get($enumValue))
    <div class="nx-kpi-card">
        <span class="value">$count</span>
        <span class="label">ASIL $enumValue.toUpperCase()</span>
    </div>
#end

## Show unclassified count
#if($nxEnumUnclassified > 0)
    <div class="nx-alert-warning">
        <strong>$nxEnumUnclassified</strong> hazards pending ASIL classification
    </div>
#end

Real-World Examples

Example 1: ASIL Distribution for ISO 26262 HARA Report

## Get all hazard items from the project
#set($query = "project.id:$projectId AND type:hazard")
#set($allHazards = $transaction.workItems().search().query($query).list())

## Aggregate hazards by ASIL classification
#nxCountByEnum($allHazards, "classification")

## Display ASIL color-coded summary cards
#set($asilColors = {
    "qm": "#808080",
    "a": "#4CAF50",
    "b": "#FF9800",
    "c": "#ff5722",
    "d": "#9C27B0"
})

#foreach($asilLevel in ["qm", "a", "b", "c", "d"])
    #set($count = $nxEnumCounts.getOrDefault($asilLevel, 0))
    #set($color = $asilColors.get($asilLevel))
    #set($label = $asilLevel.toUpperCase())
    
    #if($count > 0 || $asilLevel == "qm")
        <div class="nx-asil-card" style="border-top: 4px solid $color">
            <div class="value">$count</div>
            <div class="label">ASIL $label</div>
        </div>
    #end
#end

## Alert if hazards remain unclassified
#if($nxEnumUnclassified > 0)
    <div class="nx-alert-danger">
        <strong>Incomplete Assessment:</strong> $nxEnumUnclassified hazards 
        lack ASIL classification. All hazards must be assessed per ISO 26262-3.
    </div>
#end

Example 2: Action Priority Distribution for DFMEA Summary

## Get all failure modes from System DFMEA documents
#set($query = "project.id:$projectId AND type:failureMode")
#set($allFailureModes = $transaction.workItems().search().query($query).list())

## Count by post-mitigation Action Priority
#nxCountByEnum($allFailureModes, "postmitigationAP")

## Extract AP bucket counts
#set($apHigh = $nxEnumCounts.getOrDefault("h", 0))
#set($apMed = $nxEnumCounts.getOrDefault("m", 0))
#set($apLow = $nxEnumCounts.getOrDefault("l", 0))
#set($apUnassigned = $nxEnumUnclassified)

## Determine risk status
#if($apHigh > 0)
    <div class="nx-alert-danger">
        <strong>Unacceptable Risk:</strong> $apHigh failure modes with 
        High priority require immediate mitigation or acceptance.
    </div>
#elseif($apMed > 0)
    <div class="nx-alert-warning">
        <strong>Medium Risk:</strong> $apMed failure modes with Medium priority 
        require planned corrective actions.
    </div>
#else
    <div class="nx-alert-success">
        All failure modes have acceptable post-mitigation risk.
    </div>
#end

## Render distribution cards
<div class="nx-ap-grid">
    <div class="nx-ap-card high">
        <span class="value">$apHigh</span>
        <span class="label">High Priority</span>
    </div>
    <div class="nx-ap-card med">
        <span class="value">$apMed</span>
        <span class="label">Medium Priority</span>
    </div>
    <div class="nx-ap-card low">
        <span class="value">$apLow</span>
        <span class="label">Low Priority</span>
    </div>
    <div class="nx-ap-card na">
        <span class="value">$apUnassigned</span>
        <span class="label">Unassigned</span>
    </div>
</div>

Example 3: Severity Level Distribution for Risk Matrix

## Get all hazards for HAZID analysis
#set($allHazards = $transaction.workItems().search()
    .query("project.id:$projectId AND type:hazard").list())

## Count by initial severity
#nxCountByEnum($allHazards, "severity")

## Build severity distribution table
<table class="nx-severity-table">
    <tr>
        <th>Severity Level</th>
        <th>Count</th>
        <th>Percentage</th>
    </tr>
    #foreach($severity in ["s0", "s1", "s2", "s3"])
        #set($count = $nxEnumCounts.getOrDefault($severity, 0))
        #set($percent = 0)
        #if($nxEnumTotal > 0)
            #set($percent = $mathtool.round($count * 100.0 / $nxEnumTotal))
        #end
        <tr>
            <td>Severity $severity.toUpperCase()</td>
            <td>$count</td>
            <td>${percent}%</td>
        </tr>
    #end
</table>

Implementation Notes

Enum Field Resolution

The macro handles enum field access via Polarion’s API:
$item.fields().get($fieldName).get().getReference().id()
The returned ID is the enum option’s reference key (e.g., "qm", "a", "h", "medium"). Keys are case-insensitive when matching against enum definitions.

Null/Unclassified Handling

Items with:
  • No value set for the field (null)
  • Empty field reference
  • Field not present in work item type definition
…are counted separately in $nxEnumUnclassified. This distinction allows dashboards to highlight incomplete assessments.

LinkedHashMap Ordering

The returned $nxEnumCounts map preserves enum definition order from Polarion’s enumeration configuration. For example, ASIL enums are typically ordered [QM, A, B, C, D], so iteration yields counts in that sequence.

Performance Considerations

For projects with >1000 work items of a type, consider filtering the query before passing to nxCountByEnum:
## Instead of querying all failure modes:
#set($query = "project.id:$projectId AND type:failureMode")

## Filter by module (document) to reduce iteration:
#set($query = "project.id:$projectId AND type:failureMode 
               AND module.id:riskSpecification/DFMEA_System")
#set($filtered = $transaction.workItems().search().query($query).list())
#nxCountByEnum($filtered, "postmitigationAP")

Scope Limitations

The macro cannot be called inside a #foreach loop with #set statements due to Velocity scoping. If you need to count multiple fields in sequence, call the macro once per field outside any loop context:
## Correct: calls outside loop
#nxCountByEnum($items, "field1")
#set($field1Counts = $nxEnumCounts)

#nxCountByEnum($items, "field2")
#set($field2Counts = $nxEnumCounts)

## Incorrect: macro call inside loop with #set
#foreach($item in $items)
    #nxCountByEnum([$item], "field")  ## ❌ Scope issues
#end
MacroPurposeLink
nxAPBucketsSpecialized enum counter for Action Priority (H/M/L)nxAPBuckets
nxLinkCoverageCount items WITH links to target types (traceability)nxLinkCoverage
nxKpiCardRender count values as styled KPI cardsnxKpiCard
nxCoverageBarRender percentage progress bar with traffic-light coloringnxCoverageBar

Common Field Names by Standard

ISO 26262 (Functional Safety):
  • classification — ASIL levels (qm, a, b, c, d)
  • severity — S0-S3 (s0, s1, s2, s3)
  • exposure — E0-E4 (e0, e1, e2, e3, e4)
  • controllability — C0-C3 (c0, c1, c2, c3)
AIAG-VDA FMEA:
  • premitigationAP — Pre-mitigation action priority (h, m, l)
  • postmitigationAP — Post-mitigation action priority (h, m, l)
  • severity — Severity rating 1-10
  • occurrence — Occurrence rating 1-10
  • detection — Detection rating 1-10
ISO 14971 (Risk Management):
  • risk — Risk level (low, medium, high, critical)
  • likelihood — L1-L5
  • harm — Harm severity

Troubleshooting

IssueCauseSolution
$nxEnumCounts is emptyField name incorrect or field not on work itemsVerify field exists via #get($item.fields().get($fieldName))
All items counted as unclassifiedEnum field returns null for all itemsCheck Polarion field configuration; ensure enum field is set on items
LinkedHashMap iteration shows wrong orderUsing custom sort instead of Polarion definitionRemove custom sorting; preserve iteration order from macro return
Counts don’t add up to totalUnclassified items not included in $nxEnumCountsRemember: $nxEnumTotal = $nxEnumCounts.values().sum() + $nxEnumUnclassified

Macro Definition Location

Source: .polarion/pages/scripts/velocity/nextedy_solutions.vm The nxCountByEnum macro is part of the Nextedy Solutions shared Velocity library and is automatically imported by all TestAuto2 — Automotive Safety Solution dashboards and reports. For custom dashboard development, ensure the library is imported:
#parse("nextedy_solutions.vm")