Skip to content

Virtual Grid

The data grid is the primary interface for viewing and interacting with timeline data. It uses virtual scrolling backed by SQLite pagination to handle millions of rows without performance degradation.

Virtual Grid displaying EvtxECmd timeline data with sortable columns, row detail panel, and histogram

The menu bar provides access to all application features through five dropdown menus with glassmorphism styling.

File

ItemShortcutDescription
Open⌘OOpen a file via the system dialog
Export⌘EExport filtered data as CSV, TSV, XLSX, or XLS
Save Session⌘SSave all tabs, filters, bookmarks, tags, and color rules to a .tle file
Load Session⇧⌘ORestore a previously saved session
Open RecentSubmenu showing the last 10 opened files with full paths
Close Tab⌘WClose the active tab
Close All TabsClose every open tab
ExitQuit the application

View

ItemDescription
ColumnsOpen the Column Manager to show, hide, and reorder columns
Color RulesCreate and manage conditional formatting rules
TagsView and manage all tags across the active tab
Filter PresetsSave and load named filter configurations
Edit FilterOpen the advanced filter editor for the active tab
Merge TabsCombine multiple tabs into a unified super-timeline

Actions

ItemDescription
Show Flagged OnlyToggle between all rows and bookmarked-only view
Select AllSelect all rows (checkbox)
Deselect AllClear checkbox selection
Invert SelectionToggle the selection state of every row
Copy Selected RowsCopy selected rows as tab-separated text to clipboard
Export Selected RowsExport selected rows as CSV via save dialog
IOC MatchingScan timeline data for Indicators of Compromise
Bulk Tag / BookmarkApply tags or bookmarks to rows by time range
Pivot ±N MinutesFilter to a time window around the selected row
Find DuplicatesIdentify repeated values in any column

Tools

ItemDescription
Stack ValuesFrequency analysis of unique values in any column
Gap AnalysisDetect periods of unusual inactivity in the timeline
Log SourcesGantt-style heatmap of log source coverage across time
Burst DetectionIdentify abnormal spikes in event volume
Process InspectorParent-child process hierarchy with MITRE ATT&CK detection
Lateral Movement TrackerNetwork graph of host-to-host logon activity with attack pattern detection
Persistence AnalyzerAutomated detection of 30+ persistence techniques with risk scoring
Generate ReportCreate an HTML investigation report from bookmarks and tags

Help

ItemShortcutDescription
Quick HelpIn-app guide covering supported formats, search modes, and shortcuts
Keyboard Shortcuts⌘/Reference card of all keyboard shortcuts
WebsiteOpen the IRFlow Timeline documentation site
About IRFlow TimelineVersion info, author, and social links

Toolbar Controls

In addition to the menu bar, the toolbar contains:

  • Date/time format selector and timezone selector
  • Theme toggle (dark/light)
  • Font size controls (decrease/increase)
  • Histogram toggle — show or hide the timeline histogram visualization

How It Works

Rather than loading all rows into memory, the grid maintains a sliding window of 10,000 rows centered on your scroll position. As you scroll, new rows are fetched from SQLite using LIMIT/OFFSET queries with a 2,000-row prefetch threshold. This means:

  • Memory usage stays constant regardless of dataset size — only ~10K rows in the JS heap at any moment
  • Scrolling is smooth with 20-row overscan padding above and below the viewport and requestAnimationFrame-throttled scroll handling
  • Initial load is instant — no waiting for millions of rows to render
  • Skeleton placeholders appear briefly during fast scrolling while the next data window loads

Column Operations

Sorting

Click any column header to sort. Click again to toggle ascending/descending, click a third time to clear. A sort indicator appears on the active column.

Sorting is type-aware and handled entirely in SQL:

Column TypeSort Method
TimestampCustom sort_datetime() function — handles ISO, US date, Unix seconds/milliseconds, Excel serial dates, and 12-hour AM/PM formats
NumericCAST(column AS REAL) — detected automatically when 80%+ of sampled values are numeric
TextCOLLATE NOCASE — case-insensitive alphabetical

Indexes are created lazily on first sort for optimal performance. Background async indexing builds indexes for all columns after import without blocking the UI.

Resizing

Drag the right edge of any column header to resize it. Minimum width is 60px. Column widths are preserved per tab and saved in sessions.

Pinning

Cmd+Click a column header and select Pin Left to pin it to the left side of the grid. Pinned columns use sticky positioning so they stay visible as you scroll horizontally — useful for keeping timestamp or event name columns always in view.

Hiding / Showing

Open the Column Manager from the toolbar to:

  • Hide columns you don't need
  • Show previously hidden columns
  • Show All / Hide All with one click
  • Reorder columns via drag-and-drop
  • Reset to default column order

Empty columns are auto-hidden on import so your grid starts clean.

Reordering

Drag column headers to rearrange them directly in the grid. Column order is persisted per tab and saved in sessions.

Auto-Fit

Cmd+Click a column header and select Best Fit to auto-size the column width to its content with 10% padding.

Column Quick Stats

Cmd+Click a column header and select Column Stats to see value distribution, fill rate, and type-specific statistics for that column.

Row Selection

Each row has a checkbox for multi-selection, plus these interaction methods:

  • Checkbox — click the checkbox cell to toggle selection without affecting the detail panel
  • Single click — selects a row and displays it in the detail panel
  • Shift+Click — selects a range of rows from the last clicked row to the current
  • Cmd+Click — toggles individual rows in/out of the selection without clearing existing selections
  • Arrow Up/Down — navigates selection with auto-scroll to keep the selected row visible

The header row includes a master checkbox (select all / deselect all). In grouped view, each group header has its own checkbox to select or deselect all rows within that group (shows indeterminate state when partially selected).

Bulk Selection Actions

Available from the Actions menu:

  • Select All — selects all rows (works in both normal and grouped mode)
  • Deselect All — clears the selection
  • Invert Selection — toggles the selection state of every row
  • Copy Selected Rows (Cmd+C) — copies selected rows as tab-separated text to the clipboard
  • Export Selected Rows — exports selected rows as CSV via a save dialog

Selection state (selected rows, last clicked row, scroll position) is preserved per tab — switching tabs and back restores exactly where you left off.

The status bar shows "Row: X" for single selection or "N rows selected" for multi-select, along with the full file path of the active tab.

Detail Panel

Clicking a row opens a resizable detail panel at the bottom of the window. It displays all column values for the selected row in a readable format with per-value copy buttons, which is especially useful when rows contain long values that are truncated in the grid. Drag the top edge to resize (80px–600px).

Cell Rendering

Color Rules

Rows are colored by the first matching color rule. Rules support four conditions: contains, equals, starts with, and regex. Rules are pre-compiled once for performance — regex patterns are not re-created per row.

Color priority: selection highlight > color rule > bookmark highlight > alternating row stripes.

Eight built-in presets are available for common forensic patterns (PowerShell, Mimikatz, LSASS, Critical events, etc.).

Search Highlighting

When search is active in highlight mode, matching terms are marked with yellow/amber background within each cell. Supports regex and multi-word mixed/AND search term highlighting.

IOC Highlighting

After running an IOC scan, matched indicator values are highlighted inline in the grid with orange semi-transparent background and bold text. When both search and IOC highlights are active, they use distinct colors — orange for IOC matches, amber for search matches. IOC patterns are sorted longest-first to prevent shorter substrings from stealing matches. An "IOC Highlights" badge in the status bar shows the count and can be clicked to clear.

Timestamp Formatting

Timestamp columns are formatted according to your selected datetime format and timezone setting. All other columns are rendered as-is with text truncation and ellipsis overflow.

Grouped View

Group rows by any column using the context menu or by dragging column headers to the group bar. Multiple grouping levels are supported for hierarchical views.

Groups display:

  • Collapsible headers showing the value and row count per group
  • Multi-level nesting — each expand fetches the next grouping level from SQLite
  • Leaf-level data — expanding the deepest group loads actual rows (batched at 100K) with a "Load More" button for large groups
  • Clear button to remove all grouping at once

Filtering

Per-Column Text Filters

A filter row below the column headers provides a text input per column. Typing filters using case-insensitive SQL LIKE matching. Filters are debounced at 500ms to avoid excessive queries while typing.

Checkbox Filters

Cmd+Click a column header to open a checkbox filter showing the top 25 values for that column. Search within the value list to find specific entries. Toggle values on/off to include or exclude them.

Disable Individual Filters

Active filters can be individually toggled on/off without removing them, useful for A/B comparison while preserving your filter setup.

Filter Caching

Query results are cached per unique filter configuration (up to 4 cache entries per tab). This enables instant toggling between highlight and filter mode, and fast tab switching.

Context Menu

The context menu uses a macOS-style glass/blur aesthetic with inline SVG icons for each action.

Open via: Cmd+Click a column header.

Column Header Menu

IconActionDescription
PinPin / UnpinPin column to the left side
Eye-slashHide ColumnRemove column from view
ArrowsBest FitAuto-size column to content
UndoReset WidthsReset all column widths to default
Up arrowSort AscendingSort A→Z / oldest→newest
Down arrowSort DescendingSort Z→A / newest→oldest
Stacked barsStack ValuesOpen value frequency analysis
Bar chartColumn StatsValue distribution and type statistics

Row / Cell (Cmd+Click)

  • Copy Cell value
  • Copy Row as TSV
  • Bookmark / Remove Bookmark
  • Add Tag
  • Bulk Tag / Untag selected rows

Find Duplicates

Open Actions > Find Duplicates to find repeated values in any column. Select a column from the dropdown and click "Find Duplicates" to scan for values that appear more than once. Results show the duplicate value and occurrence count (capped at 100 displayed). Click "Filter to Duplicates" to apply a checkbox filter on the selected column showing only rows with duplicate values.

Bookmarks and Tags

Bookmarks

Click the star icon in the bookmark column to flag important rows. Bookmarked rows receive a subtle orange background overlay. The status bar shows a "Flagged: N" count. Use the bookmarked-only filter to show only flagged rows.

Tags

The Tags column is a full first-class grid column displaying color-coded tag pills per row. It supports sorting, text filtering, checkbox filtering, stacking, and column stats — just like any data column. Add tags via the context menu with tag name suggestions. Tags support bulk operations — select multiple rows and apply or remove tags in one action. See Bookmarks & Tags for full details.

Performance Characteristics

MetricValue
Row height26px fixed
Cached window10,000 rows centered on scroll position
Prefetch thresholdRe-fetch when within 2,000 rows of cache edge
Overscan20 rows above/below viewport
Query debounce500ms for search/filter changes
Scroll fetch debounce50ms for scroll-driven window fetches
Search result cacheUp to 4 entries per tab
Count cachePer filter signature, invalidated on bookmark/tag changes
Index creationBackground async — all columns indexed after import without blocking UI
Stale request preventionMonotonic fetch IDs discard out-of-order responses
Min column width60px
Group batch size100,000 rows per expand

Built for the DFIR community.