Safety Outlier Explorer: test evidence

Requirement-traced qualification evidence for the safety.viz outlier-explorer module.

Scope
29 coverage rows69 distinct requirement IDs
Tests executed
235 automated checks37 browser ยท 198 unit
Result
pass all passing8 evidence screenshots
Generated
2026-08-15 09:05 UTC
Environment
linux 6.17.0-1022-azure ยท node v22.23.2 ยท playwright 1.61.1 ยท chromium 149.0.7827.55

Scope & approach

Traceability for the outlier-explorer module (a Chart.js reimplementation of RhoInc/safety-outlier-explorer matching its behavior, under #24), per the convention in CONTRIBUTING.md. Two requirement-ID schemes appear:

Each table row traces one requirement to the automated test(s) that evidence it: the Requirement column shows the reviewed requirement text and its ID, the source-matrix rows link back to the specification, the issue column links the implementing work, and the result column shows the recorded outcome of every matching test from the committed evidence.json with its captured screenshots. Browser evidence is captured at fixed conditions (1280ร—800, device scale 1) on the canonical Linux CI environment.

Browser evidence (Playwright โ€” tests/e2e/outlier-explorer.spec.js)

17 requirement rows ยท 17 tests

RequirementSource matrix rowsIssueTests & evidence
SOE-CTRL-001

SOE-FUNC-001 This drop-down menu is used to filter the lab variable that is displayed in the chart. The default measure is set to the first variable in the data set, but the default value can be adjusted to any measure upon the project team's request. Users can select any pre-defined measure in this filter. Selecting a measure will display the data points associated with that measure and will display the visits that the measure is collected at underneath the chart.

SOE-FUNC-002 The chart can be configured to have any number of data filters. Each specified filter has a drop-down menu that is used to filter the visit data that is displayed in the chart.

SOE-FUNC-004 The chart contains a toggle that controls the display of the x-axis. Users can view the x-axis data by study day, visit, or visit number. The x-axis displays the data point at which the measure data is collected and manipulating it changes the scale at which the measure data is plotted. Study day, visit, or visit number can be chosen for a given measure, but the chart default is to show the x-axis by study day.

SOE-FUNC-005 Users are able to adjust the lower limit of the y-axis by manipulating the input within the Lower Limit box. Users are able to adjust the upper limit of the y-axis by manipulating the input within the Upper Limit box. Each limit box has up and down arrows to adjust the value of the box by 1. Users can select an arrow to change the input or delete the current value in the box and type in a new value. When typing in a value, users must click outside of the box to apply the changes. When a user manipulates a y-axis limit, the y-axis on the chart below the controls will reflect the change.

SOE-FUNC-006 Users can change the upper and lower y-axis limits back to the default values for a measure by selecting the "Reset Limits" button. Pressing the button will erase the current values in the upper and lower limit boxes and replace them with defaults. The chart below will also reflect the changes and will show the default axes.

SOE-FUNC-007 Users can opt to change the method for the normal ranges to the following options: None, LLN-ULN, Standard Deviation, and Quantiles. The default for the normal range controls is set to "LLN-ULN", which is the upper and lower normal range specified in the data. Users may select "None", which will remove the green shading around the normal ranges and will remove the inlier count to the left of the charts. Users may also select "Standard Deviation", which will prompt the user to enter the number of standard deviations they would like to set as the normal range. Altering the default value will change the upper and lower normal range bands in the chart and will change the inlier count to the left of the chart. Users may also select "Quantiles", which prompts the user to enter an upper and lower quantile to set as the normal ranges. Altering the upper quantile will change the upper normal range band in the chart and altering the lower quantile will change the lower normal range band in the chart. Changing the normal ranges may change the number of inliers and the inlier count to the left of the chart will update based on your selections.

SOE-FUNC-001, SOE-FUNC-002, SOE-FUNC-004, SOE-FUNC-005, SOE-FUNC-006, SOE-FUNC-007#24
  • pass SOE-FUNC-001/SOE-FUNC-002/SOE-FUNC-004/SOE-FUNC-005/SOE-FUNC-006/SOE-FUNC-007: renders the full control panel (#24)
Evidence screenshot SOE-FUNC-001-control-panel.pngEvidence screenshot SOE-FUNC-007-normal-range-band.png
SOE-COUNT-003

SOE-FUNC-003 Displayed under the header, this statement provides the total number of participants in the data set in integers as well as the percentage of participants shown to one decimal place. In the default view, all participant data is included in the chart, or 100%, unless the project team requests otherwise. When filters are used, the data shown in the histogram is manipulated and the number of participant records shown at the top of the page may increase or decrease, depending on the variable selected.

SOE-REG-001 Confirm that the number and percentage of participants is captured above the chart

SOE-REG-002 Confirm that selecting the Measure filter changes the distribution of observations

SOE-FUNC-003, SOE-REG-001, SOE-REG-002#24
  • pass SOE-FUNC-003/SOE-REG-001/SOE-REG-002: participant note reports N and % and updates on filter (#24)
SOE-DATA-037

SOE-REG-037 Confirm that the right side of the webpage between the controls and the chart a note should appear that details how many records with missing and/or non-numeric results were removed.

SOE-REG-038 Confirm that the test dataset already contains missing records. To test non-numeric records edit ADBDS.csv by adding non-numeric values to the STRESN column.

SOE-REG-037, SOE-REG-038#24
  • pass SOE-REG-037/SOE-REG-038: missing and non-numeric results are dropped with a reported count and note (#24)
Evidence screenshot SOE-REG-037-invalid-data-note.png
SOE-SELECT-010

SOE-FUNC-010 Clicking a data point will open a listing of small multiples below the chart that contains a detailed listing of all of the participant's records. This linked table contains small charts for each measure captured in the data set as well as the participant's subject ID, age, sex, and race. When the listing appears, the data points selected will appear in a continuous gray line inside of the chart. When a user clicks outside of the selected data point, the gray line disappears along with the detailed listing.

SOE-FUNC-012 Display the raw data records, including the subject identifier, age, race, sex, and small data renderings of each measure captured in the data set

SOE-FUNC-013 Create a gray line to connect the selected data points

SOE-REG-013 Confirm that clicking on a data point applies a dark highlight to all of the participant's data points

SOE-REG-014 Confirm that clicking on a data point opens a detailed listing of a participant's data beneath the chart

SOE-REG-016 Confirm that all marks (points, lines) associated with that participant should highlight.

SOE-REG-022 Confirm that the listing contains subject-level demographic data (Age, Sex, and Race appear by default, can add other Participant Details if wanted)

SOE-REG-023 Confirm that the listing contains subject-level information about measures and and visits

SOE-FUNC-010, SOE-FUNC-012, SOE-FUNC-013, SOE-REG-013, SOE-REG-014, SOE-REG-016, SOE-REG-022, SOE-REG-023#24
  • pass SOE-FUNC-010/SOE-FUNC-012/SOE-REG-013/SOE-REG-014/SOE-REG-016: clicking a point highlights the participant and opens a linked listing (#24)
Evidence screenshot SOE-FUNC-010-participant-detail.png
SOE-SELECT-020

SOE-FUNC-010 Clicking a data point will open a listing of small multiples below the chart that contains a detailed listing of all of the participant's records. This linked table contains small charts for each measure captured in the data set as well as the participant's subject ID, age, sex, and race. When the listing appears, the data points selected will appear in a continuous gray line inside of the chart. When a user clicks outside of the selected data point, the gray line disappears along with the detailed listing.

SOE-REG-020 Confirm that with an overlapping point highlighted, changing any control should remove the note but maintain the highlighting of the selected participant.

SOE-FUNC-010, SOE-REG-020#24
  • pass SOE-FUNC-010/SOE-REG-020: clicking the background clears the selection and listing (#24)
Evidence screenshot SOE-FUNC-010-participant-detail.png
SOE-NORM-007

SOE-FUNC-007 Users can opt to change the method for the normal ranges to the following options: None, LLN-ULN, Standard Deviation, and Quantiles. The default for the normal range controls is set to "LLN-ULN", which is the upper and lower normal range specified in the data. Users may select "None", which will remove the green shading around the normal ranges and will remove the inlier count to the left of the charts. Users may also select "Standard Deviation", which will prompt the user to enter the number of standard deviations they would like to set as the normal range. Altering the default value will change the upper and lower normal range bands in the chart and will change the inlier count to the left of the chart. Users may also select "Quantiles", which prompts the user to enter an upper and lower quantile to set as the normal ranges. Altering the upper quantile will change the upper normal range band in the chart and altering the lower quantile will change the lower normal range band in the chart. Changing the normal ranges may change the number of inliers and the inlier count to the left of the chart will update based on your selections.

SOE-REG-025 Confirm that a dropdown labeled Normal range method appears in the controls section with four options: None, LLN-ULN, Standard Deviation, and Quantiles.

SOE-REG-026 Confirm that selecting Standard Deviation displays a text input labeled Number of standard deviations and defaults to 1.96.

SOE-REG-027 Confirm that selecting Quantiles displays two text inputs, one for the lower quantile and one for the upper quantile, labeled Lower quantile and Upper quantile respectively, that default to .05 and .95.

SOE-FUNC-007, SOE-REG-025, SOE-REG-026, SOE-REG-027#24
  • pass SOE-FUNC-007/SOE-REG-025/SOE-REG-026/SOE-REG-027: normal-range methods drive the band and conditional inputs (#24)
Evidence screenshot SOE-FUNC-007-normal-range-band.png
SOE-YAXIS-005

SOE-FUNC-005 Users are able to adjust the lower limit of the y-axis by manipulating the input within the Lower Limit box. Users are able to adjust the upper limit of the y-axis by manipulating the input within the Upper Limit box. Each limit box has up and down arrows to adjust the value of the box by 1. Users can select an arrow to change the input or delete the current value in the box and type in a new value. When typing in a value, users must click outside of the box to apply the changes. When a user manipulates a y-axis limit, the y-axis on the chart below the controls will reflect the change.

SOE-FUNC-006 Users can change the upper and lower y-axis limits back to the default values for a measure by selecting the "Reset Limits" button. Pressing the button will erase the current values in the upper and lower limit boxes and replace them with defaults. The chart below will also reflect the changes and will show the default axes.

SOE-REG-004 Confirm that entering a value into the Y-axis Lower Limit box and clicking outside of the box updates the lower limit of the y-axis

SOE-REG-005 Confirm that entering a value into the Upper Limit box and clicking outside of the box updates the upper limit of the y-axis

SOE-REG-006 Confirm that selecting the y-axis reset button returns the chart to the default values for that measure

SOE-FUNC-005, SOE-FUNC-006, SOE-REG-004, SOE-REG-005, SOE-REG-006#24
  • pass SOE-FUNC-005/SOE-FUNC-006/SOE-REG-004/SOE-REG-005/SOE-REG-006: y-axis limits redraw, normalize, and reset (#24)
SOE-GROUP-049

SOE-REG-048 Add the following snippet: groups: [{value_col: 'ARM',label: 'Treatment Group'},{value_col: 'SEX',label: 'Sex'}] and verify that the chart now has a "Group By" control.

SOE-REG-049 Confirm that the points and lines are colored by the categories of that group, and that a legend appears at the bottom corresponding to the current grouping and colors.

SOE-REG-050 Confirm that when the 'Group by' Control is changed, the chart and legend reflects the new grouping.

SOE-REG-048, SOE-REG-049, SOE-REG-050#24
  • pass SOE-REG-048/SOE-REG-049/SOE-REG-050: grouping colors the marks and renders a legend (#24)
Evidence screenshot SOE-REG-049-color-by-group.png
SOE-XAXIS-004

SOE-FUNC-004 The chart contains a toggle that controls the display of the x-axis. Users can view the x-axis data by study day, visit, or visit number. The x-axis displays the data point at which the measure data is collected and manipulating it changes the scale at which the measure data is plotted. Study day, visit, or visit number can be chosen for a given measure, but the chart default is to show the x-axis by study day.

SOE-REG-003 Confirm that the x-axis filter changes the x-axis to the selected variable

SOE-FUNC-004, SOE-REG-003#24
  • pass SOE-FUNC-004/SOE-REG-003: the x-axis toggle switches between the visit and study-day axes (#24)
SOE-TIP-011

SOE-REG-011 Confirm that hovering on a data point displays tooltips for the data point with Subject, value, and visit

SOE-REG-011#24
  • pass SOE-REG-011: point tooltips list participant, result, and time (#24)
SOE-EVENT-003

SOE-API-003 The custom participantsSelected event is dispatched to the overall chart wrapper (chart.wrap) whenever the details for a given participant are viewed (or cleared) by clicking on a line or point in the chart. The event has a custom data property holding an array with the selected ID when a new participant is selected (["123-456-7"]) or an empty array when participant details are cleared.

SOE-API-003#24
  • pass SOE-API-003: participantsSelected fires on select and clear (#24)
SOE-FILT-051

SOE-REG-051 Add the following snippet: "filters": [{"value_col": "ARM","label": "Treatment Group","start": "Placebo"}] and verify a filter appears with the name 'Treatment Group' that subsets the data appropriately when used.

SOE-REG-052 Verify that the dropdown for the the filter does not have an "All" option

SOE-REG-053 Verify that on renderering, the chart is already filtered by 'Placebo' and that this is reflected by the drop down

SOE-REG-051, SOE-REG-052, SOE-REG-053#24
  • pass SOE-REG-051/SOE-REG-052/SOE-REG-053: a filter with a start value initializes filtered and offers no All option (#24)
SOE-API-001

SOE-API-001 a factory to create a custom Webcharts chart object

โ€” (see legacy-API note)#24
  • pass SOE-API-001: lifecycle API supports init, setData, setSettings, render, resize, and destroy (#24)
PPRF-OE-001/PPRF-OE-002
PPRF-OE-001, PPRF-OE-002 (participant-profile matrix)#99
  • pass PPRF-OE-001/PPRF-OE-002: clicking a point opens the railed profile ALONGSIDE the linked listing (#99)
Evidence screenshot PPRF-OE-002-docked-profile.pngEvidence screenshot PPRF-OE-002-railed-profile.png
PPRF-OE-003
PPRF-OE-003 (participant-profile matrix)#99
  • pass PPRF-OE-003: background click and control changes empty the rail (#99)
PPRF-OE-002 (rail Clear)
PPRF-OE-002 (participant-profile matrix)#99
  • pass PPRF-OE-002: the rail Clear affordance routes through the host clear path (#99)
Evidence screenshot PPRF-OE-002-docked-profile.pngEvidence screenshot PPRF-OE-002-railed-profile.png
SOE-AXIS-001/002/003

SOE-AXIS-001 On load and after every render, each Y-axis Limits input displays the limit currently in force for the selected measure โ€” the padded default domain of the filtered results (SOE-REG-034) by default, or the user's override โ€” formatted to three significant figures of the axis range. Neither box is ever blank.

SOE-AXIS-002 Displaying a limit does not pin it. A limit the user has not edited remains automatic โ€” it is re-derived from the data on every render, so changing the measure, the filters, or the y-axis scale updates the value shown โ€” while an edited limit persists as an override until it is reset. The distinction is held in state (an override slot separate from the recorded domain), not inferred from an empty input.

SOE-AXIS-003 The Reset Limits control clears both y-axis limits overrides and repopulates both inputs with the derived limits, so there is always a way back to automatic now that an empty box no longer means it.

SOE-AXIS-001, SOE-AXIS-002, SOE-AXIS-003#85
  • pass SOE-AXIS-001/SOE-AXIS-002/SOE-AXIS-003: y-limit inputs load pre-filled with the drawn axis, follow the measure, and Reset restores them (#85)
Evidence screenshot SOE-AXIS-001-y-limits-prefilled.png

Unit evidence (Vitest โ€” tests/unit/outlier-explorer/)

12 requirement rows ยท 34 tests

RequirementSource matrix rowsIssueTests & evidence
SOE-CFG-004/005/006/013/014

SOE-CFG-004 an array of filter variables and associated metadata

SOE-CFG-005 an array of ID-level variables and associated metadata

SOE-CFG-006 added in v2.4. Takes an array of col/label objects and adds those values to the end of the standard point tooltips. The following would add Date to the tooltip: {tooltip_cols: [{label:"Date",value_col:"DT"}]};

SOE-CFG-013 an object that defines the line color, thickness, and opacity

SOE-CFG-014 an object that defines the point color, radius, and opacity and its outline color, thickness, and opacity

SOE-CFG-004, SOE-CFG-005, SOE-CFG-006, SOE-CFG-013, SOE-CFG-014#24

configure.test.js

  • pass outlier-explorer configure SOE-CFG-004: filter specs normalize strings and objects and preserve a start value (#24)
  • pass outlier-explorer configure SOE-CFG-005: details default to time, id, result, normal limits, and unit when unset (#24)
  • pass outlier-explorer configure SOE-CFG-006/013/014: tooltip_cols normalize and mark attributes merge over defaults (#24)
  • pass outlier-explorer getPlugins SOE-CFG-006/SOE-REG-012: pointTooltip appends configured tooltip_cols when present (#24)
SOE-CFG-007/008/009 (defaults)

SOE-CFG-007 the number of standard deviations from the mean with which to define the normal range

SOE-CFG-008 this quantile defines the lower bound of the normal range

SOE-CFG-009 this quantile defines the upper bound of the normal range

SOE-CFG-007, SOE-CFG-008, SOE-CFG-009#24

configure.test.js

  • pass outlier-explorer configure SOE-FUNC-007/SOE-CFG-007..009: normal-range method defaults to LLN-ULN with sd and quantile defaults (#24)
  • pass outlier-explorer structureData SOE-FUNC-007/SOE-CFG-007: Standard Deviation normal range uses mean +/- k*sd (#24)
  • pass outlier-explorer structureData SOE-FUNC-007/SOE-CFG-008: Quantiles normal range uses the configured quantiles (#24)
Evidence screenshot SOE-FUNC-007-normal-range-band.png
SOE-FUNC-004/SOE-REG-048

SOE-FUNC-004 The chart contains a toggle that controls the display of the x-axis. Users can view the x-axis data by study day, visit, or visit number. The x-axis displays the data point at which the measure data is collected and manipulating it changes the scale at which the measure data is plotted. Study day, visit, or visit number can be chosen for a given measure, but the chart default is to show the x-axis by study day.

SOE-REG-048 Add the following snippet: groups: [{value_col: 'ARM',label: 'Treatment Group'},{value_col: 'SEX',label: 'Sex'}] and verify that the chart now has a "Group By" control.

SOE-FUNC-004, SOE-REG-048#24

configure.test.js

  • pass outlier-explorer configure SOE-FUNC-004: time_cols default to a derived Measurement axis and normalize ordinal specs (#24)
  • pass outlier-explorer configure SOE-REG-048: groups always offer a leading None option and honor group_by (#24)
  • pass outlier-explorer structureData SOE-FUNC-004: assignSequence derives a 1-based per-participant measurement index (#24)
SOE-REG-037/038, SOE-REG-029/031

SOE-REG-037 Confirm that the right side of the webpage between the controls and the chart a note should appear that details how many records with missing and/or non-numeric results were removed.

SOE-REG-038 Confirm that the test dataset already contains missing records. To test non-numeric records edit ADBDS.csv by adding non-numeric values to the STRESN column.

SOE-REG-029 Confirm that a unit variable is appended to each measure in the Measure dropdown.

SOE-REG-031 Confirm that there are values displayed next to each measure under the specified unit variable in the data set.

SOE-REG-037, SOE-REG-038, SOE-REG-029, SOE-REG-031#24

structureData.test.js

  • pass outlier-explorer structureData SOE-REG-029/SOE-REG-031: measureLabel appends the unit when present (#24)
  • pass outlier-explorer structureData SOE-REG-037/SOE-REG-038: cleanData drops missing and non-numeric results with a count (#24)
Evidence screenshot SOE-REG-037-invalid-data-note.png
SOE-FUNC-004/SOE-REG-028 (axis)

SOE-FUNC-004 The chart contains a toggle that controls the display of the x-axis. Users can view the x-axis data by study day, visit, or visit number. The x-axis displays the data point at which the measure data is collected and manipulating it changes the scale at which the measure data is plotted. Study day, visit, or visit number can be chosen for a given measure, but the chart default is to show the x-axis by study day.

SOE-REG-028 Confirm that the x-axis tick labels change rotation angles depending on the x-axis control variable.

SOE-FUNC-004, SOE-REG-028#24

structureData.test.js

  • pass outlier-explorer configure SOE-FUNC-004: time_cols default to a derived Measurement axis and normalize ordinal specs (#24)
  • pass outlier-explorer getScales SOE-REG-028: buildXScale rotates ordinal visit ticks and keeps linear ticks upright (#24)
  • pass outlier-explorer structureData SOE-FUNC-004: assignSequence derives a 1-based per-participant measurement index (#24)
  • pass outlier-explorer structureData SOE-REG-028: orderedCategories sorts ordinal visits by their order column (#24)
SOE-FUNC-007/SOE-CFG-007/008 (stats)

SOE-FUNC-007 Users can opt to change the method for the normal ranges to the following options: None, LLN-ULN, Standard Deviation, and Quantiles. The default for the normal range controls is set to "LLN-ULN", which is the upper and lower normal range specified in the data. Users may select "None", which will remove the green shading around the normal ranges and will remove the inlier count to the left of the charts. Users may also select "Standard Deviation", which will prompt the user to enter the number of standard deviations they would like to set as the normal range. Altering the default value will change the upper and lower normal range bands in the chart and will change the inlier count to the left of the chart. Users may also select "Quantiles", which prompts the user to enter an upper and lower quantile to set as the normal ranges. Altering the upper quantile will change the upper normal range band in the chart and altering the lower quantile will change the lower normal range band in the chart. Changing the normal ranges may change the number of inliers and the inlier count to the left of the chart will update based on your selections.

SOE-CFG-007 the number of standard deviations from the mean with which to define the normal range

SOE-CFG-008 this quantile defines the lower bound of the normal range

SOE-REG-025 Confirm that a dropdown labeled Normal range method appears in the controls section with four options: None, LLN-ULN, Standard Deviation, and Quantiles.

SOE-FUNC-007, SOE-CFG-007, SOE-CFG-008, SOE-REG-025#24

structureData.test.js

  • pass outlier-explorer configure SOE-FUNC-007/SOE-CFG-007..009: normal-range method defaults to LLN-ULN with sd and quantile defaults (#24)
  • pass outlier-explorer structureData SOE-FUNC-007: countInliers counts observations inside the band (#24)
  • pass outlier-explorer structureData SOE-FUNC-007/SOE-CFG-007: Standard Deviation normal range uses mean +/- k*sd (#24)
  • pass outlier-explorer structureData SOE-FUNC-007/SOE-CFG-008: Quantiles normal range uses the configured quantiles (#24)
  • pass outlier-explorer structureData SOE-FUNC-007/SOE-REG-025: LLN-ULN normal range is the median of the limit columns; None is null (#24)
Evidence screenshot SOE-FUNC-007-normal-range-band.png
SOE-FUNC-005/006, SOE-REG-004/033

SOE-FUNC-005 Users are able to adjust the lower limit of the y-axis by manipulating the input within the Lower Limit box. Users are able to adjust the upper limit of the y-axis by manipulating the input within the Upper Limit box. Each limit box has up and down arrows to adjust the value of the box by 1. Users can select an arrow to change the input or delete the current value in the box and type in a new value. When typing in a value, users must click outside of the box to apply the changes. When a user manipulates a y-axis limit, the y-axis on the chart below the controls will reflect the change.

SOE-FUNC-006 Users can change the upper and lower y-axis limits back to the default values for a measure by selecting the "Reset Limits" button. Pressing the button will erase the current values in the upper and lower limit boxes and replace them with defaults. The chart below will also reflect the changes and will show the default axes.

SOE-REG-004 Confirm that entering a value into the Y-axis Lower Limit box and clicking outside of the box updates the lower limit of the y-axis

SOE-REG-033 Confirm that when clicking the arrows in the y-axis limit inputs, the limits should increment by a reasonable factor of the y-axis range, or roughly 1/15 of the range. For example, if the range is 150 the increment should be 10 and if the range is 1.5 the increment should be .1.

SOE-FUNC-005, SOE-FUNC-006, SOE-REG-004, SOE-REG-033#24

getScales.test.js

  • pass outlier-explorer getScales SOE-FUNC-005: resolveYDomain honors user lower/upper and falls back to default (#24)
  • pass outlier-explorer getScales SOE-FUNC-005/SOE-REG-004: normalizeYDomain swaps inverted limits in place (#24)
  • pass outlier-explorer getScales SOE-FUNC-005/SOE-REG-034: default y-domain pads the measure extent so points are not clipped (#24)
  • pass outlier-explorer getScales SOE-REG-033: axisStep snaps ~1/15 of the range to a power of ten (#24)
SOE-REG-028 (x-scale)

SOE-REG-028 Confirm that the x-axis tick labels change rotation angles depending on the x-axis control variable.

SOE-REG-028#24

getScales.test.js

  • pass outlier-explorer getScales SOE-REG-028: buildXScale rotates ordinal visit ticks and keeps linear ticks upright (#24)
  • pass outlier-explorer structureData SOE-REG-028: orderedCategories sorts ordinal visits by their order column (#24)
SOE-REG-011/049, SOE-CFG-006

SOE-REG-011 Confirm that hovering on a data point displays tooltips for the data point with Subject, value, and visit

SOE-REG-049 Confirm that the points and lines are colored by the categories of that group, and that a legend appears at the bottom corresponding to the current grouping and colors.

SOE-CFG-006 added in v2.4. Takes an array of col/label objects and adds those values to the end of the standard point tooltips. The following would add Date to the tooltip: {tooltip_cols: [{label:"Date",value_col:"DT"}]};

SOE-REG-011, SOE-REG-049, SOE-CFG-006#24

getPlugins.test.js

  • pass outlier-explorer configure SOE-CFG-006/013/014: tooltip_cols normalize and mark attributes merge over defaults (#24)
  • pass outlier-explorer getPlugins SOE-CFG-006/SOE-REG-012: pointTooltip appends configured tooltip_cols when present (#24)
  • pass outlier-explorer getPlugins SOE-REG-011: pointTooltip lists participant, result, and time (#24)
  • pass outlier-explorer getPlugins SOE-REG-049: groupColorScale maps distinct group values to palette colors and cycles (#24)
Evidence screenshot SOE-REG-049-color-by-group.png
SOE-DATA-001/003 (schema)

SOE-DATA-001 The Safety Outlier Explorer is initialized with JSON data files that match the format created by d3.csv(). The chart expects an ADaM-esque data structure by default but can be customized to work with any dataset that contains one row per participant per time point per measure and includes the required columns specified below.

SOE-DATA-003 No customization is needed to initialize a chart when the data object contains all default variables above. Just pass an empty object ({}) for settings and initialize the chart like so: safetyOutlierExplorer('body', {}).init(data).

SOE-DATA-001, SOE-DATA-003#24

checkInputs.test.js

  • pass outlier-explorer checkInputs SOE-DATA-001: missing required measure/value columns throw a naming error (#24)
  • pass outlier-explorer checkInputs SOE-DATA-001: valid long-format data with the required columns passes (#24)
  • pass outlier-explorer checkInputs SOE-DATA-003: an empty settings object initializes from the defaults (#24)
SOE-API-001 (module export)

SOE-API-001 a factory to create a custom Webcharts chart object

โ€”#24

export.test.js

  • pass outlier-explorer module export SOE-API-001: the public collection exposes the outlierExplorer factory (#24)
SOE-AXIS-001/002/003/004

SOE-AXIS-001 On load and after every render, each Y-axis Limits input displays the limit currently in force for the selected measure โ€” the padded default domain of the filtered results (SOE-REG-034) by default, or the user's override โ€” formatted to three significant figures of the axis range. Neither box is ever blank.

SOE-AXIS-002 Displaying a limit does not pin it. A limit the user has not edited remains automatic โ€” it is re-derived from the data on every render, so changing the measure, the filters, or the y-axis scale updates the value shown โ€” while an edited limit persists as an override until it is reset. The distinction is held in state (an override slot separate from the recorded domain), not inferred from an empty input.

SOE-AXIS-003 The Reset Limits control clears both y-axis limits overrides and repopulates both inputs with the derived limits, so there is always a way back to automatic now that an empty box no longer means it.

SOE-AXIS-004 Pre-filling must not let an invalid domain reach the chart: a limit typed across the other limit as currently displayed is swapped rather than inverted, an empty or non-numeric entry returns that limit to automatic, and a log-scale domain stays positive.

SOE-AXIS-001, SOE-AXIS-002, SOE-AXIS-003, SOE-AXIS-004#85

axis-limits.test.js

  • pass outlier-explorer axis-limit prefill (SOE-AXIS-001) SOE-AXIS-001: displaying a limit does not pin it โ€” the overrides stay null until edited (#85)
  • pass outlier-explorer axis-limit prefill (SOE-AXIS-001) SOE-AXIS-001: the Y-axis limit inputs load pre-filled with the padded domain the chart drew (#85)
  • pass outlier-explorer limit guardrails with prefilled inputs (SOE-AXIS-004) SOE-AXIS-004: a lower limit typed above the prefilled upper limit is swapped, never inverted (#85)
  • pass outlier-explorer limit guardrails with prefilled inputs (SOE-AXIS-004) SOE-AXIS-004: clearing a prefilled input returns that limit to auto and the box refills (#85)
  • pass outlier-explorer Reset Limits (SOE-AXIS-003) SOE-AXIS-003: Reset Limits clears the overrides and repopulates both inputs with the derived domain (#85)
  • pass outlier-explorer unedited limits stay automatic (SOE-AXIS-002) SOE-AXIS-002: an edited limit survives a filter change and stays an override (#85)
  • pass outlier-explorer unedited limits stay automatic (SOE-AXIS-002) SOE-AXIS-002: an unedited limit re-derives on a measure change and the input follows (#85)
  • pass outlier-explorer unedited limits stay automatic (SOE-AXIS-002) SOE-AXIS-002: an unedited limit re-derives when a filter narrows the cohort (#85)
Evidence screenshot SOE-AXIS-001-y-limits-prefilled.png

Visual evidence

Every screenshot below is a committed baseline: the same PNG is the visual-regression baseline the browser suite asserts against and the evidence artifact shown here. Click any capture for the full-resolution image.

Source-matrix routing status

The matrix carries 84 rows; this module implements the core product surface โ€” roughly 50 rows, evidenced by the tests above โ€” and descopes the remaining exotic, legacy, or data-unsupported rows honestly.

Railed participant profile (#99, PPRF-OE)

The shared participant-profile module mounts in the rail beside the chart (config-on, profile: true) and is fed by the renderer's existing point-click selection via the participantsSelected dispatch on the shell root (SOE-API-003) โ€” the rail SUPPLEMENTS the linked listing (records vs story), replacing nothing. Adoption rows are PPRF-OE-001..003 in the participant-profile matrix; unit evidence lives in tests/unit/outlier-explorer/profile-adoption.test.js.

View-selector rollout (VIEW-3, #76)

One primary display โ€” the line chart. Every control reshapes that chart; the participant listing is a point-click drill-down, not a view switch. Ruled single-view in the shared view-selector rollout (#76) โ€” no view control is added; see view-selector-inventory.md.

Reproducing this report

The evidence set is regenerated from a full test run and committed with the code it qualifies; CI fails when they drift. To verify or rebuild it:

npm ci
npm run evidence:check   # compare a fresh run against the committed evidence
npm run evidence         # regenerate docs/evidence/outlier-explorer/evidence.json

Screenshot baselines are canonical to the Linux CI runner; the repository's Update evidence baselines workflow is the authoritative way to refresh them. See CONTRIBUTING.md for the traceability convention.