dataframe-textual 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dataframe-textual might be problematic. Click here for more details.
- dataframe_textual/__init__.py +35 -0
- dataframe_textual/__main__.py +48 -0
- dataframe_textual/common.py +204 -0
- dataframe_textual/data_frame_help_panel.py +98 -0
- dataframe_textual/data_frame_table.py +1395 -0
- dataframe_textual/data_frame_viewer.py +320 -0
- dataframe_textual/table_screen.py +311 -0
- dataframe_textual/yes_no_screen.py +409 -0
- dataframe_textual-0.2.1.dist-info/METADATA +549 -0
- dataframe_textual-0.2.1.dist-info/RECORD +13 -0
- dataframe_textual-0.2.1.dist-info/WHEEL +4 -0
- dataframe_textual-0.2.1.dist-info/entry_points.txt +2 -0
- dataframe_textual-0.2.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dataframe-textual
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Interactive CSV/Excel viewer for the terminal (Textual TUI)
|
|
5
|
+
Project-URL: Homepage, https://github.com/need47/dataframe-textual
|
|
6
|
+
Project-URL: Repository, https://github.com/need47/dataframe-textual.git
|
|
7
|
+
Project-URL: Documentation, https://github.com/need47/dataframe-textual#readme
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/need47/dataframe-textual/issues
|
|
9
|
+
Author-email: Tiejun Cheng <need47@gmail.com>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: csv,data-analysis,interactive,polars,terminal,textual,tui,viewer
|
|
13
|
+
Classifier: Development Status :: 3 - Alpha
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Natural Language :: English
|
|
19
|
+
Classifier: Operating System :: MacOS
|
|
20
|
+
Classifier: Operating System :: POSIX
|
|
21
|
+
Classifier: Operating System :: Unix
|
|
22
|
+
Classifier: Programming Language :: Python :: 3
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
27
|
+
Classifier: Topic :: Office/Business
|
|
28
|
+
Classifier: Topic :: Utilities
|
|
29
|
+
Classifier: Typing :: Typed
|
|
30
|
+
Requires-Python: >=3.11
|
|
31
|
+
Requires-Dist: polars>=1.34.0
|
|
32
|
+
Requires-Dist: rich>=14.2.0
|
|
33
|
+
Requires-Dist: textual>=1.0.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: textual-dev>=1.8.0; extra == 'dev'
|
|
36
|
+
Provides-Extra: excel
|
|
37
|
+
Requires-Dist: fastexcel>=0.16.0; extra == 'excel'
|
|
38
|
+
Requires-Dist: xlsxwriter>=3.2.9; extra == 'excel'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# DataFrame Viewer/Editor
|
|
42
|
+
|
|
43
|
+
A powerful, interactive terminal-based CSV/Excel viewer/editor built with Python, Polars, and Textual. Inspired by VisiData, this tool provides smooth keyboard navigation, data manipulation, and a clean interface for exploring tabular data directly in your terminal. Now with **multi-file support for simultaneous data comparison**!
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
## Features
|
|
48
|
+
|
|
49
|
+
### Core Data Viewing
|
|
50
|
+
- 🚀 **Fast CSV Loading** - Powered by Polars for efficient data handling with lazy pagination
|
|
51
|
+
- 🎨 **Rich Terminal UI** - Beautiful, color-coded columns with automatic type detection
|
|
52
|
+
- ⌨️ **Comprehensive Keyboard Navigation** - Intuitive controls for browsing, editing, and manipulating data
|
|
53
|
+
- 📊 **Flexible Input** - Read from files or stdin (pipes/redirects)
|
|
54
|
+
- 🔄 **Smart Pagination** - Lazy load rows on demand for handling large datasets
|
|
55
|
+
|
|
56
|
+
### Data Manipulation
|
|
57
|
+
- 📝 **Data Editing** - Edit cells, delete rows, and remove columns
|
|
58
|
+
- 🔍 **Search & Filter** - Find values, highlight matches, and filter selected rows
|
|
59
|
+
- ↔️ **Column/Row Reordering** - Move columns and rows with simple keyboard shortcuts
|
|
60
|
+
- 📈 **Sorting & Statistics** - Multi-column sorting and frequency distribution analysis
|
|
61
|
+
- 💾 **Save & Undo** - Save filtered data back to CSV with full undo/redo support
|
|
62
|
+
|
|
63
|
+
### Advanced Features
|
|
64
|
+
- 📌 **Pin Rows/Columns** - Keep important rows and columns visible while scrolling
|
|
65
|
+
- 🎯 **Cursor Type Cycling** - Switch between cell, row, and column selection modes
|
|
66
|
+
- 📂 **Multi-File Support** - Open multiple CSV files in tabs for side-by-side comparison
|
|
67
|
+
- 🔄 **Tab Management** - Seamlessly switch between open files with keyboard shortcuts
|
|
68
|
+
|
|
69
|
+
## Installation
|
|
70
|
+
|
|
71
|
+
### Using pip
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Install from PyPI
|
|
75
|
+
pip install dataframe-textual
|
|
76
|
+
|
|
77
|
+
# With Excel support (fastexcel, xlsxwriter)
|
|
78
|
+
pip install dataframe-textual[excel]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Then run:
|
|
82
|
+
```bash
|
|
83
|
+
dataframe-textual <csv_file>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Using uv
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Quick run using uvx without installation
|
|
90
|
+
uvx https://github.com/need47/dataframe-textual.git <csvfile>
|
|
91
|
+
|
|
92
|
+
# Clone or download the project
|
|
93
|
+
cd dataframe-textual
|
|
94
|
+
|
|
95
|
+
# Run directly with uv
|
|
96
|
+
uv run python main.py <csv_file>
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Development installation
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Clone the repository
|
|
105
|
+
git clone https://github.com/need47/dataframe-textual.git
|
|
106
|
+
cd dataframe-textual
|
|
107
|
+
|
|
108
|
+
# Install from local source
|
|
109
|
+
pip install -e .
|
|
110
|
+
|
|
111
|
+
# Or with development dependencies
|
|
112
|
+
pip install -e ".[excel,dev]"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Usage
|
|
116
|
+
|
|
117
|
+
### Basic Usage - Single File
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
# After pip install dataframe-textual
|
|
121
|
+
dataframe-textual pokemon.csv
|
|
122
|
+
|
|
123
|
+
# Or if running from source
|
|
124
|
+
python main.py pokemon.csv
|
|
125
|
+
|
|
126
|
+
# Or with uv
|
|
127
|
+
uv run python main.py pokemon.csv
|
|
128
|
+
|
|
129
|
+
# Read from stdin
|
|
130
|
+
cat data.csv | dataframe-textual
|
|
131
|
+
dataframe-textual < data.csv
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Multi-File Usage - Multiple Tabs
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
# Open multiple files in tabs
|
|
138
|
+
dataframe-textual file1.csv file2.csv file3.csv
|
|
139
|
+
|
|
140
|
+
# Open multiple sheets in tabs in an Excel file
|
|
141
|
+
dataframe-textual file.xlsx
|
|
142
|
+
|
|
143
|
+
# Mix files and stdin (file opens first, then read from stdin)
|
|
144
|
+
dataframe-textual data1.csv < data2.csv
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
When multiple files are opened:
|
|
148
|
+
- Each file appears as a separate tab at the top
|
|
149
|
+
- Switch between tabs using `>` (next) or `<` (previous)
|
|
150
|
+
- Open additional files with `Ctrl+O`
|
|
151
|
+
- Close the current tab with `Ctrl+W`
|
|
152
|
+
- Each file maintains its own state (sort order, selections, history, etc.)
|
|
153
|
+
- Edits and filters are independent per file
|
|
154
|
+
|
|
155
|
+
## Keyboard Shortcuts
|
|
156
|
+
|
|
157
|
+
### App-Level Controls
|
|
158
|
+
|
|
159
|
+
#### File & Tab Management
|
|
160
|
+
|
|
161
|
+
| Key | Action |
|
|
162
|
+
|-----|--------|
|
|
163
|
+
| `Ctrl+O` | Open new CSV file in a new tab |
|
|
164
|
+
| `Ctrl+W` | Close current tab |
|
|
165
|
+
| `Ctrl+Shift+S` | Save all open tabs to Excel file |
|
|
166
|
+
| `>` or `b` | Move to next tab |
|
|
167
|
+
| `<` | Move to previous tab |
|
|
168
|
+
| `B` | Toggle tab bar visibility |
|
|
169
|
+
| `q` | Quit the application |
|
|
170
|
+
|
|
171
|
+
#### View & Settings
|
|
172
|
+
|
|
173
|
+
| Key | Action |
|
|
174
|
+
|-----|--------|
|
|
175
|
+
| `?` or `h` | Toggle help panel (context-sensitive) |
|
|
176
|
+
| `k` | Cycle through themes |
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### Table-Level Controls
|
|
181
|
+
|
|
182
|
+
#### Navigation
|
|
183
|
+
|
|
184
|
+
| Key | Action |
|
|
185
|
+
|-----|--------|
|
|
186
|
+
| `g` | Jump to first row |
|
|
187
|
+
| `G` | Jump to last row (loads all remaining rows) |
|
|
188
|
+
| `↑` / `↓` | Move up/down one row |
|
|
189
|
+
| `←` / `→` | Move left/right one column |
|
|
190
|
+
| `PageDown` / `PageUp` | Scroll down/up |
|
|
191
|
+
| Arrow keys | Navigate the table |
|
|
192
|
+
|
|
193
|
+
#### Viewing & Display
|
|
194
|
+
|
|
195
|
+
| Key | Action |
|
|
196
|
+
|-----|--------|
|
|
197
|
+
| `Enter` | View full details of current row in modal |
|
|
198
|
+
| `F` | Show frequency distribution for column |
|
|
199
|
+
| `C` | Cycle cursor type: cell → row → column → cell |
|
|
200
|
+
| `#` | Toggle row labels visibility |
|
|
201
|
+
|
|
202
|
+
#### Data Editing
|
|
203
|
+
|
|
204
|
+
| Key | Action |
|
|
205
|
+
|-----|--------|
|
|
206
|
+
| `e` | Edit current cell (respects data type) |
|
|
207
|
+
| `d` | Delete current row |
|
|
208
|
+
| `-` | Delete current column |
|
|
209
|
+
|
|
210
|
+
#### Searching & Filtering
|
|
211
|
+
|
|
212
|
+
| Key | Action |
|
|
213
|
+
|-----|--------|
|
|
214
|
+
| `\|` (pipe) | Search in current column (case-insensitive) |
|
|
215
|
+
| `/` (slash) | Global search across all columns |
|
|
216
|
+
| `\` | Search current column using cell value |
|
|
217
|
+
| `s` | Select/deselect current row |
|
|
218
|
+
| `t` | Toggle highlighting of all selected rows (invert) |
|
|
219
|
+
| `T` | Clear all selected rows |
|
|
220
|
+
| `"` (quote) | Filter to show only selected rows |
|
|
221
|
+
| `v` | Filter by selected rows (if any) or current cell value |
|
|
222
|
+
| `V` | Filter by expression (Polars expression syntax) |
|
|
223
|
+
|
|
224
|
+
#### Sorting
|
|
225
|
+
|
|
226
|
+
| Key | Action |
|
|
227
|
+
|-----|--------|
|
|
228
|
+
| `[` | Sort current column ascending |
|
|
229
|
+
| `]` | Sort current column descending |
|
|
230
|
+
|
|
231
|
+
#### Reordering
|
|
232
|
+
|
|
233
|
+
| Key | Action |
|
|
234
|
+
|-----|--------|
|
|
235
|
+
| `Shift+↑` | Move current row up |
|
|
236
|
+
| `Shift+↓` | Move current row down |
|
|
237
|
+
| `Shift+←` | Move current column left |
|
|
238
|
+
| `Shift+→` | Move current column right |
|
|
239
|
+
|
|
240
|
+
#### Data Management
|
|
241
|
+
|
|
242
|
+
| Key | Action |
|
|
243
|
+
|-----|--------|
|
|
244
|
+
| `f` | Freeze rows and columns |
|
|
245
|
+
| `c` | Copy current cell to clipboard |
|
|
246
|
+
| `Ctrl+S` | Save current tab to CSV/TSV file |
|
|
247
|
+
| `u` | Undo last action |
|
|
248
|
+
| `U` | Reset to original data |
|
|
249
|
+
|
|
250
|
+
#### Modal Interactions
|
|
251
|
+
|
|
252
|
+
**In Frequency Distribution Modal** (opened with `F`):
|
|
253
|
+
- `[` / `]` - Sort frequency table
|
|
254
|
+
- `v` - Filter main table to selected value
|
|
255
|
+
- `"` - Highlight rows with selected value
|
|
256
|
+
- `q` / `Escape` - Close modal
|
|
257
|
+
|
|
258
|
+
**In Row Detail Modal** (opened with `Enter`):
|
|
259
|
+
- `v` - Filter main table to selected column value
|
|
260
|
+
- `"` - Highlight rows with selected column value
|
|
261
|
+
- `q` / `Escape` - Close modal
|
|
262
|
+
|
|
263
|
+
**Tip**: Press `?` or `h` to open the context-sensitive help panel which displays all available shortcuts based on your current focus.
|
|
264
|
+
|
|
265
|
+
## Features in Detail
|
|
266
|
+
|
|
267
|
+
### 1. Color-Coded Data Types
|
|
268
|
+
|
|
269
|
+
Columns are automatically styled based on their data type:
|
|
270
|
+
- **Int64** (Integers): Cyan text, right-aligned
|
|
271
|
+
- **Float64** (Decimals): Magenta text, right-aligned
|
|
272
|
+
- **String**: Green text, left-aligned
|
|
273
|
+
- **Boolean**: Blue text, centered
|
|
274
|
+
- **Date/Datetime**: Blue text, centered
|
|
275
|
+
|
|
276
|
+
### 2. Row Detail View
|
|
277
|
+
|
|
278
|
+
Press `Enter` on any row to open a modal showing all column values for that row. Useful for examining wide datasets where columns don't fit on screen.
|
|
279
|
+
|
|
280
|
+
**In the Row Detail Modal**:
|
|
281
|
+
- Press `v` to **filter** the main table to show only rows with the selected column value
|
|
282
|
+
- Press `"` to **highlight** all rows containing the selected column value
|
|
283
|
+
- Press `q` or `Escape` to close the modal
|
|
284
|
+
|
|
285
|
+
### 3. Search & Filtering
|
|
286
|
+
|
|
287
|
+
**Column Search** (`|`):
|
|
288
|
+
- Search for values in the current column
|
|
289
|
+
- Case-insensitive substring matching
|
|
290
|
+
- All matching rows are highlighted in red
|
|
291
|
+
- Multiple searches accumulate selections
|
|
292
|
+
|
|
293
|
+
**Global Search** (`/`):
|
|
294
|
+
- Search for a term across all columns simultaneously
|
|
295
|
+
- Cell-level highlighting in red for each matching cell
|
|
296
|
+
- Useful for finding a value anywhere in the dataset
|
|
297
|
+
- Automatically loads rows if matches extend beyond visible area
|
|
298
|
+
- Type-aware matching: converts values to strings before comparing
|
|
299
|
+
|
|
300
|
+
**Cell-Value Search** (`\`):
|
|
301
|
+
- Automatically search using the current cell's value
|
|
302
|
+
- Quick way to find all occurrences of a value
|
|
303
|
+
|
|
304
|
+
**Row Filtering** (`"`):
|
|
305
|
+
- Display only the selected (highlighted) rows
|
|
306
|
+
- Other rows are hidden but preserved
|
|
307
|
+
- Use undo (`u`) to restore
|
|
308
|
+
|
|
309
|
+
### 4. Filter by Expression
|
|
310
|
+
|
|
311
|
+
Press `f` to open a powerful filter expression dialog. This allows you to write complex filter conditions using a special syntax:
|
|
312
|
+
|
|
313
|
+
**Column References:**
|
|
314
|
+
- `$_` - Current column (based on cursor position)
|
|
315
|
+
- `$1`, `$2`, etc. - Column by 1-based index
|
|
316
|
+
- `$age`, `$salary` - Column by name
|
|
317
|
+
|
|
318
|
+
**Operators:**
|
|
319
|
+
- Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`
|
|
320
|
+
- Logical: `&&` (AND), `||` (OR)
|
|
321
|
+
- Arithmetic: `+`, `-`, `*`, `/`, `%`
|
|
322
|
+
|
|
323
|
+
**Examples:**
|
|
324
|
+
- `$_ > 50` - Current column greater than 50
|
|
325
|
+
- `$salary >= 100000` - Salary at least 100,000
|
|
326
|
+
- `$age < 30 && $status == 'active'` - Age less than 30 AND status is active
|
|
327
|
+
- `$name == 'Alice' || $name == 'Bob'` - Name is Alice or Bob
|
|
328
|
+
- `$salary / 1000 >= 50` - Salary divided by 1,000 is at least 50
|
|
329
|
+
|
|
330
|
+
See [FILTER_EXPRESSION_GUIDE.md](FILTER_EXPRESSION_GUIDE.md) for comprehensive syntax documentation.
|
|
331
|
+
|
|
332
|
+
### 5. Sorting
|
|
333
|
+
|
|
334
|
+
- Press `[` to sort current column ascending
|
|
335
|
+
- Press `]` to sort current column descending
|
|
336
|
+
- Multi-column sorting supported (press multiple times on different columns)
|
|
337
|
+
- Press same key twice to toggle direction
|
|
338
|
+
- Frequency view (`F`) shows value distribution with optional sorting
|
|
339
|
+
|
|
340
|
+
### 6. Frequency Distribution
|
|
341
|
+
|
|
342
|
+
Press `F` to see how many times each value appears in the current column. The modal shows:
|
|
343
|
+
- Value
|
|
344
|
+
- Count
|
|
345
|
+
- Percentage of total
|
|
346
|
+
- **Total row** at the bottom
|
|
347
|
+
|
|
348
|
+
**In the Frequency Table**:
|
|
349
|
+
- Press `[` and `]` to sort by any column (value, count, or percentage)
|
|
350
|
+
- Press `v` to **filter** the main table to show only rows with the selected value
|
|
351
|
+
- Press `"` to **highlight** all rows containing the selected value
|
|
352
|
+
- Press `q` or `Escape` to close the frequency table
|
|
353
|
+
|
|
354
|
+
This is useful for:
|
|
355
|
+
- Understanding value distributions
|
|
356
|
+
- Quickly filtering to specific values
|
|
357
|
+
- Identifying rare or common values
|
|
358
|
+
- Finding the most/least frequent entries
|
|
359
|
+
|
|
360
|
+
### 7. Data Editing
|
|
361
|
+
|
|
362
|
+
**Edit Cell** (`e`):
|
|
363
|
+
- Opens modal for editing current cell
|
|
364
|
+
- Validates input based on column data type
|
|
365
|
+
- Shows column name and type
|
|
366
|
+
- Integer, number, and text inputs available
|
|
367
|
+
|
|
368
|
+
**Delete Row** (`d`):
|
|
369
|
+
- Delete single row at cursor
|
|
370
|
+
- Or delete all selected rows at once
|
|
371
|
+
- Deleted rows are marked internally but kept for undo
|
|
372
|
+
|
|
373
|
+
**Delete Column** (`-`):
|
|
374
|
+
- Removes the entire column from view and dataframe
|
|
375
|
+
- Cannot be undone directly (use undo feature)
|
|
376
|
+
|
|
377
|
+
### 8. Column & Row Reordering
|
|
378
|
+
|
|
379
|
+
**Move Columns**: `Shift+←` and `Shift+→`
|
|
380
|
+
- Swaps adjacent columns
|
|
381
|
+
- Reorder is preserved when saving
|
|
382
|
+
|
|
383
|
+
**Move Rows**: `Shift+↑` and `Shift+↓`
|
|
384
|
+
- Swaps adjacent rows
|
|
385
|
+
- Visual reordering without affecting data
|
|
386
|
+
|
|
387
|
+
### 9. Pin Rows and Columns
|
|
388
|
+
|
|
389
|
+
Press `f` to open the pin dialog:
|
|
390
|
+
- Enter number of fixed rows: keeps top rows visible while scrolling
|
|
391
|
+
- Enter two numbers: `<rows> <columns>` (space-separated)
|
|
392
|
+
- Example: `2 3` pins top 2 rows and left 3 columns
|
|
393
|
+
|
|
394
|
+
### 10. Save to CSV
|
|
395
|
+
|
|
396
|
+
Press `Ctrl+S` to save:
|
|
397
|
+
- Save filtered, edited, or sorted data back to CSV
|
|
398
|
+
- Choose filename in modal dialog
|
|
399
|
+
- Confirm if file already exists
|
|
400
|
+
- Automatic .tsv or .csv detection
|
|
401
|
+
|
|
402
|
+
### 11. Undo/Redo
|
|
403
|
+
|
|
404
|
+
Press `u` to undo:
|
|
405
|
+
- Reverts last action with full state restoration
|
|
406
|
+
- Works for edits, deletions, sorts, searches, etc.
|
|
407
|
+
- Shows description of reverted action
|
|
408
|
+
|
|
409
|
+
### 12. Cursor Type Cycling
|
|
410
|
+
|
|
411
|
+
Press `C` to cycle through selection modes:
|
|
412
|
+
1. **Cell mode**: Highlight individual cell (and its row/column headers)
|
|
413
|
+
2. **Row mode**: Highlight entire row
|
|
414
|
+
3. **Column mode**: Highlight entire column
|
|
415
|
+
|
|
416
|
+
Visual feedback shows which mode is active.
|
|
417
|
+
|
|
418
|
+
### 13. Clipboard Operations
|
|
419
|
+
|
|
420
|
+
Press `c` to copy:
|
|
421
|
+
- Copies current cell value to system clipboard
|
|
422
|
+
- Works on macOS (`pbcopy`) and Linux (`xclip`)
|
|
423
|
+
- Shows confirmation notification
|
|
424
|
+
|
|
425
|
+
## Data Type Support
|
|
426
|
+
|
|
427
|
+
- **Int64, Int32, UInt32**: Integer values
|
|
428
|
+
- **Float64, Float32**: Decimal numbers (shown with 4 significant figures)
|
|
429
|
+
- **String**: Text data
|
|
430
|
+
- **Boolean**: True/False values
|
|
431
|
+
- **Date**: ISO date format (YYYY-MM-DD)
|
|
432
|
+
- **Datetime**: ISO datetime format
|
|
433
|
+
- **Null values**: Displayed as `-`
|
|
434
|
+
|
|
435
|
+
## Examples
|
|
436
|
+
|
|
437
|
+
### Single File Examples
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
# View Pokemon dataset
|
|
441
|
+
dataframe-textual pokemon.csv
|
|
442
|
+
|
|
443
|
+
# View Titanic dataset with analysis
|
|
444
|
+
dataframe-textual titanic.csv
|
|
445
|
+
|
|
446
|
+
# Filter and view specific columns
|
|
447
|
+
cut -d',' -f1,2,3 pokemon.csv | dataframe-textual
|
|
448
|
+
|
|
449
|
+
# View with grep filter (then use | search in viewer)
|
|
450
|
+
grep "Fire" pokemon.csv | dataframe-textual
|
|
451
|
+
|
|
452
|
+
# Chain with other commands
|
|
453
|
+
cat data.csv | sort -t',' -k2 | dataframe-textual
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Multi-File Examples
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
# Compare two versions of a dataset
|
|
460
|
+
dataframe-textual pokemon_v1.csv pokemon_v2.csv
|
|
461
|
+
|
|
462
|
+
# Side-by-side analysis of related files
|
|
463
|
+
dataframe-textual sales_2022.csv sales_2023.csv forecast_2024.csv
|
|
464
|
+
|
|
465
|
+
# Cross-reference datasets
|
|
466
|
+
dataframe-textual customers.csv orders.csv products.csv
|
|
467
|
+
|
|
468
|
+
# Start with one file, open others using Ctrl+O
|
|
469
|
+
dataframe-textual initial_data.csv
|
|
470
|
+
# Then press Ctrl+O to open more files interactively
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
### Advanced Workflows
|
|
474
|
+
|
|
475
|
+
```bash
|
|
476
|
+
# Start with a filtered file, compare with original
|
|
477
|
+
grep "status=active" data.csv > filtered.csv
|
|
478
|
+
dataframe-textual data.csv filtered.csv
|
|
479
|
+
# Now compare the full dataset with the filtered version in separate tabs
|
|
480
|
+
|
|
481
|
+
# Multi-step analysis
|
|
482
|
+
# 1. Open multiple related CSVs
|
|
483
|
+
# 2. Use Ctrl+O to open additional files as you discover relationships
|
|
484
|
+
# 3. Each tab maintains independent sort/filter/search state
|
|
485
|
+
# 4. Use Ctrl+W to close tabs when done analyzing
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
## Performance
|
|
489
|
+
|
|
490
|
+
- **Lazy loading**: Only loads visible rows + 10 rows ahead
|
|
491
|
+
- **Efficient sorting**: Uses Polars' optimized sort algorithms
|
|
492
|
+
- **Smooth scrolling**: No lag when paging through large files
|
|
493
|
+
- **Memory efficient**: Handles datasets larger than RAM
|
|
494
|
+
|
|
495
|
+
Tested with:
|
|
496
|
+
- 10,000+ row CSV files
|
|
497
|
+
- Wide datasets (100+ columns)
|
|
498
|
+
- Various data types and sizes
|
|
499
|
+
|
|
500
|
+
## Dependencies
|
|
501
|
+
|
|
502
|
+
- **polars**: Fast DataFrame library for CSV processing
|
|
503
|
+
- **textual**: Terminal UI framework
|
|
504
|
+
- **rich**: Rich text and formatting in the terminal
|
|
505
|
+
|
|
506
|
+
## Architecture Overview
|
|
507
|
+
|
|
508
|
+
### Single-Table Design
|
|
509
|
+
|
|
510
|
+
The core of the application is built around the `DataFrameTable` widget:
|
|
511
|
+
|
|
512
|
+
- **Self-contained**: Each table instance maintains its own complete state (13 independent variables)
|
|
513
|
+
- **Fully autonomous**: All operations (editing, sorting, filtering, searching) are handled within the table
|
|
514
|
+
- **Event-driven**: Each table owns and handles its keyboard events
|
|
515
|
+
- **Backward compatible**: Works identically in single-file mode
|
|
516
|
+
|
|
517
|
+
### Multi-Table Design
|
|
518
|
+
|
|
519
|
+
The `DataFrameApp` coordinates multiple independent `DataFrameTable` instances:
|
|
520
|
+
|
|
521
|
+
- **Tab-based interface**: Uses Textual's `TabbedContent` for tab management
|
|
522
|
+
- **Independent state**: Each tab has completely separate state (sort order, selections, history)
|
|
523
|
+
- **Seamless switching**: Switch between files without losing context or state
|
|
524
|
+
- **File management**: Open/close files dynamically without restarting the application
|
|
525
|
+
|
|
526
|
+
### State Isolation
|
|
527
|
+
|
|
528
|
+
Each `DataFrameTable` instance owns:
|
|
529
|
+
- DataFrame (`self.df`)
|
|
530
|
+
- Sorted columns (`self.sorted_columns`)
|
|
531
|
+
- Selected rows (`self.selected_rows`)
|
|
532
|
+
- Edit history (`self.histories`)
|
|
533
|
+
- Cursor state (position, type)
|
|
534
|
+
- Search/filter state
|
|
535
|
+
- And 8 more internal state variables
|
|
536
|
+
|
|
537
|
+
This ensures perfect isolation between tabs with zero cross-contamination.
|
|
538
|
+
|
|
539
|
+
## Requirements
|
|
540
|
+
|
|
541
|
+
- Python 3.11+
|
|
542
|
+
- POSIX-compatible terminal (macOS, Linux, WSL)
|
|
543
|
+
- Terminal supporting ANSI escape sequences and mouse events
|
|
544
|
+
|
|
545
|
+
## Acknowledgments
|
|
546
|
+
|
|
547
|
+
- Inspired by [VisiData](https://visidata.org/)
|
|
548
|
+
- Built with [Textual](https://textual.textualize.io/), [Polars](https://www.pola.rs/), and [Rich](https://rich.readthedocs.io/)
|
|
549
|
+
- All code created through iterative development
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
dataframe_textual/__init__.py,sha256=uzB3bjlbm8JbsjxEgwqvPcYERktm3F9d9Op_6cWJ1sk,853
|
|
2
|
+
dataframe_textual/__main__.py,sha256=LPLyZcv4hAFfF3hUt1S2dtZOqaAZnlguicgwiDrtXgk,1349
|
|
3
|
+
dataframe_textual/common.py,sha256=3zzhI__F_hoOFDRe-wt-oTfMDFik1ohraIa6rXcVit8,6357
|
|
4
|
+
dataframe_textual/data_frame_help_panel.py,sha256=SQ2lulb1SPxItR9tMvIgOzzeCcW9SB1rRojAcwZ7Vis,2730
|
|
5
|
+
dataframe_textual/data_frame_table.py,sha256=u_gMc-U57efgIRoCfOR65clieK7M7FUg45jjUb06V_w,50079
|
|
6
|
+
dataframe_textual/data_frame_viewer.py,sha256=BP-pCYIG5bEDFkUmUyA3sxWc3z1zI_viClDZlT-s_uE,11715
|
|
7
|
+
dataframe_textual/table_screen.py,sha256=Pq6aM-vntDxLj1r5Uzke6_pzbuhO-VrX_V12ezwm3uM,10588
|
|
8
|
+
dataframe_textual/yes_no_screen.py,sha256=z7MEVTMepFuGWFIthhQlAT3m69D6lgIl4tb2_oJAWWQ,13207
|
|
9
|
+
dataframe_textual-0.2.1.dist-info/METADATA,sha256=jACe80kpq-4nzJZ0Ra5MwSnezCOMbJb4hTe9obRUWaI,17131
|
|
10
|
+
dataframe_textual-0.2.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
+
dataframe_textual-0.2.1.dist-info/entry_points.txt,sha256=FkXDHVYYtGud6F2Jm2X9OMFAuFrSflNfgcNP5c2469M,70
|
|
12
|
+
dataframe_textual-0.2.1.dist-info/licenses/LICENSE,sha256=AVTg0gk1X-LHI-nnHlAMDQetrwuDZK4eypgSMDO46Yc,1069
|
|
13
|
+
dataframe_textual-0.2.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Tiejun Cheng
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|