README file from
Githubtimemd-visualizor for Obsidian
timemd-visualizor navigates and visualizes data exported from the time.md screen-time analytics app, directly inside Obsidian.
Drop any time.md export into a folder in your vault and timemd-visualizor recreates the core time.md experience — Overview, Trends, Calendar, Details, and Apps & Categories views — without needing to open the app.
Supported import formats
timemd-visualizor auto-detects and parses every format time.md can export:
- JSON (
.json) — nested or flat - CSV (
.csv) — with or without metadata comments and section markers - Markdown (
.md) — GitHub-flavored tables with metadata header - Obsidian (
.md) — YAML frontmatter + wiki links, fully navigable in place
Views
| View | What it shows |
|---|---|
| Overview | Today's total, top apps, sparkline, key metrics |
| Trends | Daily / weekly line chart with period comparison |
| Calendar | Month grid + 7×24 usage heatmap |
| Details | Filterable raw-session table |
| Apps & Categories | Aggregated apps and user-defined categories |
| Projects | Category groups with donut distribution chart and stats |
| Web History | Browser history timeline, top domains, hourly activity |
| Reports | Daily / weekday breakdowns with CSV / JSON / Markdown export |
| Input Tracking | Cursor heatmap, typing intensity, top words / keys, per-app clicks (opt-in in time.md) |
Open any view from the command palette (timemd-visualizor: Open Overview, etc.) or the ribbon icon.
Input Tracking
If you've enabled Input Tracking in the time.md app (Settings → Input Tracking), the .input destination emits six new sections that this plugin renders as the Input Tracking view:
| Section | What it shows |
|---|---|
| Cursor Heatmap Bins | 2D heat overlay in absolute screen coordinates, per-screen tab strip, optional click overlay |
| Typing Intensity | Hourly keystrokes line chart |
| Top Typed Keys | Bar list of the 25 most-pressed keys |
| Top Typed Words | Bar list of the 50 most-typed words (only populated when "Full content" capture is on; default-redacted with a Reveal toggle) |
| Raw Mouse Events | Per-app click counts + click dots overlaid on the cursor heatmap |
| Raw Keystrokes | Optional first-200 timeline (chars default-redacted; secure-input rows show 🔒) |
Example export workflow
-
In time.md → Export view, pick Destination = Input (or Combined with the input toggles enabled).
-
Pick a format the plugin can read — JSON is recommended for the raw sections:
Format: JSON Destination: Input Date range: Today Sections: Top Typed Words, Top Typed Keys, Cursor Heatmap Bins, Typing Intensity, Raw Keystrokes (optional), Raw Mouse Events (optional) -
Save the file into the folder you've configured under Settings → timemd-visualizor → Export folder.
-
Run timemd-visualizor: Open Input Tracking from the command palette (or click the keyboard ribbon icon).
A minimal JSON export the view can render looks like:
{
"title": "Input Tracking — 2026-05-04",
"destination": "input",
"sections": [
{
"name": "input_cursor_heatmap",
"display_name": "Cursor Heatmap Bins",
"headers": ["screen_id", "bin_x", "bin_y", "samples"],
"data": [
{ "screen_id": 1, "bin_x": 30, "bin_y": 22, "samples": 1820 },
{ "screen_id": 1, "bin_x": 31, "bin_y": 22, "samples": 1280 },
{ "screen_id": 2, "bin_x": 60, "bin_y": 20, "samples": 1140 }
]
},
{
"name": "input_typing_intensity",
"display_name": "Typing Intensity",
"headers": ["timestamp", "keystrokes"],
"data": [
{ "timestamp": "2026-05-04T10:00:00Z", "keystrokes": 388 },
{ "timestamp": "2026-05-04T11:00:00Z", "keystrokes": 612 },
{ "timestamp": "2026-05-04T15:00:00Z", "keystrokes": 720 }
]
},
{
"name": "input_top_keys",
"display_name": "Top Typed Keys",
"headers": ["key_code", "key_label", "count"],
"data": [
{ "key_code": 49, "key_label": "Space", "count": 1820 },
{ "key_code": 36, "key_label": "Return", "count": 412 },
{ "key_code": 51, "key_label": "Delete", "count": 388 }
]
}
]
}
A larger fixture covering all six sections lives at tests/fixtures/input-tracking-sample.json — drop it into your export folder to preview the view without needing real data.
Privacy
- The Top Typed Words and Raw Keystrokes panels default to redacted (each character replaced with
•); click Reveal words / Reveal chars to unmask. - Rows captured while macOS Secure Input was active (e.g. password fields,
sudoprompts) are surfaced as 🔒 with emptycharvalues, by design from the time.md exporter. - If no input sections are present in any loaded export, the Input Tracking view shows an empty-state callout — the existing views are unaffected.
Embedding into notes
Drop a timemd code block into any note to render a live widget that updates whenever you reload exports:
```timemd
view: overview
```
Supported views
view |
Renders |
|---|---|
overview |
Stats strip, trend sparkline, top apps (default) |
stat |
One big number — configure with metric: |
trends, trend-chart |
Daily line chart |
calendar, heatmap |
7×24 weekly heatmap |
apps, top-apps |
App bar list |
categories |
Category bar list |
details |
Recent sessions list |
projects |
Categories list + distribution donut + stats |
distribution |
Donut chart + category legend + stats card (no list) |
web-history |
Browser history (timeline / domains / activity tab) |
reports |
Time distribution + weekday averages + report data table |
input-stats |
Stats strip — keystrokes, peak typing minute, cursor samples, clicks, apps observed |
cursor-heatmap |
Aspect-preserving cursor heatmap in absolute screen coordinates with click overlay |
typing-intensity |
Hourly keystroke line chart |
top-keys |
Bar list of the most-pressed keys |
top-words |
Bar list of the most-typed words (default-redacted; Reveal toggle) |
input-activity |
Per-app click count bar list |
Parameters
| key | applies to | default | description |
|---|---|---|---|
view |
all | overview |
widget type (see table above) |
limit |
overview, top-apps, categories, details, top-keys, top-words |
varies | number of items shown |
days |
overview, trend-chart |
all | restrict to last N days of trend data |
height |
cursor-heatmap, typing-intensity |
view default | SVG canvas height in pixels |
metric |
stat |
total_time |
total_time, top_app, apps_count, days, peak_day |
sections |
overview |
all | comma-separated list of stats, trend, heatmap, apps |
date |
overview |
— | today, yesterday, or YYYY-MM-DD — filters every panel to that single day (requires Raw Sessions in the export) |
tab |
web-history |
timeline |
timeline, domains, or activity |
browser |
web-history |
— | filter to a single browser (Safari, Chrome, Arc, …) |
stats |
distribution |
true |
false to hide the STATS card |
legend |
distribution |
true |
false to hide the legend list (donut-only) |
label |
distribution |
true |
false to hide the "DISTRIBUTION" label |
bare |
all | false |
true removes the embed's background, border, and padding so the widget sits flush on the note |
groupBy |
reports |
app |
app, category, or day |
format |
reports |
csv |
csv, json, or markdown (used by the in-view Export button) |
title |
all | — | optional heading |
Examples
Dashboard stat card for a daily note:
```timemd
view: stat
metric: total_time
title: Screen time today
```
Last 7 days of trend:
```timemd
view: trend-chart
days: 7
title: Last week
```
Top 5 apps:
```timemd
view: top-apps
limit: 5
```
Lean overview — stats and apps only, last 7 days:
```timemd
view: overview
sections: stats, apps
days: 7
limit: 3
```
Just yesterday:
```timemd
view: overview
date: yesterday
title: Yesterday
```
Input tracking dashboard for a daily note:
```timemd
view: input-stats
title: Input today
```
```timemd
view: cursor-heatmap
height: 360
```
```timemd
view: top-words
limit: 20
```
A complete sample note that wires every input component together lives at
examples/input-tracking.md.
Setup
- Install the plugin (see "Manually installing" below while it's pre-release).
- Export data from the time.md app using any supported format.
- Place the exported file(s) inside a folder in your Obsidian vault.
- Point the plugin at that folder in Settings → timemd-visualizor → Export folder.
- Run timemd-visualizor: Open Overview from the command palette.
Manually installing (pre-release)
- Build locally:
npm install && npm run build - Copy
main.js,styles.css,manifest.jsoninto<vault>/.obsidian/plugins/timemd-visualizor/ - Enable the plugin in Obsidian settings.
Development
npm install
npm run dev # esbuild in watch mode
npm run build # type-check + production build
License
0BSD (same as the sample plugin template).