Haptics Lab
The Haptics Lab is an exploratory page for evaluating how tactile feedback (haptics) can complement chart sonification in ParaCharts. This experience is designed first for mobile testing, where touch, sound, and vibration can be experienced together while moving across real chart data points.
Haptics is treated as a progressive enhancement: audio and keyboard interaction still work broadly, but tactile output currently works only on supported Android browsers over HTTPS. Do not use desktop or iPhone for this hands-on haptics evaluation yet.
Chart Navigation Lab
The charts below are fully integrated with haptic and audio feedback. Navigate into a chart with the keyboard and move between data points with arrow keys — each point fires both a tone and a vibration whose intensity reflects the data value.
System Status
Initializing…
Self-test not run yet.
How to Navigate
- Tab into one of the charts below to focus it.
- Press Enter or ↓ to enter the data layer.
- Use ← / → to move between data points.
- Each point fires a vibration (on Android over HTTPS) whose intensity reflects the data value, plus an audio tone from the chart's built-in sonification.
- Press Escape to return to the chart top level.
- Press q while on a data point to hear a spoken summary.
Haptics Settings
Current Point
Navigate into a chart with the keyboard to see point details here. This section displays the current data point's values, index, and any haptic/audio feedback information.
Haptics Debug Log
Use this on mobile when the browser console is not available. It logs vibration support checks, skipped calls, API return values, and runtime chart events.
Show debug log (0 entries)
- Waiting for events...
Chart 1: Mountain Peak
A column chart with values rising from 8 to 100 then falling back to 8. Use arrow keys to navigate left to right and feel intensity climb then descend. Higher values produce longer vibrations. The peak (point 7, value 100) vibrates longest.
Chart 2: Staircase
A line chart with four distinct steps at values 20, 50, 80, and 100 (three points each). Use arrow keys to navigate through and feel the four distinct haptic zones increase in intensity. Each step repeats three times so you can feel consistent vibration at each level.
What To Notice During Testing
- Value discrimination (Staircase): Use arrow keys to navigate through the four steps (20, 50, 80, 100). Can you clearly distinguish each haptic zone by feel alone?
- Trend detection (Mountain Peak): Navigate left to right through the bell curve. Does the increasing then decreasing vibration intensity help you sense the peak?
- Zero handling: Notice the weak tick at value 0 — it confirms the value exists without creating a false rhythm.
- Sensory binding: Sound and touch within ~50 ms are typically fused by the brain. Do the audio tone and vibration feel unified?
- Eyes-closed navigation: Try closing your eyes while navigating to rely fully on haptic + audio feedback.
Browser and Device Support
| Feature | Chrome (Android) | Firefox (Android) | Safari (iOS) | Desktop |
|---|---|---|---|---|
| Web Vibration API (haptics) | ✅ | ✅ | ❌ | ❌ |
| Web Audio API (tones) | ✅ | ✅ | ✅ | ✅ |
Key constraints:
- Haptics require HTTPS. Vibration is blocked on plain HTTP pages.
- iOS (Safari and all iOS browsers) does not support the Web Vibration API and will silently skip the haptic step.
- Desktop browsers expose no haptic motor; only the audio channel will play.
Compatibility Policy
- PWA installation is not required. This page can vibrate from a regular website tab when browser/device policies allow it.
- Support is capability-based, not app-type-based. The deciding factors are browser support, device hardware, secure context, and user settings.
- Treat haptics as progressive enhancement. Audio, visible UI, and keyboard/screen reader flows remain the primary channels.
Android Troubleshooting Checklist
Use this quick flow when self-test works but chart interactions feel weak:
- Run Run Vibration Self-Test in the System Status card and confirm
metadata.selfTest.passedistruein exported JSON. - Verify phone settings: vibration/haptics enabled at OS level; Silent/Do Not Disturb/Battery Saver not suppressing haptics.
- Navigate points with keyboard arrows and confirm new log entries show
vibrate(...) sent successfully. - If self-test succeeds but point feedback still feels weak, place the phone on a hard surface and retest.
Resources
If you want to go deeper into haptics, accessibility, and tactile communication, these are the most useful starting points from this experiment.
1. Web API docs
- MDN: Vibration API — the main browser reference for
navigator.vibrate(), vibration patterns, cancellation, and compatibility. - MDN: Progressive web apps — broader background on installability and offline behavior. Useful context, but a PWA is not required for basic vibration support.
2. Accessibility and deafblind research
- Beyond the fingertips: imagining haptic technologies for a deafblind future — strong design framing for haptics as part of a larger sociotechnical system, especially for deafblind users.
- Nagish: Deafblind communication devices and apps — practical overview of how haptics, text, AI, braille, and communication tools can work together.
3. Practical takeaways for builders
- Start with confirmation and emphasis patterns before attempting continuous tactile encoding.
- Treat haptics as one channel in a multimodal experience, alongside audio, text, visible labels, and assistive tech.
- Design for real-time interaction and user pacing so people can explore without being overloaded.
- Expect people to assemble their own workflow from multiple tools: haptics, speech, braille, interpreters, device settings, and contextual knowledge.
4. Good questions to keep asking
- Does the haptic cue add meaning, or just motion?
- Can the user control the pace of exploration?
- Is the system still understandable without haptics?
- Are you supporting real tasks and shared experiences, not just demonstrating a device feature?
Learn More
✨ Technical Details
Perceptual Zones
Haptic intensity increases with data value through six distinct sensory zones:
| Value | Sensation | Pattern | Duration |
|---|---|---|---|
| 0 | Minimal tick (presence confirmation) | Single short | 10 ms |
| 1-25 | Weak tick | Single tick | 50 ms |
| 26-50 | Medium double | [100, 50, 100] | 250 ms total |
| 51-75 | Strong double | [150, 75, 150] | 375 ms total |
| 76-99 | Very intense | [200, 100, 200] | 500 ms total |
| 100 | Peak sensation | [250, 150, 250] | 650 ms total |
The perceptual zones map linearly to data values. Users can distinguish these zones through haptic perception alone, enabling data exploration by touch feedback. The value 0 is acknowledged with a minimal vibration to confirm its presence without confusion with "no value."
Frequency Mapping
Audio frequency maps linearly from 150 Hz (value 1) to 900 Hz (value 100):
freq (Hz) = 150 + (value x 7.5)
This places low-value data in the low-frequency range (rumble/thud) and high-value data in the high-frequency range (beep/tone), reinforcing the haptic intensity signal.
HapticFeedbackManager Reference
Below is the standalone HapticFeedbackManager class developed for this evaluation. It can be integrated into ParaCharts as a decoupled module that listens to chart focus events.
/**
* HapticFeedbackManager
* Maps data values (1-100) to Web Vibration API patterns.
* Fails silently on unsupported browsers (iOS, desktop).
*/
class HapticFeedbackManager {
constructor(options = {}) {
this.isEnabled = options.enabled !== undefined ? options.enabled : true;
this.isSupported = 'vibrate' in navigator;
this.lastTriggerTime = 0;
this.throttleMs = 50; // Prevents motor lag during fast keyboard traversal
}
/**
* Trigger a vibration for a data value (1-100).
* @param {number} value
*/
trigger(value) {
if (!this.isEnabled || !this.isSupported) return;
const now = Date.now();
if (now - this.lastTriggerTime < this.throttleMs) return;
this.lastTriggerTime = now;
const val = Math.max(1, Math.min(100, value));
const duration = Math.round(10 + val * 1.3);
const gap = Math.round(500 - val * 4.8);
if (val < 40) {
navigator.vibrate(duration);
} else if (val < 80) {
navigator.vibrate([duration, gap, duration]);
} else {
navigator.vibrate([duration, gap, duration, gap, duration]);
}
}
toggle(state) {
this.isEnabled = state;
}
}
Throttling: The 50 ms throttle prevents the device motor from queuing hundreds of commands when a user traverses a dense chart rapidly by keyboard. Without it, the phone may continue buzzing long after the user stops moving.
Integration With ParaCharts: The intended hook is the chart's pointFocus or equivalent event:
const haptics = new HapticFeedbackManager({ enabled: true });
chart.on('pointFocus', (data) => {
playTone(data.value); // existing sonification
haptics.trigger(data.value); // new tactile layer
});
The haptic trigger is synchronous so it fires at the same timestamp as the AudioContext note start, which keeps the two sensory channels aligned within the ~50 ms threshold where the brain perceives them as a single event.
Accessibility Notes
- Haptics are never the only channel. All data is also conveyed through visual labels, keyboard queries (
q), ARIA live regions, and sonification. - Users must be able to disable haptics independently of audio. A toggle should be added to the Control Panel before this feature is promoted out of experimental status.
- No motor intensity control. The Web Vibration API only controls timing, not amplitude. This limits resolution to approximately 8-12 distinguishable zones.