cicsim 0.2.0__tar.gz → 0.2.2__tar.gz

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.
Files changed (36) hide show
  1. {cicsim-0.2.0 → cicsim-0.2.2}/PKG-INFO +49 -17
  2. {cicsim-0.2.0 → cicsim-0.2.2}/README.md +48 -16
  3. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cicsim.py +106 -6
  4. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdwave.py +69 -2
  5. cicsim-0.2.2/cicsim/cmdwave_pg.py +2188 -0
  6. cicsim-0.2.2/cicsim/pivot.py +240 -0
  7. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/wavebrowser.py +6 -0
  8. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/wavefiles.py +70 -8
  9. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/wavegraph.py +31 -0
  10. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim.egg-info/PKG-INFO +49 -17
  11. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim.egg-info/SOURCES.txt +1 -0
  12. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim.egg-info/entry_points.txt +1 -0
  13. {cicsim-0.2.0 → cicsim-0.2.2}/pyproject.toml +2 -1
  14. cicsim-0.2.0/cicsim/cmdwave_pg.py +0 -1026
  15. {cicsim-0.2.0 → cicsim-0.2.2}/LICENSE +0 -0
  16. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/__init__.py +0 -0
  17. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cdsconf.py +0 -0
  18. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdarchive.py +0 -0
  19. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdip.py +0 -0
  20. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdresults.py +0 -0
  21. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdrun.py +0 -0
  22. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdrunng.py +0 -0
  23. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdsimdir.py +0 -0
  24. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdsimdirng.py +0 -0
  25. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdspider.py +0 -0
  26. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/cmdsummary.py +0 -0
  27. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/command.py +0 -0
  28. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/ngraw.py +0 -0
  29. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/plot.py +0 -0
  30. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/simcalc.py +0 -0
  31. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/spec.py +0 -0
  32. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim/spiceparser.py +0 -0
  33. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim.egg-info/dependency_links.txt +0 -0
  34. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim.egg-info/requires.txt +0 -0
  35. {cicsim-0.2.0 → cicsim-0.2.2}/cicsim.egg-info/top_level.txt +0 -0
  36. {cicsim-0.2.0 → cicsim-0.2.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cicsim
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary: Custom IC Creator Simulation Tools
5
5
  Author-email: Carsten Wulff <carsten@wulff.no>
6
6
  License: MIT
@@ -67,8 +67,8 @@ This is a script package I use to control ngspice, it can
67
67
  | 0.1.17 | Updated docs and spec |
68
68
  | 0.1.18 | Code quality overhaul: replaced os.system with subprocess, replaced eval with ast.literal_eval, migrated to Python logging module, added documentation for all CLI commands, removed setup.py in favor of pyproject.toml |
69
69
  | 0.1.19 | Wave viewer overhaul: measurement cursors (A/B) with delta readout, scroll-wheel zoom, keyboard shortcuts, engineering notation on axes (EngFormatter), Export PDF, legend toggle, regex search tooltip, Help menu. Fixed pyproject.toml license for Python 3.8. Added unit tests |
70
-
71
-
70
+ | 0.2.0 | New pyqtgraph backend (`--backend pg`): hierarchical wave browser, automatic dual Y-axes, GPU-accelerated rendering, closeable tabs, analysis functions (FFT/PSD, Histogram, Differentiate, X vs Y). Fixed AC analysis complex data plotting |
71
+ | 0.2.1 | Multi-format file support: CSV, TSV, Excel, JSON, Parquet, Feather, HDF5, Pickle, and more. `--sheet` option for Excel files. String/categorical axis support with rotated labels. Gradient (dy/dx) and slope in cursor readout. Double-click to plot. Regex signal picker for X vs Y |
72
72
 
73
73
 
74
74
  # Install this module
@@ -90,16 +90,26 @@ Head over to [Sky130nm tutorial](https://analogicus.com/aic2026/sky130nm_tutoria
90
90
 
91
91
  # Get started with waveform viewer
92
92
 
93
- Make sure you install a python version with tk. On my mac it was
93
+ A standalone `cicwave` command is available that defaults to the pyqtgraph
94
+ backend. It is equivalent to `cicsim wave --backend pg`.
94
95
 
95
96
  ``` bash
96
- brew install python-tk
97
+ # Standalone command (defaults to pg backend)
98
+ cicwave output_tran/tran_SchGtTtKffVh_*
99
+
100
+ # Or via cicsim subcommand
101
+ cicsim wave output_tran/tran_SchGtTtKffVh_* # tkinter backend
102
+ cicsim wave --backend pg output_tran/tran_SchGtTtKffVh_* # pyqtgraph backend
97
103
  ```
98
104
 
99
- Once installed, I do
105
+ Supported file formats: `.raw` (ngspice), `.csv`, `.tsv`, `.txt`, `.xlsx`,
106
+ `.xls`, `.ods`, `.json`, `.parquet`, `.feather`, `.h5`, `.hdf5`, `.pkl`,
107
+ `.pickle`, `.html`, `.xml`, `.fwf`, `.dta`, `.sas7bdat`, `.sav`.
100
108
 
101
109
  ``` bash
102
- cicsim wave output_tran/tran_SchGtTtKffVh_*
110
+ # Open CSV / Excel files
111
+ cicwave data.csv
112
+ cicwave data.xlsx --sheet "Sheet2"
103
113
  ```
104
114
 
105
115
  ![](wave.png)
@@ -108,25 +118,33 @@ cicsim wave output_tran/tran_SchGtTtKffVh_*
108
118
 
109
119
  | Key | Action |
110
120
  |:-------------|:-------------------------------|
111
- | `a` | Set cursor A at mouse position |
112
- | `b` | Set cursor B at mouse position |
121
+ | `A` | Set cursor A at mouse position |
122
+ | `B` | Set cursor B at mouse position |
113
123
  | `Escape` | Clear cursors |
114
- | `f` | Auto scale (fit) |
115
- | `r` | Reload all waves |
116
- | `l` | Toggle legend |
117
- | `Delete` | Remove selected wave |
118
- | `Ctrl+O` | Open raw file |
124
+ | `F` | Auto scale (fit) |
125
+ | `R` | Reload all waves |
126
+ | `L` | Toggle legend |
127
+ | `Ctrl+O` | Open file |
119
128
  | `Ctrl+P` | Export PDF |
120
- | `Ctrl+N` | New plot tab |
121
- | `Ctrl+A` | Add axis |
129
+ | `Ctrl+N` | New plot tab (pg) |
130
+ | `Ctrl+W` | Close current tab (pg) |
122
131
  | `Ctrl+Q` | Quit |
123
132
  | Scroll | Zoom x-axis |
124
133
  | Shift+Scroll | Zoom y-axis |
125
134
 
135
+ ## Analysis functions (pg backend, right-click menu)
136
+
137
+ | Function | Description |
138
+ |:---------|:-----------|
139
+ | FFT / PSD | Power spectral density in dB with Hanning window |
140
+ | Histogram | Distribution with Gaussian fit, mean and sigma |
141
+ | Differentiate | Numerical dy/dx |
142
+ | X vs Y | Parametric plot with regex signal picker |
143
+
126
144
 
127
145
  # Commands
128
146
 
129
- ```
147
+ ```
130
148
  Usage: cicsim [OPTIONS] COMMAND [ARGS]...
131
149
 
132
150
  Custom Integrated Circuit Simulation
@@ -151,3 +169,17 @@ Commands:
151
169
  template Run an IP template with <options> YAML file
152
170
  wave Open waveform viewer
153
171
  ```
172
+
173
+ A standalone command is also available:
174
+
175
+ ```
176
+ Usage: cicwave [OPTIONS] [FILES]...
177
+
178
+ Waveform viewer (standalone). Defaults to the pyqtgraph backend.
179
+
180
+ Options:
181
+ --x TEXT Specify x-axis
182
+ --backend [tk|pg] GUI backend (default: pg)
183
+ --sheet TEXT Sheet name for Excel files
184
+ --help Show this message and exit.
185
+ ```
@@ -35,8 +35,8 @@ This is a script package I use to control ngspice, it can
35
35
  | 0.1.17 | Updated docs and spec |
36
36
  | 0.1.18 | Code quality overhaul: replaced os.system with subprocess, replaced eval with ast.literal_eval, migrated to Python logging module, added documentation for all CLI commands, removed setup.py in favor of pyproject.toml |
37
37
  | 0.1.19 | Wave viewer overhaul: measurement cursors (A/B) with delta readout, scroll-wheel zoom, keyboard shortcuts, engineering notation on axes (EngFormatter), Export PDF, legend toggle, regex search tooltip, Help menu. Fixed pyproject.toml license for Python 3.8. Added unit tests |
38
-
39
-
38
+ | 0.2.0 | New pyqtgraph backend (`--backend pg`): hierarchical wave browser, automatic dual Y-axes, GPU-accelerated rendering, closeable tabs, analysis functions (FFT/PSD, Histogram, Differentiate, X vs Y). Fixed AC analysis complex data plotting |
39
+ | 0.2.1 | Multi-format file support: CSV, TSV, Excel, JSON, Parquet, Feather, HDF5, Pickle, and more. `--sheet` option for Excel files. String/categorical axis support with rotated labels. Gradient (dy/dx) and slope in cursor readout. Double-click to plot. Regex signal picker for X vs Y |
40
40
 
41
41
 
42
42
  # Install this module
@@ -58,16 +58,26 @@ Head over to [Sky130nm tutorial](https://analogicus.com/aic2026/sky130nm_tutoria
58
58
 
59
59
  # Get started with waveform viewer
60
60
 
61
- Make sure you install a python version with tk. On my mac it was
61
+ A standalone `cicwave` command is available that defaults to the pyqtgraph
62
+ backend. It is equivalent to `cicsim wave --backend pg`.
62
63
 
63
64
  ``` bash
64
- brew install python-tk
65
+ # Standalone command (defaults to pg backend)
66
+ cicwave output_tran/tran_SchGtTtKffVh_*
67
+
68
+ # Or via cicsim subcommand
69
+ cicsim wave output_tran/tran_SchGtTtKffVh_* # tkinter backend
70
+ cicsim wave --backend pg output_tran/tran_SchGtTtKffVh_* # pyqtgraph backend
65
71
  ```
66
72
 
67
- Once installed, I do
73
+ Supported file formats: `.raw` (ngspice), `.csv`, `.tsv`, `.txt`, `.xlsx`,
74
+ `.xls`, `.ods`, `.json`, `.parquet`, `.feather`, `.h5`, `.hdf5`, `.pkl`,
75
+ `.pickle`, `.html`, `.xml`, `.fwf`, `.dta`, `.sas7bdat`, `.sav`.
68
76
 
69
77
  ``` bash
70
- cicsim wave output_tran/tran_SchGtTtKffVh_*
78
+ # Open CSV / Excel files
79
+ cicwave data.csv
80
+ cicwave data.xlsx --sheet "Sheet2"
71
81
  ```
72
82
 
73
83
  ![](wave.png)
@@ -76,25 +86,33 @@ cicsim wave output_tran/tran_SchGtTtKffVh_*
76
86
 
77
87
  | Key | Action |
78
88
  |:-------------|:-------------------------------|
79
- | `a` | Set cursor A at mouse position |
80
- | `b` | Set cursor B at mouse position |
89
+ | `A` | Set cursor A at mouse position |
90
+ | `B` | Set cursor B at mouse position |
81
91
  | `Escape` | Clear cursors |
82
- | `f` | Auto scale (fit) |
83
- | `r` | Reload all waves |
84
- | `l` | Toggle legend |
85
- | `Delete` | Remove selected wave |
86
- | `Ctrl+O` | Open raw file |
92
+ | `F` | Auto scale (fit) |
93
+ | `R` | Reload all waves |
94
+ | `L` | Toggle legend |
95
+ | `Ctrl+O` | Open file |
87
96
  | `Ctrl+P` | Export PDF |
88
- | `Ctrl+N` | New plot tab |
89
- | `Ctrl+A` | Add axis |
97
+ | `Ctrl+N` | New plot tab (pg) |
98
+ | `Ctrl+W` | Close current tab (pg) |
90
99
  | `Ctrl+Q` | Quit |
91
100
  | Scroll | Zoom x-axis |
92
101
  | Shift+Scroll | Zoom y-axis |
93
102
 
103
+ ## Analysis functions (pg backend, right-click menu)
104
+
105
+ | Function | Description |
106
+ |:---------|:-----------|
107
+ | FFT / PSD | Power spectral density in dB with Hanning window |
108
+ | Histogram | Distribution with Gaussian fit, mean and sigma |
109
+ | Differentiate | Numerical dy/dx |
110
+ | X vs Y | Parametric plot with regex signal picker |
111
+
94
112
 
95
113
  # Commands
96
114
 
97
- ```
115
+ ```
98
116
  Usage: cicsim [OPTIONS] COMMAND [ARGS]...
99
117
 
100
118
  Custom Integrated Circuit Simulation
@@ -119,3 +137,17 @@ Commands:
119
137
  template Run an IP template with <options> YAML file
120
138
  wave Open waveform viewer
121
139
  ```
140
+
141
+ A standalone command is also available:
142
+
143
+ ```
144
+ Usage: cicwave [OPTIONS] [FILES]...
145
+
146
+ Waveform viewer (standalone). Defaults to the pyqtgraph backend.
147
+
148
+ Options:
149
+ --x TEXT Specify x-axis
150
+ --backend [tk|pg] GUI backend (default: pg)
151
+ --sheet TEXT Sheet name for Excel files
152
+ --help Show this message and exit.
153
+ ```
@@ -94,7 +94,12 @@ def archive(ctx,name,runfiles):
94
94
  @click.option("--x",default=None,help="Specify x-axis")
95
95
  @click.option("--backend",default="tk",type=click.Choice(["tk","pg"]),
96
96
  help="GUI backend: tk (tkinter+matplotlib) or pg (PySide6+pyqtgraph)")
97
- def wave(files,x,backend):
97
+ @click.option("--sheet",default=None,help="Sheet name for Excel files (default: first sheet)")
98
+ @click.option("--pivot",default=None,help="Pivot spec file (YAML/JSON)")
99
+ @click.option("--pivot-info",is_flag=True,default=False,help="Print pivot dimensions and exit")
100
+ @click.option("--session",default=None,help="Load session file (.cicwave.yaml)")
101
+ @click.option("--export",default=None,help="Export plot to file (PDF/PNG/SVG) and exit")
102
+ def wave(files,x,backend,sheet,pivot,pivot_info,session,export):
98
103
  """Open waveform viewer.
99
104
 
100
105
  Interactive waveform viewer for SPICE simulation results (.raw files).
@@ -107,10 +112,19 @@ def wave(files,x,backend):
107
112
  F Auto scale (fit all)
108
113
  R Reload all waveforms
109
114
  L Toggle legend
115
+ Shift+Z Zoom in
116
+ Ctrl+Z Zoom out
110
117
  Ctrl+O Open raw file
118
+ Ctrl+S Save session
111
119
  Ctrl+P Export to PDF
112
120
  Ctrl+N New plot tab (pg backend)
121
+ Ctrl+L Set axis labels
122
+ Ctrl+T Add annotation
113
123
  Ctrl+Q Quit
124
+ Ctrl+Up Increase line width
125
+ Ctrl+Down Decrease line width
126
+ Ctrl+= Increase font size
127
+ Ctrl+- Decrease font size
114
128
 
115
129
  \b
116
130
  Mouse (pg backend):
@@ -122,8 +136,8 @@ def wave(files,x,backend):
122
136
 
123
137
  \b
124
138
  Browser (pg backend):
125
- Click wave Add to plot
126
- Right-click Remove from plot
139
+ Double-click Add to plot
140
+ Right-click Context menu (plot, remove, style, analysis)
127
141
  Flat checkbox Toggle hierarchy / flat list
128
142
 
129
143
  \b
@@ -132,8 +146,44 @@ def wave(files,x,backend):
132
146
  pg Uses PySide6 + pyqtgraph. Install: pip install cicsim[pg]
133
147
  Features: hierarchical wave browser, automatic dual Y-axes
134
148
  (left/right by unit), GPU-accelerated rendering.
149
+
150
+ \b
151
+ Pivot:
152
+ --pivot spec.yaml Reshape data using pivot spec before viewing
153
+ --pivot-info Print unique values per pivot dimension and exit
154
+
155
+ \b
156
+ Session:
157
+ --session plot.cicwave.yaml Load saved session
158
+ --export plot.pdf Export to file and exit (no GUI)
159
+ --session s.yaml --export out.pdf Restore session and export
135
160
  """
136
161
 
162
+ _run_wave(files, x, backend, sheet, pivot, pivot_info,
163
+ session_path=session, export_path=export)
164
+
165
+
166
+ def _run_wave(files, x, backend, sheet, pivot_spec=None,
167
+ pivot_info_flag=False, session_path=None, export_path=None):
168
+ if pivot_spec:
169
+ from cicsim.pivot import load_spec, pivot_info, apply_pivot
170
+ from cicsim.wavefiles import WaveFile
171
+ spec = load_spec(pivot_spec)
172
+
173
+ if pivot_info_flag:
174
+ for f in files:
175
+ wf = WaveFile(f, x or "")
176
+ print("--- %s ---" % f)
177
+ print(pivot_info(wf.df, spec))
178
+ print()
179
+ return
180
+
181
+ if not x and spec.get('columns'):
182
+ x = spec['columns']
183
+
184
+ if session_path or export_path:
185
+ backend = "pg"
186
+
137
187
  if backend == "pg":
138
188
  try:
139
189
  from cicsim.cmdwave_pg import CmdWavePg
@@ -151,9 +201,59 @@ def wave(files,x,backend):
151
201
  sys.exit(1)
152
202
  c = cs.CmdWave(x)
153
203
 
154
- for f in files:
155
- c.openFile(f)
156
- c.run()
204
+ if session_path:
205
+ c.win.applySession(session_path)
206
+
207
+ if pivot_spec:
208
+ for f in files:
209
+ wf = WaveFile(f, x or "")
210
+ pivoted = apply_pivot(wf.df, spec)
211
+ name = "pivot(%s)" % os.path.basename(f)
212
+ c.openDataFrame(pivoted, name,
213
+ pivot_spec_path=os.path.abspath(pivot_spec),
214
+ original_path=os.path.abspath(f))
215
+ else:
216
+ for f in files:
217
+ c.openFile(f, sheet_name=sheet)
218
+
219
+ if export_path:
220
+ c.exportAndExit(export_path)
221
+ else:
222
+ c.run()
223
+
224
+
225
+ @click.command()
226
+ @click.argument("files", nargs=-1)
227
+ @click.option("--x", default=None, help="Specify x-axis")
228
+ @click.option("--backend", default="pg", type=click.Choice(["tk", "pg"]),
229
+ help="GUI backend (default: pg)")
230
+ @click.option("--sheet", default=None, help="Sheet name for Excel files (default: first sheet)")
231
+ @click.option("--pivot", default=None, help="Pivot spec file (YAML/JSON)")
232
+ @click.option("--pivot-info", is_flag=True, default=False, help="Print pivot dimensions and exit")
233
+ @click.option("--session", default=None, help="Load session file (.cicwave.yaml)")
234
+ @click.option("--export", default=None, help="Export plot to file (PDF/PNG/SVG) and exit")
235
+ def cicwave(files, x, backend, sheet, pivot, pivot_info, session, export):
236
+ """Waveform viewer (standalone).
237
+
238
+ Shortcut for 'cicsim wave --backend pg'. Opens the pyqtgraph-based
239
+ waveform viewer by default.
240
+
241
+ Supports: .raw, .csv, .tsv, .xlsx, .json, .parquet, .feather, .h5,
242
+ .pkl, and more.
243
+
244
+ \b
245
+ Pivot:
246
+ --pivot spec.yaml Reshape data using pivot spec before viewing
247
+ --pivot-info Print unique values per pivot dimension and exit
248
+
249
+ \b
250
+ Session:
251
+ --session plot.cicwave.yaml Load saved session
252
+ --export plot.pdf Export to file and exit (no GUI)
253
+ --session s.yaml --export out.pdf Restore session and export
254
+ """
255
+ _run_wave(files, x, backend, sheet, pivot, pivot_info,
256
+ session_path=session, export_path=export)
157
257
 
158
258
 
159
259
 
@@ -41,6 +41,9 @@ class CmdWave(cs.Command):
41
41
  menubar.add_cascade(menu=menu_edit, label="Edit")
42
42
  menubar.add_cascade(menu=menu_view, label="View")
43
43
 
44
+ self._line_width = 2
45
+ self._font_size = 9
46
+
44
47
  menu_file.add_command(label="Open Raw Ctrl+O",
45
48
  command=self.openFileDialog)
46
49
  menu_file.add_command(label="Export PDF Ctrl+P",
@@ -58,6 +61,10 @@ class CmdWave(cs.Command):
58
61
  command=self.reloadPlots)
59
62
  menu_edit.add_command(label="Auto Scale F",
60
63
  command=self._autoSize)
64
+ menu_edit.add_command(label="Zoom In Shift+Z",
65
+ command=self._zoomIn)
66
+ menu_edit.add_command(label="Zoom Out Ctrl+Z",
67
+ command=self._zoomOut)
61
68
  menu_edit.add_separator()
62
69
  menu_edit.add_command(label="Remove Selected Delete",
63
70
  command=self._removeLine)
@@ -73,6 +80,16 @@ class CmdWave(cs.Command):
73
80
  menu_view.add_separator()
74
81
  menu_view.add_command(label="Toggle Legend L",
75
82
  command=self._toggleLegend)
83
+ menu_view.add_separator()
84
+ menu_view.add_command(label="Increase Line Width Ctrl+Up",
85
+ command=self._incLineWidth)
86
+ menu_view.add_command(label="Decrease Line Width Ctrl+Down",
87
+ command=self._decLineWidth)
88
+ menu_view.add_separator()
89
+ menu_view.add_command(label="Increase Font Size Ctrl+=",
90
+ command=self._incFontSize)
91
+ menu_view.add_command(label="Decrease Font Size Ctrl+-",
92
+ command=self._decFontSize)
76
93
 
77
94
  menu_help = Menu(menubar)
78
95
  menubar.add_cascade(menu=menu_help, label="Help")
@@ -99,12 +116,19 @@ class CmdWave(cs.Command):
99
116
  self.root.bind('<Delete>', lambda e: self._removeLine())
100
117
  self.root.bind('<Escape>', lambda e: self._clearCursors())
101
118
 
119
+ self.root.bind('<Control-z>', lambda e: self._zoomOut())
120
+ self.root.bind('<Control-Up>', lambda e: self._incLineWidth())
121
+ self.root.bind('<Control-Down>', lambda e: self._decLineWidth())
122
+ self.root.bind('<Control-equal>', lambda e: self._incFontSize())
123
+ self.root.bind('<Control-minus>', lambda e: self._decFontSize())
124
+
102
125
  # Single-key shortcuts — skip when focus is in an Entry widget
103
126
  for key, func in [('r', self.reloadPlots),
104
127
  ('f', self._autoSize),
105
128
  ('a', self._setCursorA),
106
129
  ('b', self._setCursorB),
107
- ('l', self._toggleLegend)]:
130
+ ('l', self._toggleLegend),
131
+ ('Z', self._zoomIn)]:
108
132
  self.root.bind(key, self._make_key_handler(func))
109
133
 
110
134
  def _make_key_handler(self, func):
@@ -126,6 +150,40 @@ class CmdWave(cs.Command):
126
150
  if p:
127
151
  p.autoSize()
128
152
 
153
+ def _zoomIn(self):
154
+ p = self.graph.getCurrentPlot()
155
+ if p:
156
+ p.zoomIn()
157
+
158
+ def _zoomOut(self):
159
+ p = self.graph.getCurrentPlot()
160
+ if p:
161
+ p.zoomOut()
162
+
163
+ def _incLineWidth(self):
164
+ self._line_width = min(self._line_width + 1, 10)
165
+ self._applyLineWidth()
166
+
167
+ def _decLineWidth(self):
168
+ self._line_width = max(self._line_width - 1, 1)
169
+ self._applyLineWidth()
170
+
171
+ def _applyLineWidth(self):
172
+ for t in self.graph.nb.tabs():
173
+ self.graph.nb.nametowidget(t).setLineWidth(self._line_width)
174
+
175
+ def _incFontSize(self):
176
+ self._font_size = min(self._font_size + 1, 24)
177
+ self._applyFontSize()
178
+
179
+ def _decFontSize(self):
180
+ self._font_size = max(self._font_size - 1, 6)
181
+ self._applyFontSize()
182
+
183
+ def _applyFontSize(self):
184
+ for t in self.graph.nb.tabs():
185
+ self.graph.nb.nametowidget(t).setFontSize(self._font_size)
186
+
129
187
  def _removeLine(self):
130
188
  p = self.graph.getCurrentPlot()
131
189
  if p:
@@ -176,6 +234,8 @@ class CmdWave(cs.Command):
176
234
  " Ctrl+A Add axis\n"
177
235
  " R Reload all waves\n"
178
236
  " F Auto scale (fit)\n"
237
+ " Shift+Z Zoom in\n"
238
+ " Ctrl+Z Zoom out\n"
179
239
  " Delete Remove selected wave\n"
180
240
  "\n"
181
241
  "Cursors\n"
@@ -189,6 +249,10 @@ class CmdWave(cs.Command):
189
249
  "\n"
190
250
  "View\n"
191
251
  " L Toggle legend\n"
252
+ " Ctrl+Up Increase line width\n"
253
+ " Ctrl+Down Decrease line width\n"
254
+ " Ctrl+= Increase font size\n"
255
+ " Ctrl+- Decrease font size\n"
192
256
  "\n"
193
257
  "Zoom\n"
194
258
  " Scroll Zoom x-axis\n"
@@ -215,9 +279,12 @@ class CmdWave(cs.Command):
215
279
  def reloadPlots(self):
216
280
  self.graph.reloadPlots()
217
281
 
218
- def openFile(self, fname):
282
+ def openFile(self, fname, sheet_name=None):
219
283
  self.browser.openFile(fname)
220
284
 
285
+ def openDataFrame(self, df, name, **kwargs):
286
+ self.browser.openDataFrame(df, name)
287
+
221
288
  def run(self):
222
289
  tkinter.mainloop()
223
290