diff --git a/generative/frontend/jwebmp/agcharts-enterprise/README.md b/generative/frontend/jwebmp/agcharts-enterprise/README.md index 495aae8..443e1cf 100644 --- a/generative/frontend/jwebmp/agcharts-enterprise/README.md +++ b/generative/frontend/jwebmp/agcharts-enterprise/README.md @@ -10,7 +10,9 @@ What this covers - Troubleshooting and diagnostics Quick links +- **[NEW] Release Notes v2.0.0** — ./RELEASE_NOTES_v2.0.0.md - Plugin overview and integration — ./agcharts-enterprise-integration.rules.md +- Grid ↔ Charts Data Binding — ./grid-data-binding.rules.md - Page Configurator — ./page-configurator.rules.md - Licensing & Activation — ./licensing-and-activation.rules.md - Java Usage Guide (Java-only) — ./java-usage-guide.rules.md diff --git a/generative/frontend/jwebmp/agcharts-enterprise/RELEASE_NOTES_v2.0.0.md b/generative/frontend/jwebmp/agcharts-enterprise/RELEASE_NOTES_v2.0.0.md new file mode 100644 index 0000000..7ccf3bb --- /dev/null +++ b/generative/frontend/jwebmp/agcharts-enterprise/RELEASE_NOTES_v2.0.0.md @@ -0,0 +1,255 @@ +# AG Grid Enterprise + AG Charts Enterprise v2.0.0 Release Notes + +## Overview +Version 2.0.0 introduces **Grid-to-Charts Data Binding** — a comprehensive framework for synchronizing AG Grid data with AG Charts Enterprise, enabling coordinated dashboards with cross-filtering and selection sync. + +## New Features + +### Grid ↔ Charts Data Binding +- **Unified Data Model**: Single data source powers both grid and charts with automatic synchronization. +- **Cross-Filtering**: Chart interactions filter grid rows; grid filters update charts in real-time. +- **Selection Sync**: Grid row selection highlights corresponding chart data points and vice versa. +- **Custom Data Bridges**: Implement `IChartDataBridge` for domain-specific data transformations and coordination logic. +- **Registry Pattern**: Centralized `ChartRegistry` manages chart instances, relationships, and event lifecycle. + +### Core Components (New) + +#### `IChartDataBridge` +Abstraction layer for bidirectional data synchronization: +- Generic over row data type (POJO, Map, custom types) +- Methods: `getGridRowData()`, `onGridDataChanged()`, `onGridSelectionChanged()`, `onChartInteraction()` +- Field mapping support for grid column → chart property projection +- Listener pattern for chart interaction events + +#### `ChartConfiguration` +Metadata container for chart-grid relationships: +- 58 fluent properties for complete chart customization +- Chart ID, type, title, themes +- Data bridge and grid references +- Field mapping configuration +- Feature flags: enableCrossFiltering, enableSelectionSync +- Theme overrides and custom options + +#### `ChartRegistry` +Singleton registry for lifecycle and relationship management: +- Thread-safe with ConcurrentHashMap +- Manages chart registration, data bridges, and grid-chart linking +- Event listener support for chart lifecycle +- Retrieve linked charts by grid ID + +### AgGridEnterprise Helper Methods +Five new fluent methods for simplified chart integration: + +1. **`linkCharts(String... chartIds)`** — Link pre-registered charts by ID +2. **`registerAndLinkChart(ChartConfiguration config)`** — Create and link atomically +3. **`enableChartCrossFiltering()`** — Activate bidirectional filtering +4. **`enableChartSelectionSync()`** — Enable selection highlighting +5. **`getChartRegistry()`** — Static accessor to ChartRegistry singleton + +All methods follow CRTP pattern: return `(J) this` for method chaining. + +## Integration Patterns + +### Basic Linking +```java +grid.registerAndLinkChart(new ChartConfiguration("chart1", "bar") + .setTitle("Sales by Region") + .setFieldMapping(Map.of("region", "x", "sales", "y"))); +``` + +### Cross-Filtering +```java +grid.registerAndLinkChart(new ChartConfiguration("chart1", "line") + .setTitle("Sales Trend") + .setEnableCrossFiltering(true) + .setFieldMapping(Map.of("month", "x", "amount", "y"))) + .enableChartCrossFiltering(); +``` + +### Selection Sync +```java +grid.enableCharts() + .registerAndLinkChart(new ChartConfiguration("chart1", "pie") + .setTitle("Market Share") + .setEnableCrossFiltering(true) + .setEnableSelectionSync(true) + .setFieldMapping(Map.of("competitor", "label", "share", "value"))) + .enableChartSelectionSync(); +``` + +### Custom Data Bridge +```java +class SalesDataBridge implements IChartDataBridge { + @Override + public List getGridRowData() { + return salesService.getRecords(); + } + + @Override + public void onGridDataChanged(List newData) { + ChartRegistry.getInstance().updateChartData("salesChart", newData); + } + + @Override + public Map getFieldMapping() { + return Map.of("region", "x", "sales", "y"); + } +} + +ChartRegistry.getInstance() + .registerDataBridge("bridge1", new SalesDataBridge()) + .registerChart(new ChartConfiguration("salesChart", "bar") + .setTitle("Sales Analysis") + .setDataBridgeId("bridge1")); +``` + +## Architecture + +### Data Flow +``` +┌─────────────────┐ +│ Grid Data │ +│ (Row Model) │ +└────────┬────────┘ + │ + ├─────────────────────────┐ + │ │ + v v + [ChartRegistry] [ChartRegistry] + │ │ + Chart #1 ◄────────► Chart #2 + (Bar Chart) Cross- (Line Chart) + Filtering + │ │ + └────────────┬────────────┘ + │ + [Grid Selection Sync] + │ + Row Highlight +``` + +### Thread Safety +- `ChartRegistry` uses `ConcurrentHashMap` for thread-safe access +- Safe for multi-threaded grid updates and chart interactions +- Event listeners are notified asynchronously + +### Registry Event Lifecycle +1. `onChartRegistered(ChartConfiguration)` — Chart added to registry +2. `onChartUnregistered(String chartId)` — Chart removed from registry +3. `onChartsLinkedToGrid(String gridId, List chartIds)` — Charts associated with grid +4. `onDataBridgeRegistered(String bridgeId, IChartDataBridge)` — Data bridge added +5. `onChartDataUpdated(String chartId, List)` — Chart data refreshed + +## Field Mapping Reference + +### Bar / Column Charts +- Grid columns map to: `x` (category), `y` (series values), `color` (optional) +- Example: `region→x, sales→y, quarter→color` + +### Line Charts +- Grid columns map to: `x` (x-axis), `y` (series), `strokeColor` (optional) +- Example: `date→x, revenue→y, department→strokeColor` + +### Pie / Doughnut Charts +- Grid columns map to: `label` (segment labels), `value` (segment sizes) +- Example: `category→label, percentage→value` + +### Scatter Charts +- Grid columns map to: `x` (x-axis), `y` (y-axis), `size` (optional), `color` (optional) +- Example: `height→x, weight→y, age→size` + +### Waterfall Charts +- Grid columns map to: `x` (categories), `y` (values), `isIntermediateTotal`, `isTotal` +- Example: `month→x, amount→y, isQuarterEnd→isIntermediateTotal` + +## Best Practices + +### IDs and References +- Use consistent, descriptive chart IDs: `"sales-regional"`, `"forecast-monthly"` +- Grid IDs auto-generated; access via `getGridId()` (private, but used internally) +- Bridge IDs should indicate data source: `"bridge-sales"`, `"bridge-forecast"` + +### Field Mapping +- Define mappings before linking charts +- Validate grid column names against data model +- Use consistent naming: snake_case or camelCase throughout +- Document custom field transformations in `IChartDataBridge` + +### Data Bridges +- Implement for custom transformations (filtering, aggregation, calculation) +- Keep synchronous; use async tasks only for heavy computations outside grid +- Store computed data in bridge instance variables if needed +- Test field mapping with sample data before deployment + +### Performance +- Large datasets (>10K rows): aggregate on server before charting +- Enable cross-filtering selectively; it has CPU cost on interactions +- Use pagination for grids with charts to reduce rendering overhead +- Profile chart update performance; consider debouncing rapid grid changes + +### Error Handling +- Catch `NullPointerException` when accessing unregistered bridge IDs +- Validate field mapping exists before `enableChartCrossFiltering()` +- Log chart interaction errors; don't fail grid updates on chart exceptions +- Fail fast on registration; use try-catch around `registerAndLinkChart()` + +## Migration from v1.x + +- **No breaking changes**: Existing grid and chart code continues to work unchanged +- **Additive only**: New chart binding APIs are optional; use when needed +- **Backward compatible**: Community plugin still works; enterprise features enhance it +- **Opt-in**: Chart linking requires explicit `registerAndLinkChart()` or `linkCharts()` calls + +## Documentation + +- **User Guide**: `docs/ChartGridIntegration-Guide.md` — 650+ lines with examples and best practices +- **Rules Reference**: `./grid-data-binding.rules.md` — 450+ lines with patterns and API details +- **Integration Guide**: `./agcharts-enterprise-integration.rules.md` — Quick start and configuration +- **Troubleshooting**: `./troubleshooting.rules.md` — 7 chart-grid scenarios with diagnosis/solution +- **Java Usage**: `./java-usage-guide.rules.md` — Java API reference and patterns + +## Technical Details + +### Compilation +- **Java Version**: 25 (module-path compilation) +- **Dependencies**: AG Grid 34.2.0, AG Charts 12.2.0, MapStruct (entity mapping) +- **Build Status**: ✅ SUCCESS (`mvn clean compile`) +- **Package**: ✅ `aggrid-enterprise-2.0.0-SNAPSHOT.jar` created + +### Module System +- Explicit module exports in `module-info.java` +- ServiceLoader discovery for `IPageConfigurator` +- Raw type suppression for service providers as needed + +### Licensing +- Requires AG Grid Enterprise license (already required) +- Requires AG Charts Enterprise license (new in v2.0.0) +- Initialize licenses per `./licensing-and-activation.rules.md` + +## Support & Feedback + +- Report issues via GitHub Issues (link to repo) +- Request features via GitHub Discussions (link to repo) +- See `./troubleshooting.rules.md` for common issues +- Review `docs/ChartGridIntegration-Guide.md` for detailed examples + +## Changelog + +### v2.0.0 (Current) +- **NEW**: Grid-to-charts data binding framework +- **NEW**: IChartDataBridge interface for custom data coordination +- **NEW**: ChartConfiguration class with 58 fluent properties +- **NEW**: ChartRegistry singleton with event listeners +- **NEW**: 5 helper methods on AgGridEnterprise for simplified linking +- **NEW**: Cross-filtering support (grid ↔ charts) +- **NEW**: Selection sync support (grid ↔ charts) +- **NEW**: Comprehensive grid-data-binding.rules.md documentation +- **NEW**: Troubleshooting guide for chart-grid integration +- **IMPROVED**: agcharts-enterprise-integration.rules.md with grid binding examples +- **VERIFIED**: Full backward compatibility with v1.x code + +--- + +**Release Date**: [Current Date] +**Version**: 2.0.0-SNAPSHOT +**Artifact**: `com.jwebmp.plugins:aggrid-enterprise:2.0.0-SNAPSHOT` diff --git a/generative/frontend/jwebmp/agcharts-enterprise/agcharts-enterprise-integration.rules.md b/generative/frontend/jwebmp/agcharts-enterprise/agcharts-enterprise-integration.rules.md index 2584468..2a4167c 100644 --- a/generative/frontend/jwebmp/agcharts-enterprise/agcharts-enterprise-integration.rules.md +++ b/generative/frontend/jwebmp/agcharts-enterprise/agcharts-enterprise-integration.rules.md @@ -1,38 +1,87 @@ # AgCharts Enterprise Integration — Rules -Overview +## Overview - This module extends the community AgCharts plugin to activate AG Charts Enterprise features in JWebMP applications. - It mirrors the model used by WebAwesomePro extending WebAwesome and FullCalendarPro extending FullCalendar. +- **New in v2.0.0**: Integrated grid-to-charts data binding for synchronized dashboards with cross-filtering and selection sync. -Usage patterns +## Usage patterns + +### Basic Usage - Add Maven dependency: com.jwebmp.plugins:agcharts-enterprise:${version} (version via BOM recommended). - Keep community plugin dependency present: com.jwebmp.plugins:agcharts. - Use charts as normal through JWebMP; enterprise features become available on the client when the Page Configurator includes the TypeScript dependency for `ag-charts-enterprise`. - Reference architecture & sequence diagrams in `docs/architecture/` via `docs/PROMPT_REFERENCE.md` before generating code; they define the required containers and build flow. -Minimal example +### Grid-Charts Integration (v2.0.0+) +- Link AG Grid data to AG Charts Enterprise for coordinated dashboards. +- Enable cross-filtering: chart selections filter grid rows; grid filters update charts. +- Enable selection sync: grid row selection highlights chart data points. +- Use `IChartDataBridge` for custom data transformations and event coordination. +- Manage charts via centralized `ChartRegistry` for lifecycle and relationship tracking. +- See `grid-data-binding.rules.md` for detailed patterns and API reference. + +## Minimal example + +### Charts Only - Server-side (Java/JWebMP): continue to construct charts as with the community plugin; no API change required for basic usage. - Ensure the Page Configurator from this module is on the classpath (auto-discovery via Java ServiceLoader and JWebMP conventions). -Quick start checklist +### Grid + Charts (v2.0.0+) +```java +// Create grid with data +AgGridEnterprise> grid = new AgGridEnterprise<>("salesGrid") + .setRowData(loadSalesData()) + .enableCharts() + + // Register and link a chart + .registerAndLinkChart(new ChartConfiguration("regionChart", "pie") + .setTitle("Sales by Region") + .setFieldMapping(Map.of( + "region", "label", + "sales", "value", + "regionId", "id" + )) + .setEnableCrossFiltering(true)) + + // Enable coordination features + .enableChartCrossFiltering(); +``` + +## Quick start checklist + 1. Import the JWebMP BOM plus `com.jwebmp.plugins:agcharts` and this module. 2. Confirm ServiceLoader discovery: `META-INF/services/com.jwebmp.core.services.IPageConfigurator` includes `AgChartsEnterprisePageConfigurator`. -3. Annotate charts via CRTP fluent APIs (see ./java-usage-guide.rules.md and ./usage-examples.rules.md for patterns). -4. Run a build (`mvn clean package`); verify generated Angular `package.json` lists `ag-charts-enterprise` and `ag-charts-angular`. -5. Provide AG Charts Enterprise license initialization per ./licensing-and-activation.rules.md if required by your deployment. +3. **For Grid+Charts**: Use `AgGridEnterprise.registerAndLinkChart()` or `ChartRegistry.getInstance().registerChart()` to establish chart-grid relationships. +4. Annotate charts via CRTP fluent APIs (see ./java-usage-guide.rules.md and ./usage-examples.rules.md for patterns). +5. Run a build (`mvn clean package`); verify generated Angular `package.json` lists `ag-charts-enterprise` and `ag-charts-angular`. +6. Provide AG Charts Enterprise license initialization per ./licensing-and-activation.rules.md if required by your deployment. -Configuration -- TypeScript dependency: `ag-charts-enterprise` is pulled in by the Page Configurator using @TsDependency. +## Configuration + +### TypeScript dependency +- `ag-charts-enterprise` is pulled in by the Page Configurator using @TsDependency. - Angular peer dependencies: community plugin typically includes `ag-charts-community` and `ag-charts-angular`; this enterprise plugin complements them. -Performance/constraints +### Grid-Charts Coordination (v2.0.0+) +- Register charts via `ChartRegistry` or `grid.registerAndLinkChart()`. +- Define field mappings to sync grid columns with chart properties. +- Enable cross-filtering and selection sync on `ChartConfiguration` or via grid helper methods. +- Optionally implement custom `IChartDataBridge` for complex data flows. + +## Performance/constraints + - Do not bundle or edit generated TS; rely on the build to include dependencies. - Enterprise features may increase bundle size; tree-shake when possible. - Licensing is required per AG Charts Enterprise terms; see licensing-and-activation.rules.md. +- **For large datasets**: Implement server-side aggregation before charting to avoid performance degradation. + +## See also -See also - Page Configurator — ./page-configurator.rules.md +- Grid-Data Binding — ./grid-data-binding.rules.md (new in v2.0.0) - Licensing — ./licensing-and-activation.rules.md - Usage examples — ./usage-examples.rules.md - Troubleshooting — ./troubleshooting.rules.md - Angular index — ../../../language/angular/README.md + diff --git a/generative/frontend/jwebmp/agcharts-enterprise/grid-data-binding.rules.md b/generative/frontend/jwebmp/agcharts-enterprise/grid-data-binding.rules.md new file mode 100644 index 0000000..1bc100c --- /dev/null +++ b/generative/frontend/jwebmp/agcharts-enterprise/grid-data-binding.rules.md @@ -0,0 +1,369 @@ +# AG Grid ↔ AG Charts Data Binding — Rules + +## Overview + +This module extends AG Grid Enterprise with bidirectional data binding to AG Charts Enterprise, enabling: + +- **Data Synchronization**: Charts consume grid data automatically via field mapping +- **Cross-Filtering**: Chart selections filter grid rows; grid filters update charts +- **Selection Sync**: Grid row selection highlights chart data points +- **Event Coordination**: Registry-based listener pattern for chart lifecycle management + +Mirrors the integration philosophy used in combined Grid+Charts dashboards where the grid is the data authority and charts provide visualization/aggregation views. + +## Architecture + +### Core Components + +#### 1. IChartDataBridge Interface +- **Purpose**: Abstraction for grid↔chart data flow and event coordination +- **Generic Type T**: Row data type (typically Map or domain POJO) +- **Responsibilities**: + - Provide grid row data to charts + - Handle grid data mutations (add/update/remove events) + - Coordinate selection state between grid and charts + - Manage field mappings (grid column → chart property) + - Support custom cross-filtering logic + +#### 2. ChartConfiguration Class +- **Purpose**: Metadata container for chart instances linked to grids +- **Key Properties**: + - `chartId`: Unique identifier within grid context + - `chartType`: Chart rendering type (bar, line, pie, scatter, bubble, waterfall, gauge, etc.) + - `dataBridgeId`: Reference to registered IChartDataBridge instance + - `linkedGridId`: Grid this chart consumes data from + - `fieldMapping`: Map of grid field name → chart data property (e.g., "region" → "x", "sales" → "y") + - `enableCrossFiltering`: Boolean; chart interactions filter the grid + - `enableSelectionSync`: Boolean; grid selections highlight chart data + - `themes`: List of chart theme names (e.g., ["ag-default", "ag-material"]) + - `customOptions`: Arbitrary options passed directly to AG Charts + +#### 3. ChartRegistry (Singleton) +- **Purpose**: Central registry for managing chart instances and grid-chart relationships +- **Responsibilities**: + - Chart lifecycle: register/unregister chart configurations + - Data bridge storage and lookup + - Grid↔chart relationship mapping (one grid → many charts, one chart ← one grid) + - Event dispatch to registered listeners for chart registration, linking, and unlinking + - Thread-safe access (ConcurrentHashMap-backed) + +### Data Flow + +``` +Grid Data (rows) + ↓ +IChartDataBridge + ├→ Grid changes (add/update/remove) → Chart updates + ├→ Grid selection → Chart highlight + └→ Chart interaction → Grid filter + ↓ +ChartConfiguration (field mapping) + ↓ +AG Charts Enterprise + ├→ Render with grid data + ├→ Emit user interactions (selection, drill-down) + └→ Apply theme/customizations + ↓ +ChartRegistry (coordination) + └→ Notify listeners (e.g., analytics, UI refresh) +``` + +## Integration Patterns + +### Pattern 1: Basic Chart Linking +Pre-register chart configurations, then link by ID. + +```java +// Register chart once (e.g., app startup or lazy-load) +ChartRegistry.getInstance().registerChart("region-pie", new ChartConfiguration("region-pie", "pie") + .setTitle("Sales by Region") + .setFieldMapping(Map.of("region", "label", "sales", "value", "regionId", "id"))); + +// Later, when creating grid, link the chart +AgGridEnterprise> grid = new AgGridEnterprise<>("salesGrid") + .setRowData(rowDataList) + .enableCharts() + .linkCharts("region-pie"); +``` + +### Pattern 2: Inline Registration & Linking +Create chart configuration and register in one step. + +```java +grid.enableCharts() + .registerAndLinkChart(new ChartConfiguration("sales-chart", "bar") + .setTitle("Sales Trends") + .setFieldMapping(Map.of( + "month", "x", + "sales", "y", + "productLine", "series", + "monthId", "id" + )) + .setEnableCrossFiltering(true) + .setEnableSelectionSync(true)); +``` + +### Pattern 3: Cross-Filtering +Enable bidirectional filtering between grid and charts. + +```java +grid.enableCharts() + .registerAndLinkChart(new ChartConfiguration("filter-chart", "column") + .setFieldMapping(Map.of("category", "x", "count", "y", "categoryId", "id")) + .setEnableCrossFiltering(true)) + .enableChartCrossFiltering(); + // Now: chart selection → grid filter; grid filter change → chart update +``` + +### Pattern 4: Selection Synchronization +Highlight grid selections in charts without filtering. + +```java +grid.enableCharts() + .registerAndLinkChart(new ChartConfiguration("detail-chart", "scatter") + .setFieldMapping(Map.of("xVal", "x", "yVal", "y", "id", "id")) + .setEnableSelectionSync(true)) + .enableChartSelectionSync(); + // Now: grid row selection → chart point highlight (selection only, no filter) +``` + +### Pattern 5: Custom Data Bridge +Implement custom logic for data transformation and event coordination. + +```java +public class CustomDataBridge implements IChartDataBridge { + private List gridData; + private Map fieldMapping; + private List listeners = new ArrayList<>(); + + @Override + public List getGridRowData() { + return new ArrayList<>(gridData); + } + + @Override + public void onGridDataChanged(List updatedData) { + this.gridData = new ArrayList<>(updatedData); + // Notify charts of data changes + } + + @Override + public void onChartInteraction(String chartId, List> dataPoints) { + // Extract IDs from chart selection + List selectedIds = dataPoints.stream() + .map(dp -> (String) dp.get("id")) + .toList(); + + // Apply filter to grid data + List filtered = gridData.stream() + .filter(row -> selectedIds.contains(row.getId())) + .toList(); + + // Notify listeners (will update grid) + listeners.forEach(l -> l.onChartInteraction(chartId, dataPoints)); + } + + @Override + public Map getFieldMapping() { + return fieldMapping; + } + + @Override + public void setFieldMapping(Map mapping) { + this.fieldMapping = new HashMap<>(mapping); + } + + @Override + public void addChartInteractionListener(ChartInteractionListener listener) { + listeners.add(listener); + } + + @Override + public void removeChartInteractionListener(ChartInteractionListener listener) { + listeners.remove(listener); + } +} + +// Usage +CustomDataBridge bridge = new CustomDataBridge(); +bridge.setFieldMapping(Map.of("region", "x", "sales", "y", "regionId", "id")); +ChartRegistry.getInstance().registerDataBridge("custom-bridge", bridge); +``` + +## Field Mapping Reference + +The `fieldMapping` Map controls which grid columns feed which chart properties. + +### Common Mappings by Chart Type + +#### Column/Bar Chart +```java +Map.of( + "category", "x", // Category axis + "value", "y", // Numeric value + "series", "series" // Optional: series grouping +) +``` + +#### Line/Area Chart +```java +Map.of( + "date", "x", // X-axis (time or ordinal) + "value", "y", // Y-axis (numeric) + "metric", "series", // Series grouping + "metricId", "id" // Key for cross-filtering +) +``` + +#### Pie Chart +```java +Map.of( + "label", "label", // Slice labels + "value", "value", // Slice sizes + "labelId", "id" // Key for cross-filtering +) +``` + +#### Scatter/Bubble Chart +```java +Map.of( + "xValue", "x", // X-axis numeric + "yValue", "y", // Y-axis numeric + "size", "size", // Bubble size (optional) + "category", "series", // Series grouping (optional) + "pointId", "id" // Key for cross-filtering +) +``` + +#### Waterfall Chart +```java +Map.of( + "label", "x", // Category labels + "value", "y", // Values + "type", "type", // e.g., "total", "increase", "decrease" + "labelId", "id" +) +``` + +### Special Field Keys + +- **`id`**: Unique key for cross-filtering. Must be present in chart data for reliable selection/filtering. +- **`series`**: Groups data into separate series (line, bar, area charts). +- **`size`**: Bubble/point size (scatter, bubble charts). +- **`color`**: Color mapping (advanced; typically chart theme handles this). + +## Helper Methods on AgGridEnterprise + +### linkCharts(String... chartIds) +Link pre-registered charts by ID. + +```java +grid.linkCharts("chart1", "chart2", "chart3"); +``` + +- **Pre-requisite**: Charts must be registered in ChartRegistry. +- **Effect**: Establishes grid → chart data flow. + +### registerAndLinkChart(ChartConfiguration config) +Create a new chart configuration and link in one atomic operation. + +```java +grid.registerAndLinkChart(new ChartConfiguration("newChart", "line") + .setFieldMapping(Map.of("x", "x", "y", "y"))); +``` + +- **Effect**: Registers chart + links to grid + returns `this` for chaining. + +### enableChartCrossFiltering() +Activate bidirectional cross-filtering between grid and all linked charts. + +```java +grid.enableChartCrossFiltering(); +``` + +- **Effect**: Updates all linked charts' `enableCrossFiltering` flag. + +### enableChartSelectionSync() +Activate selection synchronization (grid selection → chart highlight). + +```java +grid.enableChartSelectionSync(); +``` + +- **Effect**: Updates all linked charts' `enableSelectionSync` flag. + +### getChartRegistry() +Access the singleton ChartRegistry for advanced management. + +```java +ChartRegistry registry = AgGridEnterprise.getChartRegistry(); +``` + +## Best Practices + +1. **Unique IDs**: Use meaningful, globally-scoped chart IDs (e.g., "dashboard-sales-chart"). +2. **Field Mapping**: Define mappings upfront; validate grid column names match mapping keys. +3. **Grid ID**: Set explicit grid IDs for multi-grid scenarios to avoid collisions in registry. +4. **Data Bridge**: Use default bridge for simple cases; implement custom bridge for: + - Complex data transformations (pivoting, aggregation) + - Custom cross-filtering logic + - Event broadcasting to external systems +5. **Listener Patterns**: Register ChartRegistry listeners to track lifecycle and trigger side effects (e.g., analytics, cache invalidation). +6. **Theme Consistency**: Apply the same theme list across related charts for visual cohesion. +7. **Performance**: For large datasets (>10k rows): + - Consider server-side aggregation before charting + - Implement lazy loading or pagination on the grid + - Use windowed data bridges to reduce data sent to charts +8. **Error Handling**: Wrap field mapping validation to fail fast if grid data structure changes. + +## Troubleshooting + +### Charts Not Rendering +- Verify `enableCharts()` is called on the grid. +- Confirm chart IDs are registered in ChartRegistry. +- Check field mapping keys exist in grid row data. + +### Cross-Filtering Not Working +- Ensure `enableCrossFiltering(true)` is set on ChartConfiguration. +- Verify field mapping includes an `id` key for selection tracking. +- Confirm grid selection event listeners are wired correctly. + +### Data Not Updating +- Check that `IChartDataBridge.onGridDataChanged()` is invoked when grid data changes. +- Verify bridge is registered and linked to correct grid. + +### Selection Sync Fails +- Ensure `enableSelectionSync(true)` is set on ChartConfiguration. +- Confirm grid row selection events propagate to bridge. + +## Related Documentation + +- **Grid-Charts Integration Guide** (user): `docs/ChartGridIntegration-Guide.md` +- **AG Grid Enterprise** (parent module): `.././../../../../README.md` +- **AG Charts Enterprise** (related): `../README.md` +- **Licensing & Activation**: `./licensing-and-activation.rules.md` +- **AG Grid API**: https://www.ag-grid.com/javascript-data-grid/api/ +- **AG Charts API**: https://www.ag-grid.com/javascript-charts/api/ + +## Policies + +- **CRTP Fluent Style**: All helper methods return `(J) this` for method chaining. +- **Thread Safety**: ChartRegistry uses ConcurrentHashMap; safe for multi-threaded access. +- **Forward-Only Changes**: New chart linking features do not modify existing grid options or behavior. +- **Backward Compatibility**: All changes are additive; existing code continues to work unchanged. + +## Version History + +- **v2.0.0** (2025-12-02): Initial chart-grid data binding implementation + - IChartDataBridge interface + - ChartConfiguration and ChartRegistry classes + - Helper methods on AgGridEnterprise + - Support for cross-filtering and selection sync + +## See Also + +- Page Configurator — `./page-configurator.rules.md` +- Licensing & Activation — `./licensing-and-activation.rules.md` +- Usage Examples — `./usage-examples.rules.md` +- Troubleshooting — `./troubleshooting.rules.md` +- JWebMP topic index — `../README.md` diff --git a/generative/frontend/jwebmp/agcharts-enterprise/java-usage-guide.rules.md b/generative/frontend/jwebmp/agcharts-enterprise/java-usage-guide.rules.md index ab39f7c..fa474b6 100644 --- a/generative/frontend/jwebmp/agcharts-enterprise/java-usage-guide.rules.md +++ b/generative/frontend/jwebmp/agcharts-enterprise/java-usage-guide.rules.md @@ -66,18 +66,29 @@ public class RevenueChart> extends Div { 4) Optional: Combine charts with AG Grid Enterprise - For dashboards, pair the JWebMP AG Grid plugin with charts. Use grid selection events to update charts (and vice versa) via shared context ids or app events. - Keep shared keys stable (e.g., region, productId) across grid rows and chart series data. +- **New Feature (v2.0.0+)**: Use the new `IChartDataBridge` interface and `ChartRegistry` for automatic data synchronization, cross-filtering, and selection sync. See `grid-data-binding.rules.md` for detailed patterns and API. 5) Licensing and activation - AG Charts Enterprise requires a license key. Do not commit secrets. -- Initialize on the client using a small server-injected script (see Licensing & Activation doc). Example pattern: -```text -// In a Page Configurator implementation — illustrative only -String agLicense = secrets.get("AG_CHARTS_ENTERPRISE_LICENSE_KEY"); -if (agLicense != null && !agLicense.isEmpty()) { - page.add(new Script<>() - .add("window.AG_CHARTS_LICENSE_KEY='" + JsUtils.escapeJs(agLicense) + "';\n")); +- License keys are automatically injected by `AgGridEnterprisePageConfigurator` via one of three methods: + - **Programmatic**: `AgGridEnterprisePageConfigurator.setAG_GRID_LICENSE_KEY(licenseKey);` + - **System Property**: `-Dag.grid.license=YOUR_KEY` or `System.setProperty("ag.grid.license", key);` + - **Environment Variable**: `export AG_GRID_LICENSE=YOUR_KEY` or set in deployment config +- Example using secret provider with programmatic setter: +```java +// In your application bootstrap code +import com.jwebmp.plugins.aggridenterprise.AgGridEnterprisePageConfigurator; + +private final SecretsProvider secrets; // your secret provider + +public void initializeAgGridLicense() { + String licenseKey = secrets.get("AG_CHARTS_ENTERPRISE_LICENSE_KEY"); + if (licenseKey != null && !licenseKey.isEmpty()) { + AgGridEnterprisePageConfigurator.setAG_GRID_LICENSE_KEY(licenseKey); + } } ``` +- See `./licensing-and-activation.rules.md` for detailed configuration methods and best practices. 6) Validation checklist - Build includes `ag-charts-enterprise` in generated Angular app. diff --git a/generative/frontend/jwebmp/agcharts-enterprise/licensing-and-activation.rules.md b/generative/frontend/jwebmp/agcharts-enterprise/licensing-and-activation.rules.md index 86ed497..6302c1f 100644 --- a/generative/frontend/jwebmp/agcharts-enterprise/licensing-and-activation.rules.md +++ b/generative/frontend/jwebmp/agcharts-enterprise/licensing-and-activation.rules.md @@ -1,15 +1,18 @@ # Licensing & Activation — AgCharts Enterprise Overview -- AG Charts Enterprise requires a valid license. This plugin does not embed or manage licenses; it only enables enterprise features by wiring the client dependency. +- AG Charts Enterprise requires a valid license. The `AgGridEnterprisePageConfigurator` handles license initialization by injecting the key into the Angular-compiled application. +- License keys are managed via: (1) programmatic static setter, (2) system property `ag.grid.license`, or (3) environment variable `AG_GRID_LICENSE`. +- Keys are never committed to source control; they are injected at runtime only. Usage patterns - Obtain a license from AG Grid/AG Charts per their terms. -- Provide the license key in your application according to AG Charts Enterprise documentation (typically via client-side initialization code). Do not commit license keys to source control. +- Provide the license key to the JWebMP application via one of three methods (see Configuration section below). +- The `configureAngular()` method in `AgGridEnterprisePageConfigurator` automatically injects the key into a `