Skip to content

a11y: Chart VoiceOver descriptors + localize chart-mark strings#2121

Merged
garthvh merged 2 commits into
meshtastic:mainfrom
bruschill:a11y/pr6-charts
Jul 20, 2026
Merged

a11y: Chart VoiceOver descriptors + localize chart-mark strings#2121
garthvh merged 2 commits into
meshtastic:mainfrom
bruschill:a11y/pr6-charts

Conversation

@bruschill

@bruschill bruschill commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

What changed?

Makes the Swift Charts metric graphs navigable by VoiceOver (they previously had no per-point accessibility) and localizes the hardcoded English chart-mark strings.

  • Shared MetricsChartSeries — every series mark gets a per-mark .accessibilityLabel (localized metric name + timestamp) and .accessibilityValue (reading + units) via the central chartBodyClosure. Added an optional unit field to the series model (default nil), populated by the AirQuality/Environment series.
  • DeviceMetricsLog / DetectionSensorLog / PaxCounterLog / PowerMetricsLog / PositionAltitudeChart / NodeWeatherForecast — replaced generic "Line Series"/"Bar Series"/"X: … Y: …" strings with per-metric localized labels/values; localized legend/foreground-style keys so legend and marks stay in sync; PositionAltitudeChart altitude is now unit-aware (m/ft) and locale-formatted; hid internal threshold/selection RuleMarks and decorative weather marks.
  • 10 files changed, +145 / −32; 20 additive Localizable.xcstrings keys.

Design choice: per-mark labels/values instead of .accessibilityChartDescriptor, because the shared charts render an arbitrary user-configurable mix of series where a static AXChart descriptor would be brittle.

Why did it change?

The metric charts were opaque to VoiceOver — no way to read individual data points — and the deferred chart-mark strings were hardcoded English. This makes the data readable and the strings translatable.

How is this tested?

Built the Meshtastic scheme for iOS Simulator (iPhone 17 Pro, Xcode 26) → ** BUILD SUCCEEDED **. SwiftLint clean. Passed a focused Swift/SwiftUI review confirming the shared-model unit change is safe for every consumer (unitless path exercised), all String(localized:) keys resolve, number/measurement formatting is locale-correct, and the catalog edits are clean-additive. A live VoiceOver pass over the charts is recommended before merge.

Screenshots/Videos (when applicable)

N/A — no visual change; adds VoiceOver descriptors to existing charts.

Checklist

  • My code adheres to the project's coding and style guidelines.
  • I have conducted a self-review of my code.
  • I have commented my code, particularly in complex areas.
  • I have verified whether these changes require updates to the in-app documentation under docs/user/ or docs/developer/. No doc update is needed (VoiceOver descriptors only, no UI/flow change) — please apply the skip-docs-check label.
  • I have tested the change to ensure that it works as intended.

Summary by CodeRabbit

  • Accessibility
    • Improved VoiceOver descriptions across weather, environmental, power, device, detection, altitude, and PAX charts.
    • Chart readings now include localized timestamps, measurement units, formatted values, and “No reading” text when applicable.
    • Reduced unnecessary VoiceOver elements by hiding chart markers and selection guides.
  • Localization
    • Added localized labels and accessibility metadata for chart metrics, legends, units, and device counts.

@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 83f4e3cf-6bce-4ed7-a150-546a1f8de734

📥 Commits

Reviewing files that changed from the base of the PR and between 1ce6508 and d4c48e9.

📒 Files selected for processing (10)
  • Localizable.xcstrings
  • Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift
  • Meshtastic/Views/Helpers/Weather/NodeWeatherForecast.swift
  • Meshtastic/Views/Nodes/DetectionSensorLog.swift
  • Meshtastic/Views/Nodes/DeviceMetricsLog.swift
  • Meshtastic/Views/Nodes/Helpers/Map/PositionAltitudeChart.swift
  • Meshtastic/Views/Nodes/Helpers/Metrics Columns/AirQualityDefaultSeries.swift
  • Meshtastic/Views/Nodes/Helpers/Metrics Columns/EnvironmentDefaultSeries.swift
  • Meshtastic/Views/Nodes/PaxCounterLog.swift
  • Meshtastic/Views/Nodes/PowerMetricsLog.swift

📝 Walkthrough

Walkthrough

Chart accessibility metadata is localized across metrics, weather, detection, altitude, PAX, and power charts. Shared chart series now format readings with optional units and localized fallback text, while decorative chart marks are hidden from VoiceOver.

Changes

Accessibility localization

Layer / File(s) Summary
Localization keys and shared chart metadata
Localizable.xcstrings, Meshtastic/Model/Metrics Visualization/MetricsChartSeries.swift
Adds VoiceOver localization keys and centralizes timestamp, reading, unit, and “No reading” accessibility formatting in MetricsChartSeries.
Measurement unit configuration
Meshtastic/Views/Nodes/Helpers/Metrics Columns/*
Adds units for particulate, environmental, temperature, humidity, pressure, light, radiation, wind, rainfall, weight, and distance series.
Specialized chart accessibility metadata
Meshtastic/Views/Helpers/Weather/NodeWeatherForecast.swift, Meshtastic/Views/Nodes/*, Meshtastic/Views/Nodes/Helpers/Map/PositionAltitudeChart.swift
Updates chart labels, values, legends, measurement formatting, and accessibility visibility for weather, detection, device metrics, altitude, PAX, and power charts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: garthvh

Poem

I’m a rabbit with charts in my den,
Making labels speak clearly again.
Degrees, volts, and PAX counts too,
With timestamps crisp and readings true.
Hidden marks softly leave the scene—
Hop-hop, accessibility clean!


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@garthvh garthvh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after detailed review (CodeRabbit was rate-limited and did not run). Chart VoiceOver descriptors are data-accurate and localization keys verified; CI green. Merged current main to resolve the Localizable.xcstrings key conflict (union of both key sets, JSON validated).

@garthvh
garthvh merged commit 5a442f4 into meshtastic:main Jul 20, 2026
2 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-docs-check Use this label to skip the automatic docs audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants