@smartnet360/svelte-components 0.0.13 → 0.0.15
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.
- package/dist/apps/antenna-pattern/components/AntennaControls.svelte +209 -57
- package/dist/apps/antenna-pattern/components/AntennaDiagrams.svelte +173 -96
- package/dist/apps/antenna-pattern/components/chart-engines/PolarAreaChart.svelte +125 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarAreaChart.svelte.d.ts +16 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarBarChart.svelte +121 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarBarChart.svelte.d.ts +15 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarLineChart.svelte +125 -0
- package/dist/apps/antenna-pattern/components/chart-engines/PolarLineChart.svelte.d.ts +16 -0
- package/dist/apps/antenna-pattern/components/chart-engines/index.d.ts +9 -0
- package/dist/apps/antenna-pattern/components/chart-engines/index.js +8 -0
- package/dist/apps/antenna-pattern/index.d.ts +1 -0
- package/dist/apps/antenna-pattern/index.js +2 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-area-utils.d.ts +89 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-area-utils.js +146 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-bar-utils.d.ts +88 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-bar-utils.js +131 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-line-utils.d.ts +88 -0
- package/dist/apps/antenna-pattern/utils/chart-engines/polar-line-utils.js +134 -0
- package/dist/apps/antenna-pattern/utils/recent-antennas.d.ts +20 -0
- package/dist/apps/antenna-pattern/utils/recent-antennas.js +60 -0
- package/package.json +4 -4
@@ -2,25 +2,18 @@
|
|
2
2
|
|
3
3
|
<script lang="ts">
|
4
4
|
import { onMount } from 'svelte';
|
5
|
-
import { browser } from '$app/environment';
|
6
5
|
import { loadAntennas } from '../utils/db-utils';
|
7
6
|
import type { Antenna } from '../db';
|
8
7
|
import AntennaControls from './AntennaControls.svelte';
|
9
8
|
import AntennaSettingsModal from './AntennaSettingsModal.svelte';
|
10
|
-
import {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
type PlotlyTraceData
|
16
|
-
} from '../utils/plotly-chart-utils';
|
17
|
-
|
18
|
-
let Plotly: any;
|
19
|
-
let chartDiv = $state<HTMLDivElement>();
|
9
|
+
import { PolarLineChart, PolarBarChart, PolarAreaChart } from './chart-engines/index';
|
10
|
+
|
11
|
+
// Chart engine types
|
12
|
+
type ChartEngineType = 'polar-line' | 'polar-bar' | 'polar-area';
|
13
|
+
|
20
14
|
let antennas = $state<Antenna[]>([]);
|
21
15
|
let selectedAntenna = $state<Antenna | null>(null);
|
22
16
|
let selectedAntenna2 = $state<Antenna | null>(null);
|
23
|
-
let chartInitialized = $state(false);
|
24
17
|
|
25
18
|
// External Bootstrap slider values
|
26
19
|
let ant1ElectricalTilt = $state(0);
|
@@ -31,6 +24,12 @@
|
|
31
24
|
// Viewing mode and pattern visibility
|
32
25
|
let viewMode = $state<'single' | 'compare'>('single');
|
33
26
|
let patternType = $state<'horizontal' | 'vertical'>('vertical');
|
27
|
+
|
28
|
+
// Chart engine selection
|
29
|
+
let chartEngine = $state<ChartEngineType>('polar-line');
|
30
|
+
|
31
|
+
// Pattern display mode - normalized vs gain-adjusted
|
32
|
+
let patternDisplayMode = $state<'normalized' | 'gain-adjusted'>('normalized');
|
34
33
|
|
35
34
|
// Settings modal state
|
36
35
|
let showSettingsModal = $state(false);
|
@@ -40,12 +39,35 @@
|
|
40
39
|
|
41
40
|
// Handle antenna selection from controls
|
42
41
|
function handleAntenna1Change(antenna: Antenna | null) {
|
42
|
+
console.log('📥 [PARENT] handleAntenna1Change called:', {
|
43
|
+
antenna: antenna ? {
|
44
|
+
name: antenna.name,
|
45
|
+
frequency: antenna.frequency,
|
46
|
+
tilt: antenna.tilt
|
47
|
+
} : null,
|
48
|
+
previousAntenna: selectedAntenna ? {
|
49
|
+
name: selectedAntenna.name,
|
50
|
+
frequency: selectedAntenna.frequency,
|
51
|
+
tilt: selectedAntenna.tilt
|
52
|
+
} : null,
|
53
|
+
timestamp: new Date().toISOString()
|
54
|
+
});
|
55
|
+
|
43
56
|
selectedAntenna = antenna;
|
44
57
|
if (antenna) {
|
45
58
|
// Update available electrical tilts based on selected antenna
|
59
|
+
const previousTilts = [...availableElectricalTilts];
|
46
60
|
availableElectricalTilts = antenna.tilt ?
|
47
61
|
antenna.tilt.split(',').map(t => t.trim()) :
|
48
62
|
['0', '2', '4', '6', '8'];
|
63
|
+
|
64
|
+
console.log('🔧 [PARENT] Updated available tilts and reset positions:', {
|
65
|
+
from: previousTilts,
|
66
|
+
to: availableElectricalTilts,
|
67
|
+
electricalTiltReset: ant1ElectricalTilt,
|
68
|
+
mechanicalTiltReset: ant1MechanicalTilt
|
69
|
+
});
|
70
|
+
|
49
71
|
ant1ElectricalTilt = 0;
|
50
72
|
ant1MechanicalTilt = 0;
|
51
73
|
}
|
@@ -61,10 +83,22 @@
|
|
61
83
|
|
62
84
|
// Handle electrical tilt changes from controls
|
63
85
|
function handleTilt1Change(tilt: number) {
|
86
|
+
console.log('📥 [PARENT] handleTilt1Change called:', {
|
87
|
+
tilt,
|
88
|
+
previousTilt: ant1ElectricalTilt,
|
89
|
+
changed: tilt !== ant1ElectricalTilt,
|
90
|
+
timestamp: new Date().toISOString()
|
91
|
+
});
|
64
92
|
ant1ElectricalTilt = tilt;
|
65
93
|
}
|
66
94
|
|
67
95
|
function handleTilt2Change(tilt: number) {
|
96
|
+
console.log('📥 [PARENT] handleTilt2Change called:', {
|
97
|
+
tilt,
|
98
|
+
previousTilt: ant2ElectricalTilt,
|
99
|
+
changed: tilt !== ant2ElectricalTilt,
|
100
|
+
timestamp: new Date().toISOString()
|
101
|
+
});
|
68
102
|
ant2ElectricalTilt = tilt;
|
69
103
|
}
|
70
104
|
|
@@ -118,89 +152,38 @@
|
|
118
152
|
}
|
119
153
|
}
|
120
154
|
|
121
|
-
// Watch for slider changes and update chart
|
122
|
-
$effect(() => {
|
123
|
-
if (chartInitialized) {
|
124
|
-
updateChart();
|
125
|
-
}
|
126
|
-
});
|
127
|
-
|
128
155
|
onMount(async () => {
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
156
|
+
try {
|
157
|
+
// Load antenna data
|
158
|
+
antennas = await loadAntennas();
|
159
|
+
|
160
|
+
if (antennas.length > 0) {
|
161
|
+
// Set default antenna selection for antenna 1
|
162
|
+
selectedAntenna = antennas[0];
|
163
|
+
if (selectedAntenna.tilt) {
|
164
|
+
availableElectricalTilts = selectedAntenna.tilt.split(',').map(t => t.trim());
|
165
|
+
}
|
134
166
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
}
|
141
|
-
|
142
|
-
// Set default antenna selection for antenna 2 (for compare mode)
|
143
|
-
if (antennas.length > 1) {
|
144
|
-
selectedAntenna2 = antennas[1];
|
145
|
-
} else {
|
146
|
-
selectedAntenna2 = antennas[0]; // Use same antenna if only one available
|
147
|
-
}
|
148
|
-
|
149
|
-
await initializeChart();
|
167
|
+
// Set default antenna selection for antenna 2 (for compare mode)
|
168
|
+
if (antennas.length > 1) {
|
169
|
+
selectedAntenna2 = antennas[1];
|
170
|
+
} else {
|
171
|
+
selectedAntenna2 = antennas[0]; // Use same antenna if only one available
|
150
172
|
}
|
151
|
-
} catch (error) {
|
152
|
-
console.error('Failed to initialize:', error);
|
153
173
|
}
|
154
|
-
}
|
155
|
-
});
|
156
|
-
|
157
|
-
async function initializeChart() {
|
158
|
-
if (!Plotly || !chartDiv) return;
|
159
|
-
|
160
|
-
const data = createAntennaChartData(
|
161
|
-
selectedAntenna,
|
162
|
-
selectedAntenna2,
|
163
|
-
viewMode,
|
164
|
-
patternType === 'horizontal',
|
165
|
-
patternType === 'vertical',
|
166
|
-
ant1ElectricalTilt,
|
167
|
-
ant1MechanicalTilt,
|
168
|
-
ant2ElectricalTilt,
|
169
|
-
ant2MechanicalTilt
|
170
|
-
);
|
171
|
-
const title = generateChartTitle(viewMode, selectedAntenna, selectedAntenna2);
|
172
|
-
const layout = createChartLayout(title);
|
173
|
-
const config = createChartConfig();
|
174
|
-
|
175
|
-
try {
|
176
|
-
await Plotly.newPlot(chartDiv, data, layout, config);
|
177
|
-
chartInitialized = true;
|
178
|
-
console.log('Chart initialized with antenna controls');
|
179
174
|
} catch (error) {
|
180
|
-
console.error('Failed to
|
175
|
+
console.error('Failed to initialize:', error);
|
181
176
|
}
|
182
|
-
}
|
183
|
-
|
184
|
-
async function updateChart() {
|
185
|
-
if (!Plotly || !chartDiv || !chartInitialized) return;
|
177
|
+
});
|
186
178
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
patternType === 'vertical',
|
194
|
-
ant1ElectricalTilt,
|
195
|
-
ant1MechanicalTilt,
|
196
|
-
ant2ElectricalTilt,
|
197
|
-
ant2MechanicalTilt
|
198
|
-
);
|
199
|
-
const title = generateChartTitle(viewMode, selectedAntenna, selectedAntenna2);
|
200
|
-
await Plotly.react(chartDiv, data, createChartLayout(title));
|
201
|
-
} catch (error) {
|
202
|
-
console.error('Failed to update chart:', error);
|
179
|
+
// Generate chart title based on current selection
|
180
|
+
function generateChartTitle(): string {
|
181
|
+
if (viewMode === 'compare' && selectedAntenna && selectedAntenna2) {
|
182
|
+
return `${selectedAntenna.name} vs ${selectedAntenna2.name}`;
|
183
|
+
} else if (selectedAntenna) {
|
184
|
+
return `${selectedAntenna.name} - Pattern Analysis`;
|
203
185
|
}
|
186
|
+
return 'Antenna Pattern Analysis';
|
204
187
|
}
|
205
188
|
</script>
|
206
189
|
|
@@ -208,10 +191,10 @@
|
|
208
191
|
|
209
192
|
|
210
193
|
<!-- Viewing Mode and Pattern Visibility Controls -->
|
211
|
-
<div class="row mb-
|
212
|
-
<div class="col-md-
|
213
|
-
<div class="form-label">
|
214
|
-
<div class="btn-group w-100" role="group" aria-label="
|
194
|
+
<div class="row mb-3">
|
195
|
+
<div class="col-md-2">
|
196
|
+
<div class="form-label">View Mode:</div>
|
197
|
+
<div class="btn-group w-100" role="group" aria-label="View mode selection">
|
215
198
|
<input
|
216
199
|
type="radio"
|
217
200
|
class="btn-check"
|
@@ -219,7 +202,7 @@
|
|
219
202
|
bind:group={viewMode}
|
220
203
|
value="single"
|
221
204
|
>
|
222
|
-
<label class="btn btn-outline-primary" for="singleMode">Single
|
205
|
+
<label class="btn btn-outline-primary" for="singleMode">Single</label>
|
223
206
|
|
224
207
|
<input
|
225
208
|
type="radio"
|
@@ -232,7 +215,62 @@
|
|
232
215
|
</div>
|
233
216
|
</div>
|
234
217
|
|
235
|
-
<div class="col-md-
|
218
|
+
<div class="col-md-2">
|
219
|
+
<div class="form-label">Chart Type:</div>
|
220
|
+
<div class="btn-group w-100" role="group" aria-label="Chart type selection">
|
221
|
+
<input
|
222
|
+
type="radio"
|
223
|
+
class="btn-check"
|
224
|
+
id="polarLineChart"
|
225
|
+
bind:group={chartEngine}
|
226
|
+
value="polar-line"
|
227
|
+
>
|
228
|
+
<label class="btn btn-outline-primary" for="polarLineChart">Line</label>
|
229
|
+
|
230
|
+
<!-- <input
|
231
|
+
type="radio"
|
232
|
+
class="btn-check"
|
233
|
+
id="polarBarChart"
|
234
|
+
bind:group={chartEngine}
|
235
|
+
value="polar-bar"
|
236
|
+
>
|
237
|
+
<label class="btn btn-outline-success" for="polarBarChart">Bar</label> -->
|
238
|
+
|
239
|
+
<input
|
240
|
+
type="radio"
|
241
|
+
class="btn-check"
|
242
|
+
id="polarAreaChart"
|
243
|
+
bind:group={chartEngine}
|
244
|
+
value="polar-area"
|
245
|
+
>
|
246
|
+
<label class="btn btn-outline-primary" for="polarAreaChart">Area</label>
|
247
|
+
</div>
|
248
|
+
</div>
|
249
|
+
|
250
|
+
<div class="col-md-3">
|
251
|
+
<div class="form-label">Display Mode:</div>
|
252
|
+
<div class="btn-group w-100" role="group" aria-label="Pattern display mode selection">
|
253
|
+
<input
|
254
|
+
type="radio"
|
255
|
+
class="btn-check"
|
256
|
+
id="normalizedMode"
|
257
|
+
bind:group={patternDisplayMode}
|
258
|
+
value="normalized"
|
259
|
+
>
|
260
|
+
<label class="btn btn-outline-primary" for="normalizedMode">Pattern</label>
|
261
|
+
|
262
|
+
<input
|
263
|
+
type="radio"
|
264
|
+
class="btn-check"
|
265
|
+
id="gainAdjustedMode"
|
266
|
+
bind:group={patternDisplayMode}
|
267
|
+
value="gain-adjusted"
|
268
|
+
>
|
269
|
+
<label class="btn btn-outline-primary" for="gainAdjustedMode">+Gain</label>
|
270
|
+
</div>
|
271
|
+
</div>
|
272
|
+
|
273
|
+
<div class="col-md-2">
|
236
274
|
<div class="form-label">Pattern Type:</div>
|
237
275
|
<div class="btn-group w-100" role="group" aria-label="Pattern type selection">
|
238
276
|
<input
|
@@ -255,7 +293,7 @@
|
|
255
293
|
</div>
|
256
294
|
</div>
|
257
295
|
|
258
|
-
<div class="col-md-
|
296
|
+
<div class="col-md-3">
|
259
297
|
<div class="form-label">Actions:</div>
|
260
298
|
<button
|
261
299
|
type="button"
|
@@ -284,11 +322,50 @@
|
|
284
322
|
/>
|
285
323
|
</div>
|
286
324
|
|
287
|
-
<!-- Center Column - Chart (always centered) -->
|
325
|
+
<!-- Center Column - Chart Engine (always centered) -->
|
288
326
|
<div class="col-md-6">
|
289
327
|
<div class="card">
|
290
328
|
<div class="card-body p-1">
|
291
|
-
|
329
|
+
{#if chartEngine === 'polar-line'}
|
330
|
+
<PolarLineChart
|
331
|
+
{selectedAntenna}
|
332
|
+
{selectedAntenna2}
|
333
|
+
{viewMode}
|
334
|
+
{patternType}
|
335
|
+
{patternDisplayMode}
|
336
|
+
{ant1ElectricalTilt}
|
337
|
+
{ant1MechanicalTilt}
|
338
|
+
{ant2ElectricalTilt}
|
339
|
+
{ant2MechanicalTilt}
|
340
|
+
title={generateChartTitle()}
|
341
|
+
/>
|
342
|
+
{:else if chartEngine === 'polar-bar'}
|
343
|
+
<PolarBarChart
|
344
|
+
{selectedAntenna}
|
345
|
+
{selectedAntenna2}
|
346
|
+
{viewMode}
|
347
|
+
{patternType}
|
348
|
+
{patternDisplayMode}
|
349
|
+
{ant1ElectricalTilt}
|
350
|
+
{ant1MechanicalTilt}
|
351
|
+
{ant2ElectricalTilt}
|
352
|
+
{ant2MechanicalTilt}
|
353
|
+
title={generateChartTitle()}
|
354
|
+
/>
|
355
|
+
{:else if chartEngine === 'polar-area'}
|
356
|
+
<PolarAreaChart
|
357
|
+
{selectedAntenna}
|
358
|
+
{selectedAntenna2}
|
359
|
+
{viewMode}
|
360
|
+
{patternType}
|
361
|
+
{patternDisplayMode}
|
362
|
+
{ant1ElectricalTilt}
|
363
|
+
{ant1MechanicalTilt}
|
364
|
+
{ant2ElectricalTilt}
|
365
|
+
{ant2MechanicalTilt}
|
366
|
+
title={generateChartTitle()}
|
367
|
+
/>
|
368
|
+
{/if}
|
292
369
|
</div>
|
293
370
|
</div>
|
294
371
|
</div>
|
@@ -0,0 +1,125 @@
|
|
1
|
+
<svelte:options runes={true} />
|
2
|
+
|
3
|
+
<script lang="ts">
|
4
|
+
import { onMount } from 'svelte';
|
5
|
+
import { browser } from '$app/environment';
|
6
|
+
import type { Antenna } from '../../db';
|
7
|
+
import {
|
8
|
+
createPolarAreaChartData,
|
9
|
+
createPolarAreaLayout,
|
10
|
+
type PolarAreaTraceData
|
11
|
+
} from '../../utils/chart-engines/polar-area-utils';
|
12
|
+
|
13
|
+
interface Props {
|
14
|
+
selectedAntenna?: Antenna | null;
|
15
|
+
selectedAntenna2?: Antenna | null;
|
16
|
+
viewMode?: 'single' | 'compare';
|
17
|
+
patternType?: 'horizontal' | 'vertical';
|
18
|
+
patternDisplayMode?: 'normalized' | 'gain-adjusted';
|
19
|
+
ant1ElectricalTilt?: number;
|
20
|
+
ant1MechanicalTilt?: number;
|
21
|
+
ant2ElectricalTilt?: number;
|
22
|
+
ant2MechanicalTilt?: number;
|
23
|
+
title?: string;
|
24
|
+
}
|
25
|
+
|
26
|
+
let {
|
27
|
+
selectedAntenna = null,
|
28
|
+
selectedAntenna2 = null,
|
29
|
+
viewMode = 'single',
|
30
|
+
patternType = 'vertical',
|
31
|
+
patternDisplayMode = 'normalized',
|
32
|
+
ant1ElectricalTilt = 0,
|
33
|
+
ant1MechanicalTilt = 0,
|
34
|
+
ant2ElectricalTilt = 0,
|
35
|
+
ant2MechanicalTilt = 0,
|
36
|
+
title = 'Antenna Pattern - Polar Area Chart'
|
37
|
+
}: Props = $props();
|
38
|
+
|
39
|
+
let Plotly: any;
|
40
|
+
let chartDiv = $state<HTMLDivElement>();
|
41
|
+
let chartInitialized = $state(false);
|
42
|
+
|
43
|
+
// Initialize Plotly on mount
|
44
|
+
onMount(async () => {
|
45
|
+
if (browser) {
|
46
|
+
try {
|
47
|
+
Plotly = await import('plotly.js-dist-min');
|
48
|
+
console.log('Plotly loaded for polar area chart');
|
49
|
+
await initializeChart();
|
50
|
+
} catch (error) {
|
51
|
+
console.error('Failed to load Plotly:', error);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
});
|
55
|
+
|
56
|
+
// Update chart when data changes
|
57
|
+
$effect(() => {
|
58
|
+
if (chartInitialized) {
|
59
|
+
updateChart();
|
60
|
+
}
|
61
|
+
});
|
62
|
+
|
63
|
+
async function initializeChart() {
|
64
|
+
if (!Plotly || !chartDiv) return;
|
65
|
+
|
66
|
+
const data = createPolarAreaChartData(
|
67
|
+
selectedAntenna,
|
68
|
+
selectedAntenna2,
|
69
|
+
viewMode,
|
70
|
+
patternType === 'horizontal',
|
71
|
+
patternType === 'vertical',
|
72
|
+
ant1ElectricalTilt,
|
73
|
+
ant1MechanicalTilt,
|
74
|
+
ant2ElectricalTilt,
|
75
|
+
ant2MechanicalTilt,
|
76
|
+
patternDisplayMode
|
77
|
+
);
|
78
|
+
|
79
|
+
const layout = createPolarAreaLayout(title);
|
80
|
+
const config = {
|
81
|
+
responsive: true,
|
82
|
+
displayModeBar: true,
|
83
|
+
displaylogo: false,
|
84
|
+
modeBarButtonsToRemove: [
|
85
|
+
'zoom2d', 'pan2d', 'select2d', 'lasso2d',
|
86
|
+
'zoomIn2d', 'zoomOut2d', 'autoScale2d',
|
87
|
+
'resetScale2d', 'toggleSpikelines', 'toImage'
|
88
|
+
]
|
89
|
+
};
|
90
|
+
|
91
|
+
try {
|
92
|
+
await Plotly.newPlot(chartDiv, data, layout, config);
|
93
|
+
chartInitialized = true;
|
94
|
+
console.log('Polar area chart initialized');
|
95
|
+
} catch (error) {
|
96
|
+
console.error('Failed to create polar area chart:', error);
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
async function updateChart() {
|
101
|
+
if (!Plotly || !chartDiv || !chartInitialized) return;
|
102
|
+
|
103
|
+
try {
|
104
|
+
const data = createPolarAreaChartData(
|
105
|
+
selectedAntenna,
|
106
|
+
selectedAntenna2,
|
107
|
+
viewMode,
|
108
|
+
patternType === 'horizontal',
|
109
|
+
patternType === 'vertical',
|
110
|
+
ant1ElectricalTilt,
|
111
|
+
ant1MechanicalTilt,
|
112
|
+
ant2ElectricalTilt,
|
113
|
+
ant2MechanicalTilt,
|
114
|
+
patternDisplayMode
|
115
|
+
);
|
116
|
+
|
117
|
+
const layout = createPolarAreaLayout(title);
|
118
|
+
await Plotly.react(chartDiv, data, layout);
|
119
|
+
} catch (error) {
|
120
|
+
console.error('Failed to update polar area chart:', error);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
</script>
|
124
|
+
|
125
|
+
<div bind:this={chartDiv} style="height: 700px;"></div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import type { Antenna } from '../../db';
|
2
|
+
interface Props {
|
3
|
+
selectedAntenna?: Antenna | null;
|
4
|
+
selectedAntenna2?: Antenna | null;
|
5
|
+
viewMode?: 'single' | 'compare';
|
6
|
+
patternType?: 'horizontal' | 'vertical';
|
7
|
+
patternDisplayMode?: 'normalized' | 'gain-adjusted';
|
8
|
+
ant1ElectricalTilt?: number;
|
9
|
+
ant1MechanicalTilt?: number;
|
10
|
+
ant2ElectricalTilt?: number;
|
11
|
+
ant2MechanicalTilt?: number;
|
12
|
+
title?: string;
|
13
|
+
}
|
14
|
+
declare const PolarAreaChart: import("svelte").Component<Props, {}, "">;
|
15
|
+
type PolarAreaChart = ReturnType<typeof PolarAreaChart>;
|
16
|
+
export default PolarAreaChart;
|
@@ -0,0 +1,121 @@
|
|
1
|
+
<svelte:options runes={true} />
|
2
|
+
|
3
|
+
<script lang="ts">
|
4
|
+
import { onMount } from 'svelte';
|
5
|
+
import { browser } from '$app/environment';
|
6
|
+
import type { Antenna } from '../../db';
|
7
|
+
import {
|
8
|
+
createPolarBarChartData,
|
9
|
+
createPolarBarLayout,
|
10
|
+
type PolarBarTraceData
|
11
|
+
} from '../../utils/chart-engines/polar-bar-utils';
|
12
|
+
|
13
|
+
interface Props {
|
14
|
+
selectedAntenna?: Antenna | null;
|
15
|
+
selectedAntenna2?: Antenna | null;
|
16
|
+
viewMode?: 'single' | 'compare';
|
17
|
+
patternType?: 'horizontal' | 'vertical';
|
18
|
+
ant1ElectricalTilt?: number;
|
19
|
+
ant1MechanicalTilt?: number;
|
20
|
+
ant2ElectricalTilt?: number;
|
21
|
+
ant2MechanicalTilt?: number;
|
22
|
+
title?: string;
|
23
|
+
}
|
24
|
+
|
25
|
+
let {
|
26
|
+
selectedAntenna = null,
|
27
|
+
selectedAntenna2 = null,
|
28
|
+
viewMode = 'single',
|
29
|
+
patternType = 'vertical',
|
30
|
+
ant1ElectricalTilt = 0,
|
31
|
+
ant1MechanicalTilt = 0,
|
32
|
+
ant2ElectricalTilt = 0,
|
33
|
+
ant2MechanicalTilt = 0,
|
34
|
+
title = 'Antenna Pattern - Polar Bar Chart'
|
35
|
+
}: Props = $props();
|
36
|
+
|
37
|
+
let Plotly: any;
|
38
|
+
let chartDiv = $state<HTMLDivElement>();
|
39
|
+
let chartInitialized = $state(false);
|
40
|
+
|
41
|
+
// Initialize Plotly on mount
|
42
|
+
onMount(async () => {
|
43
|
+
if (browser) {
|
44
|
+
try {
|
45
|
+
Plotly = await import('plotly.js-dist-min');
|
46
|
+
console.log('Plotly loaded for polar bar chart');
|
47
|
+
await initializeChart();
|
48
|
+
} catch (error) {
|
49
|
+
console.error('Failed to load Plotly:', error);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
});
|
53
|
+
|
54
|
+
// Update chart when data changes
|
55
|
+
$effect(() => {
|
56
|
+
if (chartInitialized) {
|
57
|
+
updateChart();
|
58
|
+
}
|
59
|
+
});
|
60
|
+
|
61
|
+
async function initializeChart() {
|
62
|
+
if (!Plotly || !chartDiv) return;
|
63
|
+
|
64
|
+
const data = createPolarBarChartData(
|
65
|
+
selectedAntenna,
|
66
|
+
selectedAntenna2,
|
67
|
+
viewMode,
|
68
|
+
patternType === 'horizontal',
|
69
|
+
patternType === 'vertical',
|
70
|
+
ant1ElectricalTilt,
|
71
|
+
ant1MechanicalTilt,
|
72
|
+
ant2ElectricalTilt,
|
73
|
+
ant2MechanicalTilt
|
74
|
+
);
|
75
|
+
|
76
|
+
const layout = createPolarBarLayout(title);
|
77
|
+
const config = {
|
78
|
+
responsive: true,
|
79
|
+
displayModeBar: true,
|
80
|
+
displaylogo: false,
|
81
|
+
modeBarButtonsToRemove: [
|
82
|
+
'zoom2d', 'pan2d', 'select2d', 'lasso2d',
|
83
|
+
'zoomIn2d', 'zoomOut2d', 'autoScale2d',
|
84
|
+
'resetScale2d', 'toggleSpikelines', 'toImage'
|
85
|
+
]
|
86
|
+
};
|
87
|
+
|
88
|
+
try {
|
89
|
+
await Plotly.newPlot(chartDiv, data, layout, config);
|
90
|
+
chartInitialized = true;
|
91
|
+
console.log('Polar bar chart initialized');
|
92
|
+
} catch (error) {
|
93
|
+
console.error('Failed to create polar bar chart:', error);
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
async function updateChart() {
|
98
|
+
if (!Plotly || !chartDiv || !chartInitialized) return;
|
99
|
+
|
100
|
+
try {
|
101
|
+
const data = createPolarBarChartData(
|
102
|
+
selectedAntenna,
|
103
|
+
selectedAntenna2,
|
104
|
+
viewMode,
|
105
|
+
patternType === 'horizontal',
|
106
|
+
patternType === 'vertical',
|
107
|
+
ant1ElectricalTilt,
|
108
|
+
ant1MechanicalTilt,
|
109
|
+
ant2ElectricalTilt,
|
110
|
+
ant2MechanicalTilt
|
111
|
+
);
|
112
|
+
|
113
|
+
const layout = createPolarBarLayout(title);
|
114
|
+
await Plotly.react(chartDiv, data, layout);
|
115
|
+
} catch (error) {
|
116
|
+
console.error('Failed to update polar bar chart:', error);
|
117
|
+
}
|
118
|
+
}
|
119
|
+
</script>
|
120
|
+
|
121
|
+
<div bind:this={chartDiv} style="height: 700px;"></div>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import type { Antenna } from '../../db';
|
2
|
+
interface Props {
|
3
|
+
selectedAntenna?: Antenna | null;
|
4
|
+
selectedAntenna2?: Antenna | null;
|
5
|
+
viewMode?: 'single' | 'compare';
|
6
|
+
patternType?: 'horizontal' | 'vertical';
|
7
|
+
ant1ElectricalTilt?: number;
|
8
|
+
ant1MechanicalTilt?: number;
|
9
|
+
ant2ElectricalTilt?: number;
|
10
|
+
ant2MechanicalTilt?: number;
|
11
|
+
title?: string;
|
12
|
+
}
|
13
|
+
declare const PolarBarChart: import("svelte").Component<Props, {}, "">;
|
14
|
+
type PolarBarChart = ReturnType<typeof PolarBarChart>;
|
15
|
+
export default PolarBarChart;
|