smithkit 0.1.1 → 0.2.0

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 (132) hide show
  1. package/README.md +119 -40
  2. package/dist/lib/MarkerMeasurements.d.ts +6 -0
  3. package/dist/lib/MarkerMeasurements.js +22 -0
  4. package/dist/lib/Smith.d.ts +9 -2
  5. package/dist/lib/Smith.js +68 -36
  6. package/dist/lib/SmithFormatter.d.ts +10 -0
  7. package/dist/lib/SmithFormatter.js +19 -0
  8. package/dist/lib/grid/CircleLayerControl.d.ts +15 -0
  9. package/dist/lib/grid/CircleLayerControl.js +40 -0
  10. package/dist/lib/{draw → grid}/ConstCircles.d.ts +4 -6
  11. package/dist/lib/{draw → grid}/ConstCircles.js +2 -2
  12. package/dist/lib/{draw → grid}/ConstQCircles.d.ts +2 -2
  13. package/dist/lib/{draw → grid}/ConstQCircles.js +3 -3
  14. package/dist/lib/{draw → grid}/ConstSwrCircles.d.ts +2 -2
  15. package/dist/lib/{draw → grid}/ConstSwrCircles.js +3 -3
  16. package/dist/lib/grid/GridDefinitions.d.ts +12 -0
  17. package/dist/lib/grid/GridDefinitions.js +138 -0
  18. package/dist/lib/grid/GridGeometry.d.ts +26 -0
  19. package/dist/lib/grid/GridGeometry.js +58 -0
  20. package/dist/lib/grid/GridLabels.d.ts +8 -0
  21. package/dist/lib/grid/GridLabels.js +45 -0
  22. package/dist/lib/grid/GridLayerControl.d.ts +12 -0
  23. package/dist/lib/grid/GridLayerControl.js +39 -0
  24. package/dist/lib/grid/LayerControl.d.ts +6 -0
  25. package/dist/lib/grid/LayerControl.js +16 -0
  26. package/dist/lib/{draw → grid}/SmithGridLayer.d.ts +5 -4
  27. package/dist/lib/{draw → grid}/SmithGridLayer.js +26 -9
  28. package/dist/lib/grid/types.d.ts +1 -1
  29. package/dist/lib/index.d.ts +8 -10
  30. package/dist/lib/index.js +5 -7
  31. package/dist/lib/{draw → interaction}/SmithCursor.d.ts +3 -3
  32. package/dist/lib/{draw → interaction}/SmithCursor.js +6 -6
  33. package/dist/lib/io/Touchstone.d.ts +10 -0
  34. package/dist/lib/io/Touchstone.js +75 -0
  35. package/dist/lib/layers.d.ts +2 -8
  36. package/dist/lib/layers.js +1 -73
  37. package/dist/lib/{complex → math}/Complex.d.ts +1 -0
  38. package/dist/lib/{complex → math}/Complex.js +1 -1
  39. package/dist/lib/math/geometry.d.ts +14 -0
  40. package/dist/lib/measurements.d.ts +2 -4
  41. package/dist/lib/measurements.js +1 -19
  42. package/dist/lib/rf/RfCalculations.d.ts +65 -0
  43. package/dist/lib/rf/RfCalculations.js +161 -0
  44. package/dist/lib/{SmithConstantCircle.d.ts → rf/SmithConstantCircle.d.ts} +2 -3
  45. package/dist/lib/{SmithConstantCircle.js → rf/SmithConstantCircle.js} +3 -4
  46. package/dist/lib/scales/PeripheralScaleDefinitions.d.ts +16 -0
  47. package/dist/lib/scales/PeripheralScaleDefinitions.js +54 -0
  48. package/dist/lib/scales/RadialScaleDefinitions.d.ts +15 -0
  49. package/dist/lib/scales/RadialScaleDefinitions.js +112 -0
  50. package/dist/lib/scales/SmithPeripheralScales.d.ts +4 -2
  51. package/dist/lib/scales/SmithPeripheralScales.js +46 -26
  52. package/dist/lib/scales/SmithScales.d.ts +3 -1
  53. package/dist/lib/scales/SmithScales.js +8 -2
  54. package/dist/lib/svg/LabelLayout.d.ts +17 -0
  55. package/dist/lib/svg/LabelLayout.js +145 -0
  56. package/dist/lib/{draw → svg}/SmithArc.d.ts +1 -1
  57. package/dist/lib/{draw → svg}/SmithCircle.d.ts +1 -1
  58. package/dist/lib/{draw → svg}/SmithLine.d.ts +1 -1
  59. package/dist/lib/{draw → svg}/SmithScaler.d.ts +1 -4
  60. package/dist/lib/{draw → svg}/SmithText.d.ts +1 -1
  61. package/dist/lib/svg/SvgExporter.d.ts +14 -0
  62. package/dist/lib/svg/SvgExporter.js +137 -0
  63. package/dist/lib/{draw → traces}/SmithData.d.ts +24 -35
  64. package/dist/lib/traces/SmithData.js +195 -0
  65. package/dist/lib/{draw → traces}/SmithMarker.d.ts +14 -3
  66. package/dist/lib/traces/SmithMarker.js +237 -0
  67. package/dist/lib/traces/TraceModel.d.ts +31 -0
  68. package/dist/lib/traces/TraceModel.js +123 -0
  69. package/dist/lib/traces/TraceRenderer.d.ts +33 -0
  70. package/dist/lib/traces/TraceRenderer.js +152 -0
  71. package/package.json +4 -1
  72. package/dist/lib/SmithArcsDefs.d.ts +0 -10
  73. package/dist/lib/SmithArcsDefs.js +0 -10
  74. package/dist/lib/components.d.ts +0 -14
  75. package/dist/lib/components.js +0 -26
  76. package/dist/lib/draw/SmithData.js +0 -366
  77. package/dist/lib/draw/SmithMarker.js +0 -122
  78. package/dist/lib/formatting.d.ts +0 -7
  79. package/dist/lib/formatting.js +0 -16
  80. package/dist/lib/grid/definitions.d.ts +0 -3
  81. package/dist/lib/grid/definitions.js +0 -123
  82. package/dist/lib/grid/geometry.d.ts +0 -20
  83. package/dist/lib/grid/geometry.js +0 -55
  84. package/dist/lib/grid/labels.d.ts +0 -3
  85. package/dist/lib/grid/labels.js +0 -41
  86. package/dist/lib/io/touchstone.d.ts +0 -7
  87. package/dist/lib/io/touchstone.js +0 -72
  88. package/dist/lib/math/complexRatio.d.ts +0 -3
  89. package/dist/lib/math/complexRatio.js +0 -30
  90. package/dist/lib/renormalization.d.ts +0 -10
  91. package/dist/lib/renormalization.js +0 -62
  92. package/dist/lib/rf.d.ts +0 -35
  93. package/dist/lib/rf.js +0 -74
  94. package/dist/lib/scales/peripheralScales.d.ts +0 -12
  95. package/dist/lib/scales/peripheralScales.js +0 -49
  96. package/dist/lib/scales/radialScales.d.ts +0 -12
  97. package/dist/lib/scales/radialScales.js +0 -109
  98. package/dist/lib/shapes/Arc.d.ts +0 -6
  99. package/dist/lib/shapes/Circle.d.ts +0 -5
  100. package/dist/lib/shapes/Circle.js +0 -1
  101. package/dist/lib/shapes/Line.d.ts +0 -5
  102. package/dist/lib/shapes/Line.js +0 -1
  103. package/dist/lib/shapes/Point.d.ts +0 -1
  104. package/dist/lib/shapes/Point.js +0 -1
  105. /package/dist/lib/{draw → grid}/ConstConductance.d.ts +0 -0
  106. /package/dist/lib/{draw → grid}/ConstConductance.js +0 -0
  107. /package/dist/lib/{draw → grid}/ConstReactance.d.ts +0 -0
  108. /package/dist/lib/{draw → grid}/ConstReactance.js +0 -0
  109. /package/dist/lib/{draw → grid}/ConstResistance.d.ts +0 -0
  110. /package/dist/lib/{draw → grid}/ConstResistance.js +0 -0
  111. /package/dist/lib/{draw → grid}/ConstSusceptance.d.ts +0 -0
  112. /package/dist/lib/{draw → grid}/ConstSusceptance.js +0 -0
  113. /package/dist/lib/{arcs → grid}/Tick.d.ts +0 -0
  114. /package/dist/lib/{arcs → grid}/Tick.js +0 -0
  115. /package/dist/lib/{draw → interaction}/MouseGesture.d.ts +0 -0
  116. /package/dist/lib/{draw → interaction}/MouseGesture.js +0 -0
  117. /package/dist/lib/{draw/SmithDrawOptions.js → math/geometry.js} +0 -0
  118. /package/dist/lib/{draw → svg}/SmithArc.js +0 -0
  119. /package/dist/lib/{draw → svg}/SmithCircle.js +0 -0
  120. /package/dist/lib/{draw → svg}/SmithDrawOptions.d.ts +0 -0
  121. /package/dist/lib/{shapes/Arc.js → svg/SmithDrawOptions.js} +0 -0
  122. /package/dist/lib/{draw → svg}/SmithGroup.d.ts +0 -0
  123. /package/dist/lib/{draw → svg}/SmithGroup.js +0 -0
  124. /package/dist/lib/{draw → svg}/SmithLine.js +0 -0
  125. /package/dist/lib/{draw → svg}/SmithPath.d.ts +0 -0
  126. /package/dist/lib/{draw → svg}/SmithPath.js +0 -0
  127. /package/dist/lib/{draw → svg}/SmithScaler.js +0 -0
  128. /package/dist/lib/{draw → svg}/SmithShape.d.ts +0 -0
  129. /package/dist/lib/{draw → svg}/SmithShape.js +0 -0
  130. /package/dist/lib/{draw → svg}/SmithSvg.d.ts +0 -0
  131. /package/dist/lib/{draw → svg}/SmithSvg.js +0 -0
  132. /package/dist/lib/{draw → svg}/SmithText.js +0 -0
@@ -1,366 +0,0 @@
1
- import { SmithGroup } from './SmithGroup.js';
2
- import { line } from 'd3';
3
- import { SmithMarker } from './SmithMarker.js';
4
- export class SmithData {
5
- data;
6
- color;
7
- transform;
8
- fgContainer;
9
- scaler;
10
- markerDragHandler;
11
- markerContainer;
12
- style;
13
- viewportScale = 1;
14
- destroyed = false;
15
- visible = true;
16
- pendingEvents = new Map();
17
- group;
18
- markersCount = 0;
19
- markers = [];
20
- handler = null;
21
- constructor(data, color, transform, fgContainer, scaler, markerDragHandler, markerContainer = fgContainer, style = {}) {
22
- this.data = data;
23
- this.color = color;
24
- this.transform = transform;
25
- this.fgContainer = fgContainer;
26
- this.scaler = scaler;
27
- this.markerDragHandler = markerDragHandler;
28
- this.markerContainer = markerContainer;
29
- this.style = {
30
- mode: style.mode ?? 'points',
31
- lineWidth: style.lineWidth ?? 2,
32
- pointRadius: style.pointRadius ?? 2,
33
- };
34
- this.data = this.copySamples(data);
35
- this.group = this.drawTrace(this.data);
36
- this.group.attr('pointer-events', 'none');
37
- this.fgContainer.append(this.group);
38
- this.zoomDataPoints();
39
- }
40
- drawTrace(data) {
41
- const group = new SmithGroup({
42
- stroke: 'none',
43
- strokeWidth: 'none',
44
- fill: this.color,
45
- });
46
- group.attr('data-role', 'samples');
47
- group.attr('data-mode', this.style.mode);
48
- if (this.style.mode !== 'points') {
49
- const path = line()
50
- .x((sample) => this.scaler.x(sample.reflectionCoefficient[0]))
51
- .y((sample) => this.scaler.y(sample.reflectionCoefficient[1]));
52
- group.Element.append('path')
53
- .attr('class', 'trace-line')
54
- .attr('d', path(data))
55
- .attr('fill', 'none')
56
- .attr('stroke', this.color)
57
- .attr('stroke-width', this.style.lineWidth)
58
- .attr('vector-effect', 'non-scaling-stroke')
59
- .attr('stroke-linejoin', 'round')
60
- .attr('stroke-linecap', 'round');
61
- }
62
- if (this.style.mode !== 'line') {
63
- this.renderPoints(group, data);
64
- }
65
- return group;
66
- }
67
- renderPoints(group, data) {
68
- let visible = data;
69
- if (data.length > 5000) {
70
- const cells = new Set();
71
- const cellSize = Math.max(0.5, this.style.pointRadius) / this.viewportScale;
72
- const extent = this.scaler.x(1);
73
- const margin = this.style.pointRadius / this.viewportScale;
74
- visible = data.filter((sample) => {
75
- const x = this.scaler.x(sample.reflectionCoefficient[0]) * this.transform.k + this.transform.x;
76
- const y = this.scaler.y(sample.reflectionCoefficient[1]) * this.transform.k + this.transform.y;
77
- if (x < -margin || y < -margin || x > extent + margin || y > extent + margin) {
78
- return false;
79
- }
80
- const cell = `${Math.floor(x / cellSize)},${Math.floor(y / cellSize)}`;
81
- if (cells.has(cell)) {
82
- return false;
83
- }
84
- cells.add(cell);
85
- return true;
86
- });
87
- }
88
- group.Element.selectAll('circle')
89
- .data(visible)
90
- .join('circle')
91
- .attr('cx', (sample) => this.scaler.x(sample.reflectionCoefficient[0]))
92
- .attr('cy', (sample) => this.scaler.y(sample.reflectionCoefficient[1]))
93
- .attr('r', this.style.pointRadius / (this.transform.k * this.viewportScale));
94
- }
95
- setViewportScale(scale) {
96
- if (scale === this.viewportScale || !Number.isFinite(scale) || scale <= 0) {
97
- return;
98
- }
99
- this.viewportScale = scale;
100
- this.zoomDataPoints();
101
- }
102
- zoom(transform) {
103
- if (this.destroyed) {
104
- return;
105
- }
106
- this.transform = transform;
107
- this.zoomDataPoints();
108
- this.zoomAllMarkers();
109
- }
110
- zoomDataPoints() {
111
- const k = this.transform.k;
112
- if (this.style.mode === 'line') {
113
- return;
114
- }
115
- if (this.data.length > 5000) {
116
- this.renderPoints(this.group, this.data);
117
- }
118
- else {
119
- this.group.Element.selectAll('circle').attr('r', this.style.pointRadius / (k * this.viewportScale));
120
- }
121
- }
122
- zoomAllMarkers() {
123
- const k = this.transform.k;
124
- for (const marker of this.markers) {
125
- const entry = marker.selectedPoint;
126
- if (entry) {
127
- marker.marker.zoom(k);
128
- }
129
- }
130
- }
131
- addMarker(sampleIndex = 0) {
132
- if (this.destroyed) {
133
- throw new Error('This dataset has been removed.');
134
- }
135
- this.validateSampleIndex(sampleIndex);
136
- const markerIndex = this.markersCount++;
137
- const marker = new SmithMarker(markerIndex + 1, this.color, (dragging) => this.markerDragHandler?.(marker, dragging));
138
- const markerDesc = {
139
- marker,
140
- selectedPoint: this.data[sampleIndex],
141
- number: markerIndex + 1,
142
- };
143
- this.markers.push(markerDesc);
144
- marker.Element.attr('data-role', 'marker');
145
- this.markerContainer.append(marker);
146
- marker.setDragHandler((mp) => {
147
- const dp = this.findClosestPointTo(this.scaler.pointInvert(mp));
148
- if (markerDesc.selectedPoint === dp) {
149
- return;
150
- }
151
- markerDesc.selectedPoint = dp;
152
- marker.move(this.scaler.point(dp.reflectionCoefficient));
153
- marker.zoom(this.transform.k);
154
- this.notifyMarker(markerDesc);
155
- });
156
- marker.zoom(this.transform.k);
157
- marker.show();
158
- marker.move(this.scaler.point(markerDesc.selectedPoint.reflectionCoefficient));
159
- marker.Element.style('display', () => (this.visible ? null : 'none'));
160
- this.notifyMarker(markerDesc);
161
- return this.markers.length - 1;
162
- }
163
- removeMarker(index) {
164
- const entry = this.markers[index];
165
- if (!entry) {
166
- return false;
167
- }
168
- clearTimeout(this.pendingEvents.get(entry));
169
- this.pendingEvents.delete(entry);
170
- entry.marker.destroy();
171
- this.markers.splice(index, 1);
172
- return true;
173
- }
174
- setMarkerSample(index, sampleIndex) {
175
- const entry = this.markers[index];
176
- if (!entry) {
177
- return false;
178
- }
179
- this.validateSampleIndex(sampleIndex);
180
- entry.selectedPoint = this.data[sampleIndex];
181
- entry.marker.move(this.scaler.point(entry.selectedPoint.reflectionCoefficient));
182
- this.notifyMarker(entry);
183
- return true;
184
- }
185
- setMarkerFrequency(index, frequencyHz) {
186
- if (!this.markers[index]) {
187
- return false;
188
- }
189
- if (!Number.isFinite(frequencyHz) || frequencyHz < 0) {
190
- throw new RangeError('Marker frequency must be finite and non-negative.');
191
- }
192
- return this.setMarkerSample(index, this.nearestFrequencyIndex(frequencyHz));
193
- }
194
- nearestFrequencyIndex(frequencyHz) {
195
- let closest = 0;
196
- let distance = Math.abs(this.data[0].frequencyHz - frequencyHz);
197
- for (let i = 1; i < this.data.length; i++) {
198
- const nextDistance = Math.abs(this.data[i].frequencyHz - frequencyHz);
199
- if (nextDistance < distance) {
200
- closest = i;
201
- distance = nextDistance;
202
- }
203
- }
204
- return closest;
205
- }
206
- validateSampleIndex(index) {
207
- if (!Number.isInteger(index) || index < 0 || index >= this.data.length) {
208
- throw new RangeError('Sample index is outside this trace.');
209
- }
210
- }
211
- get Samples() {
212
- return this.data;
213
- }
214
- get SampleCount() {
215
- return this.data.length;
216
- }
217
- get Color() {
218
- return this.color;
219
- }
220
- get Visible() {
221
- return this.visible;
222
- }
223
- markerSampleIndex(index) {
224
- const entry = this.markers[index];
225
- return entry ? this.data.indexOf(entry.selectedPoint) : -1;
226
- }
227
- setColor(color) {
228
- this.color = color;
229
- this.group.attr('fill', color);
230
- this.group.Element.select('.trace-line').attr('stroke', color);
231
- this.markers.forEach(({ marker }) => marker.setColor(color));
232
- }
233
- get Style() {
234
- return { ...this.style };
235
- }
236
- setStyle(options) {
237
- const next = {
238
- mode: options.mode ?? this.style.mode,
239
- lineWidth: options.lineWidth ?? this.style.lineWidth,
240
- pointRadius: options.pointRadius ?? this.style.pointRadius,
241
- };
242
- if (next.mode === this.style.mode &&
243
- next.lineWidth === this.style.lineWidth &&
244
- next.pointRadius === this.style.pointRadius) {
245
- return;
246
- }
247
- const modeChanged = next.mode !== this.style.mode;
248
- this.style = next;
249
- if (modeChanged) {
250
- this.redraw();
251
- }
252
- else {
253
- this.group.Element.select('.trace-line').attr('stroke-width', next.lineWidth);
254
- this.zoomDataPoints();
255
- }
256
- }
257
- redraw() {
258
- const group = this.drawTrace(this.data).attr('pointer-events', 'none');
259
- // Replace in place to retain trace ordering beneath the separate marker layer.
260
- this.group.Node.replaceWith(group.Node);
261
- this.group = group;
262
- this.group.Element.style('display', () => (this.visible ? null : 'none'));
263
- }
264
- setVisible(visible) {
265
- this.visible = visible;
266
- this.group.Element.style('display', () => (visible ? null : 'none'));
267
- this.markers.forEach(({ marker }) => {
268
- if (!visible) {
269
- marker.cancelDrag();
270
- }
271
- marker.Element.style('display', () => (visible ? null : 'none'));
272
- });
273
- }
274
- copySamples(values) {
275
- if (!values.length ||
276
- values.some(({ frequencyHz, reflectionCoefficient }) => !Number.isFinite(frequencyHz) ||
277
- frequencyHz < 0 ||
278
- reflectionCoefficient.length !== 2 ||
279
- !reflectionCoefficient.every(Number.isFinite))) {
280
- throw new RangeError('A dataset requires samples with a non-negative finite frequency and two finite coordinates.');
281
- }
282
- return values.map(({ frequencyHz, reflectionCoefficient }) => ({
283
- frequencyHz,
284
- reflectionCoefficient: [reflectionCoefficient[0], reflectionCoefficient[1]],
285
- }));
286
- }
287
- notifyMarker(entry) {
288
- if (this.pendingEvents.has(entry)) {
289
- return;
290
- }
291
- const timer = setTimeout(() => {
292
- this.pendingEvents.delete(entry);
293
- const index = this.markers.indexOf(entry);
294
- if (!this.destroyed && index >= 0) {
295
- this.handler?.(index, entry.selectedPoint);
296
- }
297
- }, 0);
298
- this.pendingEvents.set(entry, timer);
299
- }
300
- cancelEvents() {
301
- this.pendingEvents.forEach((timer) => clearTimeout(timer));
302
- this.pendingEvents.clear();
303
- }
304
- update(values, strategy = 'frequency') {
305
- if (this.destroyed) {
306
- throw new Error('This dataset has been removed.');
307
- }
308
- const samples = this.copySamples(values);
309
- const selectedIndices = this.markers.map((entry) => this.data.indexOf(entry.selectedPoint));
310
- this.cancelEvents();
311
- this.data = samples;
312
- const group = this.drawTrace(samples).attr('pointer-events', 'none');
313
- this.group.Element.remove();
314
- this.group = group;
315
- this.group.Element.style('display', () => (this.visible ? null : 'none'));
316
- this.fgContainer.append(group);
317
- this.zoomDataPoints();
318
- this.markers.forEach((entry, index) => {
319
- if (strategy === 'sample-index') {
320
- entry.selectedPoint = samples[Math.min(selectedIndices[index], samples.length - 1)];
321
- }
322
- else if (strategy === 'reflection') {
323
- entry.selectedPoint = this.findClosestPointTo(entry.selectedPoint.reflectionCoefficient);
324
- }
325
- else {
326
- entry.selectedPoint = samples[this.nearestFrequencyIndex(entry.selectedPoint.frequencyHz)];
327
- }
328
- entry.marker.move(this.scaler.point(entry.selectedPoint.reflectionCoefficient));
329
- this.notifyMarker(entry);
330
- });
331
- }
332
- destroy() {
333
- if (this.destroyed) {
334
- return;
335
- }
336
- this.destroyed = true;
337
- this.cancelEvents();
338
- this.handler = null;
339
- this.markers.forEach(({ marker }) => marker.destroy());
340
- this.markers = [];
341
- this.markerDragHandler = undefined;
342
- this.data = [];
343
- this.group.Element.remove();
344
- }
345
- getMarker(index) {
346
- return this.markers[index];
347
- }
348
- get Markers() {
349
- return this.markers.slice();
350
- }
351
- setMarkerMoveHandler(handler) {
352
- this.handler = handler;
353
- }
354
- findClosestPointTo(p) {
355
- const dist = (p1, p2) => {
356
- const xd = p1[0] - p2[0];
357
- const yd = p1[1] - p2[1];
358
- return Math.hypot(xd, yd);
359
- };
360
- return this.data.reduce((prev, curr) => {
361
- const d1 = dist(p, prev.reflectionCoefficient);
362
- const d2 = dist(p, curr.reflectionCoefficient);
363
- return d1 <= d2 ? prev : curr;
364
- });
365
- }
366
- }
@@ -1,122 +0,0 @@
1
- import * as d3 from 'd3';
2
- import { MouseGesture } from './MouseGesture.js';
3
- import { SmithShape } from './SmithShape.js';
4
- export class SmithMarker extends SmithShape {
5
- dragStateHandler;
6
- size = 18;
7
- mouseGesture = new MouseGesture();
8
- activeDrags = new Set();
9
- destroyed = false;
10
- triangle;
11
- inner;
12
- text;
13
- rc = [0, 0];
14
- dragHandler = null;
15
- constructor(marker, color, dragStateHandler = null) {
16
- super(d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'g')));
17
- this.dragStateHandler = dragStateHandler;
18
- const g = this.Element.style('cursor', 'var(--smithkit-marker-cursor, grab)');
19
- this.triangle = g
20
- .append('polygon')
21
- .attr('stroke', 'none')
22
- .attr('fill', 'gray')
23
- .attr('transform', 'translate(0,0)');
24
- this.inner = g
25
- .append('polygon')
26
- .attr('stroke', 'none')
27
- .attr('fill', color)
28
- .attr('transform', 'translate(0,0)');
29
- this.text = g
30
- .append('text')
31
- .attr('pointer-events', 'none')
32
- .attr('transform', 'translate(0,0)')
33
- .attr('font-family', 'Verdana')
34
- .attr('font-weight', 'normal')
35
- .attr('text-anchor', 'middle')
36
- .attr('dominant-baseline', 'middle')
37
- .attr('x', '0')
38
- .attr('y', '0')
39
- .attr('fill', 'white')
40
- .text(marker.toString());
41
- this.zoom(1);
42
- const drag = d3
43
- .drag()
44
- .on('start', (event) => {
45
- if (this.destroyed) {
46
- return;
47
- }
48
- this.mouseGesture.capture(event.sourceEvent, 'drag');
49
- const wasIdle = this.activeDrags.size === 0;
50
- this.activeDrags.add(event.identifier);
51
- if (wasIdle) {
52
- this.dragStateHandler?.(true);
53
- }
54
- })
55
- .on('drag', (event) => this.onDrag(event))
56
- .on('end', (event) => {
57
- if (this.activeDrags.delete(event.identifier) && this.activeDrags.size === 0) {
58
- this.dragStateHandler?.(false);
59
- }
60
- });
61
- this.triangle.call(drag);
62
- this.inner.call(drag);
63
- }
64
- destroy() {
65
- if (this.destroyed) {
66
- return;
67
- }
68
- this.destroyed = true;
69
- this.dragHandler = null;
70
- this.cancelDrag();
71
- this.dragStateHandler = null;
72
- this.Element.selectAll('*').on('.drag', null).interrupt();
73
- this.Element.remove();
74
- }
75
- cancelDrag() {
76
- if (this.activeDrags.size > 0) {
77
- this.activeDrags.clear();
78
- this.dragStateHandler?.(false);
79
- }
80
- this.mouseGesture.destroy();
81
- }
82
- setColor(color) {
83
- this.inner.attr('fill', color);
84
- }
85
- onDrag(event) {
86
- if (this.dragHandler) {
87
- this.dragHandler([event.x, event.y]);
88
- }
89
- }
90
- get Position() {
91
- return this.rc;
92
- }
93
- move(p) {
94
- this.rc = p;
95
- this.triangle.attr('transform', `translate(${p[0]},${p[1]})`);
96
- this.inner.attr('transform', `translate(${p[0]},${p[1]})`);
97
- this.text.attr('x', `${p[0]}`).attr('y', `${p[1]}`);
98
- }
99
- zoom(k) {
100
- const size = this.size / k;
101
- const h = size / 12;
102
- const dy = -size / 1.6;
103
- const fs = size / 1.8;
104
- // calculate inner triangle
105
- const alpha = Math.atan(1 / 2);
106
- const beta = Math.PI / 2 - alpha;
107
- const x = h / Math.sin(alpha);
108
- const y = h / Math.sin(beta) + h / Math.tan(beta);
109
- this.triangle.attr('points', `0,0 ${size / 2},${-size} ${-size / 2},${-size}`);
110
- this.inner.attr('points', `0,${-x} ${size / 2 - y},${-size + h} ${-size / 2 + y},${-size + h}`);
111
- this.text.attr('font-size', `${fs}`).attr('dy', `${dy}`);
112
- }
113
- show() {
114
- this.Element.attr('opacity', null);
115
- }
116
- hide() {
117
- this.Element.attr('opacity', '0');
118
- }
119
- setDragHandler(handler) {
120
- this.dragHandler = handler;
121
- }
122
- }
@@ -1,7 +0,0 @@
1
- import type { Complex } from './complex/Complex.js';
2
- /** Format with three significant digits and an SI prefix; includes spacing before the unit. */
3
- export declare function formatNumber(value: number): string;
4
- /** Format Cartesian components to decimalPlaces fractional digits. */
5
- export declare function formatComplex(value: Complex, unit?: string, decimalPlaces?: number): string;
6
- /** Format magnitude and phase in degrees to decimalPlaces fractional digits. */
7
- export declare function formatComplexPolar(value: Complex, unit?: string, decimalPlaces?: number): string;
@@ -1,16 +0,0 @@
1
- import { format } from 'd3';
2
- /** Format with three significant digits and an SI prefix; includes spacing before the unit. */
3
- export function formatNumber(value) {
4
- const formatted = format('.3~s')(value);
5
- return Number.isFinite(value) && /[a-zA-Zµ]$/.test(formatted)
6
- ? formatted.replace(/([a-zA-Zµ])$/, ' $1')
7
- : formatted + ' ';
8
- }
9
- /** Format Cartesian components to decimalPlaces fractional digits. */
10
- export function formatComplex(value, unit = '', decimalPlaces = 3) {
11
- return `${value.toString(decimalPlaces)} ${unit === '' ? '' : `[${unit}]`}`;
12
- }
13
- /** Format magnitude and phase in degrees to decimalPlaces fractional digits. */
14
- export function formatComplexPolar(value, unit = '', decimalPlaces = 3) {
15
- return `${value.abs().toFixed(decimalPlaces)} ${unit} ∠${((value.arg() * 180) / Math.PI).toFixed(decimalPlaces)}°`;
16
- }
@@ -1,3 +0,0 @@
1
- import type { SmithTicksData } from './types.js';
2
- /** Build fresh definitions so callers cannot mutate another chart's grid. */
3
- export declare function createGridDefinitions(): SmithTicksData;
@@ -1,123 +0,0 @@
1
- function resistanceArcs(bands) {
2
- return bands.flatMap(([values, from, to, largeArc]) => values.map((value) => [
3
- value,
4
- [
5
- [from, from < 0 ? 1 : 0],
6
- [to, to < 0 ? 1 : 0],
7
- ],
8
- [largeArc, from > to],
9
- ]));
10
- }
11
- function reactanceArcs(bands) {
12
- return bands.flatMap(([values, outer, inner]) => values.flatMap((value) => [
13
- [
14
- value,
15
- [
16
- [outer, 1],
17
- [inner, 1],
18
- ],
19
- [false, false],
20
- ],
21
- [
22
- -value,
23
- [
24
- [outer, 0],
25
- [inner, 0],
26
- ],
27
- [false, true],
28
- ],
29
- ]));
30
- }
31
- const resistanceMajor = [
32
- [[0.05, 0.15], 0.2, -0.2, false],
33
- [[0.1, 0.3, 0.5, 0.7, 0.9], 2, -2, true],
34
- [[0.2, 0.4, 0.6, 0.8, 1.2, 1.4, 1.6, 1.8], 5, -5, true],
35
- [[1, 3, 5], 10, -10, true],
36
- [[2, 4], 20, -20, true],
37
- [[20], 50, -50, true],
38
- ];
39
- const resistanceMinor = [
40
- [[0.02, 0.04, 0.06, 0.08, 0.12, 0.14, 0.16, 0.18], 0.2, 0.5, false],
41
- [[0.02, 0.04, 0.06, 0.08, 0.12, 0.14, 0.16, 0.18], -0.2, -0.5, false],
42
- [[0.05, 0.15, 0.25, 0.35, 0.45], 0.5, 1, false],
43
- [[0.05, 0.15, 0.25, 0.35, 0.45], -0.5, -1, false],
44
- [
45
- [
46
- 0.01, 0.02, 0.03, 0.04, 0.06, 0.07, 0.08, 0.09, 0.11, 0.12, 0.13, 0.14, 0.16, 0.17, 0.18,
47
- 0.19,
48
- ],
49
- 0.2,
50
- -0.2,
51
- false,
52
- ],
53
- [[0.22, 0.24, 0.26, 0.28, 0.32, 0.34, 0.36, 0.38, 0.42, 0.44, 0.46, 0.48], 0.5, -0.5, false],
54
- [[0.55, 0.65, 0.75, 0.85, 0.95], 2, -2, true],
55
- [[1.1, 1.3, 1.5, 1.7, 1.9], 2, -2, false],
56
- [[2.2, 2.4, 2.6, 2.8, 3.2, 3.4, 3.6, 3.8], 5, -5, true],
57
- [[4.2, 4.4, 4.6, 4.8], 5, -5, false],
58
- [[6, 8, 12, 14, 16, 18], 20, -20, true],
59
- [[7, 9], 10, -10, true],
60
- [[30, 40], 50, -50, true],
61
- ];
62
- const reactanceMajor = [
63
- [[0.05, 0.15], 0.2, 0],
64
- [[0.1, 0.3, 0.5, 0.7, 0.9], 2, 0],
65
- [[0.2, 0.4, 0.6, 0.8, 1.2, 1.4, 1.6, 1.8], 5, 0],
66
- [[1, 3, 5], 10, 0],
67
- [[2, 4, 10], 20, 0],
68
- [[20], 50, 0],
69
- ];
70
- const reactanceMinor = [
71
- [
72
- [
73
- 0.01, 0.02, 0.03, 0.04, 0.06, 0.07, 0.08, 0.09, 0.11, 0.12, 0.13, 0.14, 0.16, 0.17, 0.18,
74
- 0.19,
75
- ],
76
- 0.2,
77
- 0,
78
- ],
79
- [[0.02, 0.04, 0.06, 0.08, 0.12, 0.14, 0.16, 0.18], 0.5, 0.2],
80
- [[0.22, 0.24, 0.26, 0.28, 0.32, 0.34, 0.36, 0.38, 0.42, 0.44, 0.46, 0.48], 0.5, 0],
81
- [[0.05, 0.15, 0.25, 0.35, 0.45], 1, 0.5],
82
- [[0.55, 0.65, 0.75, 0.85, 0.95], 1, 0],
83
- [[1.1, 1.3, 1.5, 1.7, 1.9], 2, 0],
84
- [[2.2, 2.4, 2.6, 2.8, 3.2, 3.4, 3.6, 3.8, 4.2, 4.4, 4.6, 4.8], 5, 0],
85
- [[6, 8, 14, 16, 18], 20, 0],
86
- [[7, 9], 10, 0],
87
- [[12, 30, 40], 50, 0],
88
- ];
89
- /** Build fresh definitions so callers cannot mutate another chart's grid. */
90
- export function createGridDefinitions() {
91
- return {
92
- resistance: {
93
- major: { lines: [], circles: [10, 50], arcs: resistanceArcs(resistanceMajor) },
94
- minor: { lines: [], circles: [], arcs: resistanceArcs(resistanceMinor) },
95
- },
96
- reactance: {
97
- major: {
98
- lines: [{ p1: [-1, 0], p2: [1, 0] }],
99
- circles: [],
100
- arcs: [
101
- ...reactanceArcs(reactanceMajor),
102
- [
103
- 50,
104
- [
105
- [0, 0],
106
- [0, 1],
107
- ],
108
- [false, false],
109
- ],
110
- [
111
- -50,
112
- [
113
- [0, 1],
114
- [0, 0],
115
- ],
116
- [false, true],
117
- ],
118
- ],
119
- },
120
- minor: { lines: [], circles: [], arcs: reactanceArcs(reactanceMinor) },
121
- },
122
- };
123
- }
@@ -1,20 +0,0 @@
1
- import type { TickDefRequired } from '../arcs/Tick.js';
2
- import type { SmithTicksShapes } from './types.js';
3
- import type { Point } from '../shapes/Point.js';
4
- export type GridKind = 'resistance' | 'reactance' | 'conductance' | 'susceptance';
5
- export type GridArc = [Point, Point, number, boolean, boolean];
6
- /** Normalized geometry only: no DOM, D3, or pixel coordinates. */
7
- export declare function gridGeometry(kind: GridKind, data: SmithTicksShapes): {
8
- lines: import("../shapes/Line.js").Line[];
9
- circles: import("../shapes/Circle.js").Circle[];
10
- arcs: GridArc[];
11
- };
12
- export declare function gridLabel(kind: GridKind, definition: TickDefRequired): {
13
- point: [number, number];
14
- text: string;
15
- rotate: number;
16
- dx: number;
17
- dy: number;
18
- textAnchor: string;
19
- dominantBaseline: string;
20
- };