Use zoom-relative density coloring with warm palette

- Density thresholds now scale with zoom level:
  zoom 3: ~600 = high, zoom 7: ~150 = high, zoom 11: ~40 = high
- Warm color palette: green -> lime -> gold -> amber -> burnt orange
- 20% transparency on all dots for softer appearance
- Softer borders and shadows on dots

This makes the same property count appear as "low density" when
zoomed out (seeing 25k properties) but "high density" when zoomed
in (seeing only nearby properties).

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Hanson.xyz Dev
2025-12-16 01:04:16 -06:00
parent 7c3c322449
commit 8c44e07bc4
4 changed files with 47 additions and 26 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -173,18 +173,19 @@
}, },
/** /**
* Render density dots (zoom 8-11) * Render density dots (zoom 1-11)
* Small colored circles based on property count * Small colored circles with zoom-relative density coloring
*/ */
renderDensity: function(dots) { renderDensity: function(dots) {
this.clearAllLayers(); this.clearAllLayers();
var self = this; var self = this;
var zoom = this.map.getZoom();
dots.forEach(function(dot) { dots.forEach(function(dot) {
// Determine color based on count // Determine color based on count AND zoom (relative density)
var color = self.getDensityColor(dot.count); var color = self.getDensityColor(dot.count, zoom);
var size = self.getDensitySize(dot.count); var size = self.getDensitySize(dot.count, zoom);
var icon = L.divIcon({ var icon = L.divIcon({
html: '<div class="density-dot" style="background-color: ' + color + '; width: ' + size + 'px; height: ' + size + 'px;"></div>', html: '<div class="density-dot" style="background-color: ' + color + '; width: ' + size + 'px; height: ' + size + 'px;"></div>',
@@ -210,25 +211,44 @@
}, },
/** /**
* Get color for density dot based on count * Get zoom-relative density threshold
* At low zoom (seeing whole state), 500 is "high density"
* At high zoom (seeing city), 20 is "high density"
*/ */
getDensityColor: function(count) { getDensityThreshold: function(zoom) {
if (count >= 200) return '#dc2626'; // dark red // Baseline thresholds scale with zoom level
if (count >= 100) return '#ef4444'; // red // zoom 3: 600, zoom 5: 300, zoom 7: 150, zoom 9: 75, zoom 11: 40
if (count >= 50) return '#f97316'; // orange return Math.max(40, Math.round(600 / Math.pow(1.4, zoom - 3)));
if (count >= 20) return '#eab308'; // yellow
if (count >= 10) return '#84cc16'; // lime
return '#22c55e'; // green
}, },
/** /**
* Get size for density dot based on count * Get color for density dot based on count relative to zoom
* Uses warm palette: green -> lime -> gold -> amber -> burnt orange
*/ */
getDensitySize: function(count) { getDensityColor: function(count, zoom) {
if (count >= 200) return 12; var threshold = this.getDensityThreshold(zoom);
if (count >= 100) return 10; var ratio = count / threshold;
if (count >= 50) return 8;
if (count >= 20) return 7; // Warm color palette with 80% opacity (20% transparency)
if (ratio >= 1.5) return 'rgba(180, 83, 9, 0.8)'; // burnt orange (high)
if (ratio >= 1.0) return 'rgba(217, 119, 6, 0.8)'; // dark amber
if (ratio >= 0.6) return 'rgba(245, 158, 11, 0.8)'; // amber
if (ratio >= 0.3) return 'rgba(234, 179, 8, 0.8)'; // gold/yellow
if (ratio >= 0.15) return 'rgba(132, 204, 22, 0.8)'; // lime
return 'rgba(34, 197, 94, 0.8)'; // green (low)
},
/**
* Get size for density dot based on count relative to zoom
*/
getDensitySize: function(count, zoom) {
var threshold = this.getDensityThreshold(zoom);
var ratio = count / threshold;
if (ratio >= 1.5) return 11;
if (ratio >= 1.0) return 10;
if (ratio >= 0.6) return 8;
if (ratio >= 0.3) return 7;
return 6; return 6;
}, },
@@ -315,7 +315,7 @@
} }
} }
// Density dots (zoom 8-11) // Density dots (zoom 1-11)
.density-dot-container { .density-dot-container {
background: transparent !important; background: transparent !important;
border: none !important; border: none !important;
@@ -323,13 +323,14 @@
.density-dot { .density-dot {
border-radius: 50%; border-radius: 50%;
border: 1px solid rgba(0, 0, 0, 0.3); border: 1px solid rgba(0, 0, 0, 0.15);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
cursor: pointer; cursor: pointer;
transition: transform 0.1s ease; transition: transform 0.15s ease, box-shadow 0.15s ease;
&:hover { &:hover {
transform: scale(1.3); transform: scale(1.4);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
} }
} }