Tutorials › Pharmacometric Workflows and Reproducible Modeling › Building HTML Diagnostic Reports

Automating Diagnostics and Reports · Tutorial 308 of 399

Building HTML Diagnostic Reports

Build a portable HTML diagnostic report by combining readable page structure, rendered diagnostic content, accessible captions, and validated links to report artifacts.

Intermediate 13 min read

What You'll Learn

  • Distinguish a standalone HTML report package from a single file with every asset embedded.
  • Organize diagnostic material with semantic sections and a consistent visual layout.
  • Connect figures and tables to their captions, units, and source artifacts.
  • Construct relative links that continue to work when the report package is moved.
  • Escape generated text and check that referenced artifacts exist before delivery.
  • Validate report readability, navigation, and links using a small, explicit checklist.

From Diagnostic Outputs to a Usable HTML Report

Diagnostic figures and tables are useful only if a reviewer can find them, understand what they show, and open the associated artifacts. An HTML report brings those pieces together in a document that can be opened in a browser and distributed with its supporting files. In a pharmacometric workflow, the report should preserve context such as the diagnostic quantity, units, transformation, and analysis identifier—not just display an image.

The earlier material on diagnostic captions, data-linked narrative summaries, and reusable report sections supplies useful content for this task. Here the focus is on rendering that content as a coherent HTML document, with readable layout and links that resolve in the delivered package. A report package is “self-contained” in the practical sense that its HTML and required assets travel together and do not depend on a live analysis session or a particular working directory. It need not mean that every image is encoded inside one HTML file.

Definition: An HTML diagnostic report package is a deliverable containing an HTML document and the local assets it references, organized so that the document can be opened and its links resolved without access to the report-generation environment. A relative link identifies a target relative to the location of the HTML document, rather than relying on a machine-specific absolute path.

A useful starting structure is deliberately simple:

diagnostic-report/
  index.html
  figures/
    observed-predicted.png
    cwres-time.png
  tables/
    subgroup-summary.csv

The HTML document provides the reading order and context. The figures and table export remain separate files, linked from the document. This structure is easier to inspect and transfer than HTML that points to files in a user-specific temporary folder. It also makes clear which files belong to the report.

Structure the Document Around the Review Task

A report should have a predictable sequence: a concise report heading, a brief description of the analysis represented, then diagnostic sections with figures or tables and their explanations. Use headings to create meaningful sections, and use descriptive link text rather than vague labels such as “click here.” A small set of in-page links can let a reader move directly to important sections. These are ordinary links to named section anchors; they do not replace a carefully ordered report.

Use semantic HTML elements for their intended purposes. A heading identifies a section; a paragraph gives narrative context; a table represents values in rows and columns; and a link points to a destination. For a figure, place the image, a descriptive alternative text, and its caption together. The caption should identify the diagnostic and clarify any needed units or scale, while the surrounding text can explain the review-relevant pattern. Do not make the caption carry conclusions that the plotted data do not support.

Readable layout is not decoration added after the analysis. It affects whether readers can compare panels, find table headers, and distinguish context from interpretation. A modest embedded stylesheet can set a readable maximum text width, consistent spacing, responsive images, and table borders. Avoid relying on color alone to communicate a distinction, and check that text remains legible when the browser window is narrow.

Worked Example: Assembling Two Diagnostic Sections

Suppose a hypothetical model review has produced an observed-versus-predicted figure and a conditional weighted residuals (CWRES)-versus-time figure. The first figure uses observed concentration and population prediction in mg/L; the second uses time in hours and CWRES on a dimensionless scale. The report package contains both images under figures/.

A section can combine an anchored heading, context, a figure, a caption, and a link to the image artifact:

<section id="observed-predicted">
  <h2>Observed versus population-predicted concentration</h2>
  <p>Concentrations are shown in mg/L. Points are observations
  from the hypothetical diagnostic data set.</p>
  <figure>
    <img src="figures/observed-predicted.png"
         alt="Observed concentration plotted against
              population-predicted concentration">
    <figcaption>Figure 1. Observed versus population-predicted
    concentration (mg/L); the diagonal is the line of identity.</figcaption>
  </figure>
  <p><a href="figures/observed-predicted.png">
    Open the observed-versus-predicted image artifact
  </a></p>
</section>

The alt text describes the image’s content for readers who cannot view it; it is not a substitute for the more specific caption. The paragraph states the unit and data context. The caption identifies the plotted quantities and diagonal reference. The link gives a reader a direct route to the image file. The second section can follow the same pattern, changing the heading, description, image path, and caption to identify CWRES versus time (hours).

A small navigation block near the report heading could link to #observed-predicted and #cwres-time. Each destination works because the corresponding section has the same unique id. Check that IDs are unique and that the link fragment matches the target exactly; otherwise the link may open the document without moving to the intended section.

Relative Paths and Artifact Links

A browser resolves a relative URL from the directory containing the HTML document. Thus, if index.html is in diagnostic-report/, the link figures/observed-predicted.png points to a file inside diagnostic-report/figures/. This remains valid if the entire report directory is moved, because the relationship between the document and the image has not changed. In contrast, a link such as /home/analyst/run42/observed-predicted.png is tied to a particular machine and directory layout.

Path rule: For a relative link to work, the target must exist at the location obtained by resolving the link from the HTML document’s directory. If the report and target are moved together while retaining their relative layout, the link continues to identify the target.

This rule gives a simple justification for a pre-delivery link check: resolve each local link from the report directory, then verify that the resulting file exists. Checking only that a link string is nonempty is insufficient; a plausible-looking path can still point to the wrong directory or to a missing file. Use consistent, descriptive filenames without unnecessary spaces or ambiguous versions. If names contain spaces or non-ASCII characters, ensure that URLs are encoded correctly; avoiding such names in generated artifacts is often simpler.

Worked Example: Resolving and Checking Artifact Paths

A hypothetical report has this structure: diagnostic-report/index.html, diagnostic-report/figures/observed-predicted.png, and diagnostic-report/tables/subgroup-summary.csv. Its HTML contains links to figures/observed-predicted.png and tables/subgroup-summary.csv.

Resolve the first link from the HTML file’s parent directory. The document directory is diagnostic-report/, so the target is diagnostic-report/figures/observed-predicted.png. Resolving the second link gives diagnostic-report/tables/subgroup-summary.csv. If both files are present at those locations, both links resolve within the package.

For this example, suppose a pre-delivery check examines those two links and finds that both targets exist. The check therefore reports \(2/2=1.000\), or 100% of checked targets present, with zero missing targets. This result supports the narrow claim that these two paths exist; it does not establish that the images are readable, the CSV contents are correct, or every link in the report has been checked. Those require separate checks.

If the report directory is renamed or moved as a unit, the two relative paths still resolve. If only the HTML file is copied elsewhere, they generally do not. Deliver the package with its directory structure intact, and state clearly which HTML file is the entry point.

Render Tables and Generated Text Safely

A diagnostic table should remain understandable in HTML, not merely resemble a spreadsheet. Give it a clear caption, use header cells for column labels, and put units in the header or caption. For example, a column called “Median prediction error” is incomplete if the quantity’s scale or units are not otherwise stated. If the table is also offered as a downloadable CSV, link to it with a description that identifies the artifact.

Automated reports often insert values from data or metadata into HTML. Treat these values as text, not as trusted HTML. A subject label or analysis name could contain characters such as < or &, which have special meaning in markup. Escape text values before inserting them into HTML so they display as text rather than changing the document structure. Do not escape the surrounding HTML tags themselves. When constructing URLs, use URL-appropriate encoding for path components rather than assuming that HTML text escaping alone makes a URL valid.

Worked Example: Rendering a Hypothetical Summary Table

Consider this hypothetical subgroup summary, with median prediction error expressed as a percentage and the count recorded as a number of observations:

SubgroupObservations (n)Median prediction error (%)
Low exposure24-3.2
High exposure211.4

The total count represented is \(24+21=45\) observations. The values and units are explicit in the headers, and the table permits direct comparison of the two subgroup summaries. A report could introduce it with a sentence stating that the table summarizes the hypothetical data set, then place a caption identifying the summary and the percentage scale.

Suppose a subgroup label supplied to the report generator is Low & variable. If inserted as raw text, its ampersand can be interpreted as the beginning of an HTML character reference. Escape it for HTML text so the rendered label remains “Low & variable” without being treated as markup. Apply the same rule to generated captions and narrative text that include values from metadata. This protects the structure of the report and prevents data values from being interpreted as HTML.

Checks, Failure Modes, and Alternatives

A report is ready to review only after both its content and its delivery structure have been checked. A practical validation pass should include the following:

  • Open the entry-point HTML file in a browser and inspect the report at a normal and narrow window width.
  • Check that each figure is visible, its alternative text is present, and its caption identifies the quantity and relevant units or scale.
  • Check that tables have clear headers and that values, missing-value labels, and units are rendered as intended.
  • Resolve each local artifact link from the HTML file’s directory and confirm that the target exists.
  • Follow in-page links to confirm that each reaches the intended section; check that section identifiers are unique.
  • Move or copy the complete report package to a different directory and open it there. This tests whether it accidentally depends on the original working location.

Common failures are often small but consequential: a link points to an analysis scratch directory, a figure filename differs in capitalization from the filename on disk, an anchor does not match its target ID, or a generated label breaks markup because it was not escaped. A report can also be technically openable but hard to review if it omits units, uses unreadable text, or places interpretation in a figure without explaining the relevant context. When an asset is missing, do not silently leave a broken image; make the generation or validation process report the missing target so the issue can be corrected before delivery.

There are two broad delivery alternatives. A linked-asset package keeps images and downloadable files separate from the HTML, making individual artifacts straightforward to inspect and replace, but the directory structure must be preserved. A single HTML file can instead include assets inside the document, which reduces the number of files to distribute but can make the file larger and its contents less convenient to inspect. The choice depends on distribution needs; neither approach removes the need to test the rendered report. Avoid external resources that require network access when the report is expected to work offline.

These checks have limits. A file-existence check does not prove that an image is an appropriate diagnostic, that a table is numerically correct, or that a narrative interpretation is justified. Browser rendering can also differ across environments. HTML report validation complements—not replaces—review of the underlying diagnostic content and the generated artifacts.

Key takeaway: A portable diagnostic report combines contextualized content with paths that resolve within a delivered package. Inspect the rendered page, verify local targets, and preserve the package structure; do not infer content correctness from successful rendering alone.

Check Your Understanding

Answer each question, then compare your reasoning with the solutions.

  1. An HTML file is in review/index.html, and a figure is in review/figures/residual-time.png. What relative link identifies the figure from the HTML file?
  2. Why is a link to /tmp/run9/plot.png a poor choice for a report intended to be shared?
  3. A figure has a caption naming the diagnostic but does not identify the time unit on its horizontal axis. What should be improved?
  4. A local link check finds that every target exists. What does that result establish, and what does it not establish?

Solutions. (1) Use figures/residual-time.png, because the figure is in a subdirectory of the HTML file’s directory. (2) The absolute path depends on a particular machine and temporary directory; a relative path within the delivered package is more portable. (3) Add the time unit to the caption, axis label, or surrounding text so the plotted scale is interpretable. (4) It establishes that the checked targets exist at the resolved paths. It does not verify that their contents are correct, that the rendered page is readable, or that the diagnostic interpretation is valid.

Clinical Biostats