@mytec: color-range-save fixes iteration1
This commit is contained in:
251
RFCP-Fixes-Iteration1.md
Normal file
251
RFCP-Fixes-Iteration1.md
Normal file
@@ -0,0 +1,251 @@
|
||||
# RFCP Fixes - Iteration 1
|
||||
|
||||
## Issues to Fix:
|
||||
|
||||
### 1. Heatmap Colors - More Obvious Gradient
|
||||
|
||||
**Current problem:** Green→Yellow→Red gradient not obvious enough
|
||||
|
||||
**Fix:** Update `src/components/map/Heatmap.tsx`
|
||||
|
||||
Change the gradient to use more distinct colors with better visibility:
|
||||
|
||||
```typescript
|
||||
// In Heatmap.tsx, update the gradient prop:
|
||||
|
||||
<HeatmapLayer
|
||||
points={heatmapPoints}
|
||||
longitudeExtractor={(p: any) => p[1]}
|
||||
latitudeExtractor={(p: any) => p[0]}
|
||||
intensityExtractor={(p: any) => p[2]}
|
||||
gradient={{
|
||||
0.0: '#0000ff', // Blue (very weak, -120 dBm)
|
||||
0.2: '#00ffff', // Cyan (weak, -110 dBm)
|
||||
0.4: '#00ff00', // Green (fair, -100 dBm)
|
||||
0.6: '#ffff00', // Yellow (good, -85 dBm)
|
||||
0.8: '#ff7f00', // Orange (strong, -70 dBm)
|
||||
1.0: '#ff0000', // Red (excellent, > -70 dBm)
|
||||
}}
|
||||
radius={25}
|
||||
blur={15}
|
||||
max={1.0}
|
||||
/>
|
||||
```
|
||||
|
||||
**Reasoning:**
|
||||
- Blue/Cyan for weak signals (more intuitive - "cold" = weak)
|
||||
- Green for acceptable
|
||||
- Yellow/Orange for good
|
||||
- Red for excellent (hot = strong)
|
||||
|
||||
This is actually inverted from typical "green=good", but in RF planning, RED = STRONG SIGNAL = GOOD!
|
||||
|
||||
---
|
||||
|
||||
### 2. Coverage Radius - Increase to 100km
|
||||
|
||||
**Current problem:** Max radius only 20km, not enough for tactical planning
|
||||
|
||||
**Fix:** Update `src/components/panels/SiteForm.tsx` (or wherever Coverage Settings are)
|
||||
|
||||
Find the radius slider and change:
|
||||
|
||||
```typescript
|
||||
// Old:
|
||||
<Slider
|
||||
label="Radius (km)"
|
||||
min={1}
|
||||
max={20} // ← Change this
|
||||
step={1}
|
||||
value={coverageSettings.radius}
|
||||
onChange={(value) => updateCoverageSettings({ radius: value })}
|
||||
/>
|
||||
|
||||
// New:
|
||||
<Slider
|
||||
label="Radius (km)"
|
||||
min={1}
|
||||
max={100} // ← Increased to 100km
|
||||
step={5} // ← Larger step for easier control
|
||||
value={coverageSettings.radius}
|
||||
onChange={(value) => updateCoverageSettings({ radius: value })}
|
||||
help="Calculation area around each site"
|
||||
/>
|
||||
```
|
||||
|
||||
**Also update default value in store:**
|
||||
|
||||
```typescript
|
||||
// In src/store/coverage.ts or wherever coverage settings are initialized:
|
||||
const initialSettings = {
|
||||
radius: 10, // Default 10km (reasonable starting point)
|
||||
resolution: 200, // 200m resolution
|
||||
rsrpThreshold: -120
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Save & Calculate Button
|
||||
|
||||
**Current problem:** Two separate buttons, extra click needed
|
||||
|
||||
**Fix:** Update `src/components/panels/SiteForm.tsx`
|
||||
|
||||
Replace the button section:
|
||||
|
||||
```typescript
|
||||
// Old:
|
||||
<div className="flex gap-2">
|
||||
<Button onClick={handleSave}>Save</Button>
|
||||
<Button onClick={handleDelete} variant="danger">Delete</Button>
|
||||
</div>
|
||||
|
||||
// New:
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
onClick={handleSaveAndCalculate}
|
||||
variant="primary"
|
||||
className="flex-1"
|
||||
>
|
||||
💾 Save & Calculate Coverage
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleSave}
|
||||
variant="secondary"
|
||||
className="flex-1"
|
||||
>
|
||||
💾 Save Only
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleDelete}
|
||||
variant="danger"
|
||||
>
|
||||
🗑️ Delete
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
// Add the handler:
|
||||
const handleSaveAndCalculate = async () => {
|
||||
// Save the site first
|
||||
await handleSave();
|
||||
|
||||
// Then trigger coverage calculation
|
||||
const sites = useSitesStore.getState().sites;
|
||||
const coverage = useCoverageStore.getState();
|
||||
|
||||
// Calculate coverage for all sites
|
||||
await coverage.calculateCoverage(sites);
|
||||
|
||||
// Show success toast
|
||||
toast.success('Site saved and coverage calculated!');
|
||||
};
|
||||
```
|
||||
|
||||
**Alternative (simpler):** Just make the main button do both:
|
||||
|
||||
```typescript
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
onClick={async () => {
|
||||
await handleSave();
|
||||
// Auto-trigger calculate after save
|
||||
const sites = useSitesStore.getState().sites;
|
||||
await useCoverageStore.getState().calculateCoverage(sites);
|
||||
}}
|
||||
variant="primary"
|
||||
className="flex-1"
|
||||
>
|
||||
💾 Save & Calculate
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleDelete}
|
||||
variant="danger"
|
||||
>
|
||||
🗑️ Delete
|
||||
</Button>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Legend Colors Update
|
||||
|
||||
**Fix:** Update `src/components/map/Legend.tsx` to match new gradient:
|
||||
|
||||
```typescript
|
||||
const signalRanges = [
|
||||
{ label: 'Excellent', range: '> -70 dBm', color: '#ff0000' }, // Red
|
||||
{ label: 'Good', range: '-70 to -85 dBm', color: '#ff7f00' }, // Orange
|
||||
{ label: 'Fair', range: '-85 to -100 dBm', color: '#ffff00' }, // Yellow
|
||||
{ label: 'Poor', range: '-100 to -110 dBm', color: '#00ff00' }, // Green
|
||||
{ label: 'Weak', range: '-110 to -120 dBm', color: '#00ffff' }, // Cyan
|
||||
{ label: 'Very Weak', range: '< -120 dBm', color: '#0000ff' }, // Blue
|
||||
];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Resolution Adjustment for Large Radius
|
||||
|
||||
**Problem:** 200m resolution + 100km radius = MANY points = slow calculation
|
||||
|
||||
**Fix:** Auto-adjust resolution based on radius:
|
||||
|
||||
```typescript
|
||||
// In src/store/coverage.ts or coverage calculator:
|
||||
|
||||
const getOptimalResolution = (radius: number): number => {
|
||||
if (radius <= 10) return 100; // 100m for small areas
|
||||
if (radius <= 30) return 200; // 200m for medium areas
|
||||
if (radius <= 60) return 300; // 300m for large areas
|
||||
return 500; // 500m for very large areas (100km)
|
||||
};
|
||||
|
||||
// Use in calculation:
|
||||
const resolution = settings.resolution || getOptimalResolution(settings.radius);
|
||||
```
|
||||
|
||||
Or add a notice in UI:
|
||||
|
||||
```typescript
|
||||
<p className="text-sm text-gray-500">
|
||||
💡 Larger radius = longer calculation time.
|
||||
Consider increasing resolution (200m → 500m) for faster results.
|
||||
</p>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary of Changes:
|
||||
|
||||
1. ✅ **Heatmap gradient:** Blue → Cyan → Green → Yellow → Orange → Red
|
||||
2. ✅ **Max radius:** 20km → 100km (step: 5km)
|
||||
3. ✅ **Button:** "Save & Calculate" as primary action
|
||||
4. ✅ **Legend:** Updated colors to match new gradient
|
||||
5. ✅ **Performance:** Auto-adjust resolution or show warning
|
||||
|
||||
---
|
||||
|
||||
## Implementation Order:
|
||||
|
||||
1. **Start with colors** (easiest, biggest visual impact)
|
||||
2. **Then radius** (simple slider change)
|
||||
3. **Then button** (requires store integration)
|
||||
4. **Test everything**
|
||||
|
||||
---
|
||||
|
||||
## Files to Edit:
|
||||
|
||||
```
|
||||
frontend/src/components/map/Heatmap.tsx - gradient colors
|
||||
frontend/src/components/map/Legend.tsx - legend colors
|
||||
frontend/src/components/panels/SiteForm.tsx - radius slider + button
|
||||
frontend/src/store/coverage.ts - default settings
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Would you like me to create the exact code patches for Claude Code to apply?
|
||||
Or should I create complete replacement files?
|
||||
6
package-lock.json
generated
Normal file
6
package-lock.json
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "rfcp",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {}
|
||||
}
|
||||
Reference in New Issue
Block a user