Skip to content

Commit 9412b85

Browse files
authored
Merge pull request #4 from danylaksono/placements
new examples for creative coding
2 parents 79ac66e + be17d3b commit 9412b85

File tree

6 files changed

+1391
-14
lines changed

6 files changed

+1391
-14
lines changed

README.md

Lines changed: 232 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,22 @@ This library is inspired by Aidan Slingsby's [Gridded Glyphmaps](https://openacc
1111
## 🚀 Features
1212

1313
- **Real-time Aggregation**: Efficiently aggregates point data into screen-space grids
14+
- **Multiple Aggregation Modes**: Support for rectangular grids (`screen-grid`) and hexagonal tessellation (`screen-hex`)
1415
- **Customizable Styling**: Flexible color scales and cell sizing
1516
- **Interactive Events**: Hover and click handlers for grid cells
1617
- **Glyph Drawing**: Custom glyph rendering with Canvas 2D for advanced visualizations
1718
- **Plugin Ecosystem**: Reusable, named glyph plugins with registry system, lifecycle hooks, and legend integration
1819
- **Built-in Plugins**: Four ready-to-use plugins (`circle`, `bar`, `pie`, `heatmap`) plus utilities for custom plugins
20+
- **Flexible Aggregation Functions**: Built-in functions (sum, mean, count, max, min) with registry system for custom functions
21+
- **Customizable Normalization**: Multiple normalization strategies (max-local, max-global, z-score, percentile) with registry for custom functions
1922
- **MapLibre Integration**: Seamless integration with MapLibre GL JS
2023
- **Performance Optimized**: Uses Canvas 2D rendering for optimal performance
2124
- **Responsive Design**: Automatically adjusts to map viewport changes
2225
- **Zoom-based Sizing**: Dynamic cell size adjustment based on zoom level
2326
- **Multi-attribute Visualization**: Support for visualizing multiple data attributes per cell
24-
- **Geometry Input (NEW)**: Accept GeoJSON `source` with `placement` strategies for Polygon/Line inputs
25-
- **Feature Anchors (NEW)**: Render one glyph per feature anchor with `renderMode: 'feature-anchors'`
27+
- **Geometry Input**: Accept GeoJSON `source` with `placement` strategies for Polygon/Line inputs
28+
- **Feature Anchors**: Render one glyph per feature anchor with `renderMode: 'feature-anchors'`
29+
- **Debug Logging**: Configurable debug logging system for troubleshooting
2630

2731
## 📁 Project Structure
2832

@@ -359,6 +363,10 @@ npx http-server -p 8000
359363
6. **Multivariate Time Series** (`examples/multivariate-timeseries.html`) - Advanced multi-attribute temporal visualization
360364
7. **Plugin Glyph** (`examples/plugin-glyph.html`) - Complete plugin ecosystem example with custom `grouped-bar` plugin, lifecycle hooks, and legend integration
361365
8. **Data Utilities** (`examples/data-utilities.html`) - Demonstrates data utility functions (`groupBy`, `extractAttributes`, `computeStats`, `groupByTime`)
366+
9. **Hex Mode** (`examples/hex-mode.html`) - Hexagonal aggregation mode with interactive controls
367+
10. **Hex Mode Simple** (`examples/hex-mode-simple.html`) - Simple hexagonal aggregation example
368+
11. **US States** (`examples/us-states.html`) - Geometry input example with polygon features
369+
12. **Creative Coding** (`examples/creative-coding.html`) - Artistic visualizations: mosaic tiles, tessellations, particles, and abstract patterns demonstrating the library's creative coding capabilities
362370

363371
### Example Features
364372

@@ -395,18 +403,103 @@ npx http-server -p 8000
395403
| `aggregationFunction` | Function\|string | `'sum'` | Aggregation function or name (see [Aggregation Functions](#-aggregation-functions)) |
396404
| `normalizationFunction` | Function\|string | `'max-local'` | Normalization function or name (see [Normalization Functions](#-normalization-functions)) |
397405
| `normalizationContext` | object | `{}` | Additional context for normalization (e.g., `{globalMax: 1000}`) |
406+
| `aggregationMode` | string | `'screen-grid'` | Aggregation mode: `'screen-grid'` (rectangular) or `'screen-hex'` (hexagonal) |
407+
| `aggregationModeConfig` | object | `{}` | Mode-specific configuration (e.g., `{hexSize: 50, showBackground: true}` for hex mode) |
398408
| `adaptiveCellSize` | boolean | `false` | Enable adaptive cell sizing |
399409
| `minCellSize` | number | `20` | Minimum cell size in pixels |
400410
| `maxCellSize` | number | `100` | Maximum cell size in pixels |
401411
| `zoomBasedSize` | boolean | `false` | Adjust cell size based on zoom level |
402412
| `enabled` | boolean | `true` | Whether the layer is enabled |
413+
| `debugLogs` | boolean | `false` | Enable verbose debug logging (useful for troubleshooting) |
403414
| `source` | GeoJSON | `null` | GeoJSON Feature/FeatureCollection or array of Features (mutually exclusive with `data`) |
404415
| `placement` | object | `null` | Placement config to derive anchors from geometries (see docs) |
405416
| `renderMode` | `'screen-grid'|'feature-anchors'` | `'screen-grid'` | Rendering path (aggregate vs draw directly) |
406417
| `anchorSizePixels` | number | `auto` | Glyph size in pixels for `feature-anchors` mode |
407418

408419
See `docs/GEOMETRY_INPUT_AND_PLACEMENT.md` and `docs/PLACEMENT_CONFIG.md` for geometry input, placement strategies, and validation rules.
409420

421+
## 🔷 Aggregation Modes
422+
423+
ScreenGrid supports multiple aggregation modes for different visualization needs. The default mode is `screen-grid` (rectangular cells), but you can also use `screen-hex` for hexagonal tessellation.
424+
425+
### Available Modes
426+
427+
#### `screen-grid` (Default)
428+
Rectangular grid cells aligned to screen pixels. This is the classic ScreenGrid behavior.
429+
430+
```javascript
431+
const layer = new ScreenGridLayerGL({
432+
data: myData,
433+
aggregationMode: 'screen-grid', // Default, can be omitted
434+
cellSizePixels: 50
435+
});
436+
```
437+
438+
#### `screen-hex`
439+
Hexagonal tessellation in screen space. Provides a more organic, visually appealing grid pattern.
440+
441+
```javascript
442+
const layer = new ScreenGridLayerGL({
443+
data: myData,
444+
aggregationMode: 'screen-hex',
445+
aggregationModeConfig: {
446+
hexSize: 50, // Size of hexagons (similar to cellSizePixels)
447+
showBackground: true // Show colored hexagon backgrounds
448+
}
449+
});
450+
```
451+
452+
### Mode Configuration
453+
454+
Each mode can have mode-specific configuration via `aggregationModeConfig`:
455+
456+
**For `screen-hex`:**
457+
- `hexSize` (number): Size of hexagons in pixels (defaults to `cellSizePixels` if not provided)
458+
- `showBackground` (boolean): Whether to show colored hexagon backgrounds (default: `false` when glyphs are enabled)
459+
460+
**For `screen-grid`:**
461+
- `showBackground` (boolean): Whether to show colored cell backgrounds (default: `false` when glyphs are enabled)
462+
463+
### Custom Aggregation Modes
464+
465+
You can register custom aggregation modes using the `AggregationModeRegistry`:
466+
467+
```javascript
468+
import { AggregationModeRegistry } from 'screengrid';
469+
470+
const MyCustomMode = {
471+
name: 'my-custom-mode',
472+
type: 'screen-space', // or 'geographic'
473+
aggregate(data, getPosition, getWeight, map, config) {
474+
// Custom aggregation logic
475+
return aggregationResult;
476+
},
477+
render(aggregationResult, ctx, config, map) {
478+
// Custom rendering logic
479+
},
480+
getCellAt(point, aggregationResult, map) {
481+
// Custom cell query logic
482+
return cellInfo;
483+
},
484+
getStats(aggregationResult) {
485+
// Optional: custom statistics
486+
return stats;
487+
},
488+
needsUpdateOnZoom() { return true; },
489+
needsUpdateOnMove() { return true; }
490+
};
491+
492+
AggregationModeRegistry.register('my-custom-mode', MyCustomMode);
493+
494+
// Use it
495+
const layer = new ScreenGridLayerGL({
496+
data: myData,
497+
aggregationMode: 'my-custom-mode'
498+
});
499+
```
500+
501+
See `examples/hex-mode.html` and `examples/hex-mode-simple.html` for complete examples of hexagonal aggregation.
502+
410503
## 📊 Aggregation Functions
411504

412505
ScreenGrid supports flexible aggregation functions that determine how multiple data points within a cell are combined. You can use built-in functions or provide custom functions.
@@ -620,6 +713,109 @@ GlyphRegistry.clear()
620713

621714
See [Plugin Ecosystem](#-plugin-ecosystem) section above for detailed usage examples.
622715

716+
### AggregationModeRegistry API
717+
718+
The `AggregationModeRegistry` manages aggregation mode plugins:
719+
720+
```javascript
721+
import { AggregationModeRegistry } from 'screengrid';
722+
723+
// Register a custom mode
724+
AggregationModeRegistry.register(name, modePlugin, { overwrite = false })
725+
726+
// Retrieve a mode
727+
AggregationModeRegistry.get(name)
728+
729+
// Check if mode exists
730+
AggregationModeRegistry.has(name)
731+
732+
// List all registered modes
733+
AggregationModeRegistry.list()
734+
735+
// Unregister a mode
736+
AggregationModeRegistry.unregister(name)
737+
```
738+
739+
### Logger API
740+
741+
The `Logger` utility provides controlled debug logging:
742+
743+
```javascript
744+
import { Logger, setDebug } from 'screengrid';
745+
746+
// Enable/disable debug logging globally
747+
setDebug(true);
748+
749+
// Use logger (logs only when debug is enabled)
750+
Logger.log('Debug message');
751+
Logger.warn('Warning message');
752+
Logger.error('Error message'); // Always shown, even when debug is disabled
753+
```
754+
755+
**Note:** Debug logging can also be controlled via the `debugLogs` configuration option.
756+
757+
## 📦 Exported Modules & Utilities
758+
759+
The library exports various modules and utilities that you can use independently:
760+
761+
### Core Classes
762+
- `ScreenGridLayerGL` - Main layer class
763+
- `Aggregator` - Pure aggregation logic
764+
- `Projector` - Coordinate projection utilities
765+
- `CellQueryEngine` - Spatial query engine
766+
767+
### Aggregation & Normalization
768+
- `AggregationModeRegistry` - Registry for aggregation modes
769+
- `ScreenGridMode` - Rectangular grid mode
770+
- `ScreenHexMode` - Hexagonal grid mode
771+
- `AggregationFunctionRegistry` - Registry for aggregation functions
772+
- `AggregationFunctions` - Built-in aggregation functions (sum, mean, count, max, min)
773+
- `NormalizationFunctionRegistry` - Registry for normalization functions
774+
- `NormalizationFunctions` - Built-in normalization functions (max-local, max-global, z-score, percentile)
775+
776+
### Glyphs & Plugins
777+
- `GlyphUtilities` - Low-level glyph drawing utilities
778+
- `GlyphRegistry` - Registry for glyph plugins
779+
780+
### Geometry & Placement
781+
- `PlacementEngine` - Geometry placement engine
782+
- `PlacementValidator` - Placement configuration validator
783+
- `PlacementStrategyRegistry` - Registry for placement strategies
784+
- `GeometryUtils` - Geometry utility functions
785+
786+
### Canvas & Rendering
787+
- `CanvasManager` - Canvas lifecycle management
788+
- `Renderer` - Rendering logic
789+
790+
### Events
791+
- `EventBinder` - Event binding management
792+
- `EventHandlers` - Event handler implementations
793+
794+
### Configuration & Utilities
795+
- `ConfigManager` - Configuration management
796+
- `Logger` - Debug logging utility
797+
- `setDebug` - Enable/disable debug logging
798+
- `groupBy` - Group data by categories
799+
- `extractAttributes` - Extract multiple attributes
800+
- `computeStats` - Compute statistics
801+
- `groupByTime` - Group data by time periods
802+
803+
### Legend
804+
- `Legend` - Legend class
805+
- `LegendDataExtractor` - Legend data extraction
806+
- `LegendRenderers` - Legend rendering utilities
807+
808+
**Example:**
809+
```javascript
810+
import {
811+
ScreenGridLayerGL,
812+
AggregationModeRegistry,
813+
GlyphRegistry,
814+
Logger,
815+
setDebug
816+
} from 'screengrid';
817+
```
818+
623819
## 📊 Legend Module
624820

625821
The library includes a powerful Legend module for automatically generating data-driven legends:
@@ -660,12 +856,32 @@ See `examples/legend-example.html` for detailed usage examples.
660856

661857
### Debug Mode
662858

663-
Enable debug logging by opening browser console. The library provides detailed logging for:
859+
Enable debug logging via the `debugLogs` configuration option:
860+
861+
```javascript
862+
const layer = new ScreenGridLayerGL({
863+
data: myData,
864+
debugLogs: true // Enable verbose debug logging
865+
});
866+
```
867+
868+
Or programmatically:
869+
870+
```javascript
871+
import { setDebug } from 'screengrid';
872+
873+
setDebug(true); // Enable debug logging globally
874+
```
875+
876+
The library provides detailed logging for:
664877
- Layer initialization
665878
- Data aggregation
666879
- Rendering process
880+
- Event handling
667881
- Error states
668882

883+
**Note:** Debug logs are disabled by default for performance. Enable only when troubleshooting.
884+
669885
## 👤 Author
670886

671887
**dany laksono**
@@ -684,12 +900,24 @@ MIT License - see LICENSE file for details.
684900

685901
## 📝 Changelog
686902

687-
### v2.1.0 (Upcoming)
903+
### v2.2.0 (Current)
904+
- **NEW**: Hexagonal aggregation mode (`screen-hex`) for organic, visually appealing grid patterns
905+
- **NEW**: Aggregation mode registry system (`AggregationModeRegistry`) for extensible aggregation strategies
906+
- **NEW**: Mode-specific configuration via `aggregationModeConfig` option
907+
- **IMPROVED**: Better separation between aggregation logic and rendering logic
908+
- **IMPROVED**: Enhanced examples with hex mode demonstrations
909+
910+
### v2.1.0
688911
- **NEW**: Aggregation function registry system with built-in functions (sum, mean, count, max, min)
689912
- **NEW**: Normalization function registry system with built-in strategies (max-local, max-global, z-score, percentile)
690913
- **NEW**: Support for custom aggregation functions (including multi-attribute aggregation)
691914
- **NEW**: Support for custom normalization functions
915+
- **NEW**: Geometry Input & Placement: Support for non-point geometries (Polygons, Lines) via `source` option and placement strategies
916+
- **NEW**: Feature Anchors Rendering Mode: `renderMode: 'feature-anchors'` for drawing glyphs directly at anchor positions
917+
- **NEW**: Data Utilities: Utility functions (`groupBy`, `extractAttributes`, `computeStats`, `groupByTime`) for data processing
918+
- **NEW**: Logger utility with configurable debug logging (`debugLogs` option)
692919
- **IMPROVED**: Enhanced flexibility for data aggregation and normalization strategies
920+
- **IMPROVED**: Enhanced documentation and examples
693921
- **IMPROVED**: Backward compatible - defaults preserve existing behavior
694922

695923
### v2.0.0

0 commit comments

Comments
 (0)