charthart
This commit is contained in:
		
							parent
							
								
									7461521a90
								
							
						
					
					
						commit
						bc46735218
					
				| @ -8,6 +8,9 @@ | |||||||
| 
 | 
 | ||||||
| <div style="display: inline;"> | <div style="display: inline;"> | ||||||
|   <button class="btn componentbtn" (click)="toggleMenu()"><clr-icon shape="plus"></clr-icon>component</button> |   <button class="btn componentbtn" (click)="toggleMenu()"><clr-icon shape="plus"></clr-icon>component</button> | ||||||
|  |   <button class="btn btn-primary" (click)="openCommonFilterModal()" style="margin-left: 10px;"> | ||||||
|  |     <clr-icon shape="filter"></clr-icon> Common Filter | ||||||
|  |   </button> | ||||||
|   <div style="display: inline;"> |   <div style="display: inline;"> | ||||||
|     {{dashboardName}} |     {{dashboardName}} | ||||||
|   </div> |   </div> | ||||||
| @ -208,8 +211,20 @@ | |||||||
|           <h5>Base API Filters</h5> |           <h5>Base API Filters</h5> | ||||||
|           <div class="clr-subtext">Configure filters for the main API (applied regardless of drilldown settings)</div> |           <div class="clr-subtext">Configure filters for the main API (applied regardless of drilldown settings)</div> | ||||||
|            |            | ||||||
|  |           <!-- Common Filter Toggle --> | ||||||
|  |           <div class="clr-form-control" style="margin-top: 10px;"> | ||||||
|  |             <div class="clr-control-container"> | ||||||
|  |               <div class="clr-checkbox-wrapper"> | ||||||
|  |                 <input type="checkbox" id="commonFilterToggle" [(ngModel)]="gadgetsEditdata.commonFilterEnabled"  | ||||||
|  |                        (change)="onCommonFilterToggle()" [ngModelOptions]="{standalone: true}" class="clr-checkbox" /> | ||||||
|  |                 <label for="commonFilterToggle" class="clr-control-label">Use Common Filter</label> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |            | ||||||
|           <!-- Add Base Filter Button --> |           <!-- Add Base Filter Button --> | ||||||
|           <button class="btn btn-sm btn-primary" (click)="addBaseFilter()" style="margin-top: 10px; margin-bottom: 10px;"> |           <button class="btn btn-sm btn-primary" (click)="addBaseFilter()" style="margin-top: 10px; margin-bottom: 10px;"  | ||||||
|  |                   [disabled]="gadgetsEditdata.commonFilterEnabled"> | ||||||
|             <clr-icon shape="plus"></clr-icon> Add Filter |             <clr-icon shape="plus"></clr-icon> Add Filter | ||||||
|           </button> |           </button> | ||||||
|            |            | ||||||
| @ -218,14 +233,16 @@ | |||||||
|                style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;"> |                style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;"> | ||||||
|             <div style="display: flex; justify-content: space-between; align-items: center;"> |             <div style="display: flex; justify-content: space-between; align-items: center;"> | ||||||
|               <span>Filter {{i + 1}}</span> |               <span>Filter {{i + 1}}</span> | ||||||
|               <button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)"> |               <button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)"  | ||||||
|  |                       [disabled]="gadgetsEditdata.commonFilterEnabled"> | ||||||
|                 <clr-icon shape="trash"></clr-icon> |                 <clr-icon shape="trash"></clr-icon> | ||||||
|               </button> |               </button> | ||||||
|             </div> |             </div> | ||||||
|              |              | ||||||
|             <div class="clr-row" style="margin-top: 8px;"> |             <div class="clr-row" style="margin-top: 8px;"> | ||||||
|               <div class="clr-col-sm-5"> |               <div class="clr-col-sm-5"> | ||||||
|                 <select [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}" class="clr-select"> |                 <select [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}" class="clr-select"  | ||||||
|  |                         [disabled]="gadgetsEditdata.commonFilterEnabled"> | ||||||
|                   <option value="">Select Field</option> |                   <option value="">Select Field</option> | ||||||
|                   <!-- Base API filters should always use columnData, not drilldownColumnData --> |                   <!-- Base API filters should always use columnData, not drilldownColumnData --> | ||||||
|                   <option *ngFor="let column of getAvailableFields(gadgetsEditdata.baseFilters, i, columnData)" [value]="column">{{column}}</option> |                   <option *ngFor="let column of getAvailableFields(gadgetsEditdata.baseFilters, i, columnData)" [value]="column">{{column}}</option> | ||||||
| @ -234,11 +251,13 @@ | |||||||
|                |                | ||||||
|               <div class="clr-col-sm-5"> |               <div class="clr-col-sm-5"> | ||||||
|                 <input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"  |                 <input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"  | ||||||
|                        class="clr-input" placeholder="Filter Value" /> |                        class="clr-input" placeholder="Filter Value"  | ||||||
|  |                        [disabled]="gadgetsEditdata.commonFilterEnabled"/> | ||||||
|               </div> |               </div> | ||||||
|                |                | ||||||
|               <div class="clr-col-sm-2"> |               <div class="clr-col-sm-2"> | ||||||
|                 <button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)"> |                 <button class="btn btn-icon btn-danger btn-sm" (click)="removeBaseFilter(i)"  | ||||||
|  |                         [disabled]="gadgetsEditdata.commonFilterEnabled"> | ||||||
|                   <clr-icon shape="trash"></clr-icon> |                   <clr-icon shape="trash"></clr-icon> | ||||||
|                 </button> |                 </button> | ||||||
|               </div> |               </div> | ||||||
| @ -324,12 +343,12 @@ | |||||||
|           <h5>Base Drilldown Filters</h5> |           <h5>Base Drilldown Filters</h5> | ||||||
|           <div class="clr-subtext">Configure filters for the base drilldown level</div> |           <div class="clr-subtext">Configure filters for the base drilldown level</div> | ||||||
|            |            | ||||||
|           <!-- Add Base Drilldown Filter Button --> |           <!-- Add Drilldown Filter Button --> | ||||||
|           <button class="btn btn-sm btn-primary" (click)="addDrilldownFilter()" style="margin-top: 10px; margin-bottom: 10px;"> |           <button class="btn btn-sm btn-primary" (click)="addDrilldownFilter()" style="margin-top: 10px; margin-bottom: 10px;"> | ||||||
|             <clr-icon shape="plus"></clr-icon> Add Filter |             <clr-icon shape="plus"></clr-icon> Add Filter | ||||||
|           </button> |           </button> | ||||||
|            |            | ||||||
|           <!-- Base Drilldown Filter Fields List --> |           <!-- Drilldown Filter Fields List --> | ||||||
|           <div *ngFor="let filter of gadgetsEditdata.drilldownFilters; let i = index"  |           <div *ngFor="let filter of gadgetsEditdata.drilldownFilters; let i = index"  | ||||||
|                style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;"> |                style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;"> | ||||||
|             <div style="display: flex; justify-content: space-between; align-items: center;"> |             <div style="display: flex; justify-content: space-between; align-items: center;"> | ||||||
| @ -507,4 +526,87 @@ | |||||||
| 
 | 
 | ||||||
|     </form> |     </form> | ||||||
|   </div> |   </div> | ||||||
| </clr-modal> | </clr-modal> | ||||||
|  | 
 | ||||||
|  | <!-- Common Filter Modal --> | ||||||
|  | <clr-modal [(clrModalOpen)]="commonFilterModalOpen" [clrModalStaticBackdrop]="true" clrModalSize="lg"> | ||||||
|  |   <h3 class="modal-title">Configure Common Filter</h3> | ||||||
|  |   <div class="modal-body"> | ||||||
|  |     <form [formGroup]="commonFilterForm" class="clr-form-horizontal"> | ||||||
|  |       <div class="clr-row"> | ||||||
|  |         <div class="clr-col-sm-12"> | ||||||
|  |           <label for="commonFilterConnection">Connection</label> | ||||||
|  |           <select id="commonFilterConnection" formControlName="connection" [(ngModel)]="commonFilterData.connection" class="clr-select"> | ||||||
|  |             <option value="">Select Connection</option> | ||||||
|  |             <option *ngFor="let conn of sureconnectData" [value]="conn.id"> | ||||||
|  |               {{conn.connection_name || conn.id}} | ||||||
|  |             </option> | ||||||
|  |           </select> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |        | ||||||
|  |       <div class="clr-row"> | ||||||
|  |         <div class="clr-col-sm-12"> | ||||||
|  |           <label for="commonFilterApiUrl">API URL</label> | ||||||
|  |           <div> | ||||||
|  |             <input type="text" id="commonFilterApiUrl" formControlName="apiUrl" class="clr-input" | ||||||
|  |               [(ngModel)]="commonFilterData.apiUrl" style="width:90%">  | ||||||
|  |             <span> | ||||||
|  |               <button class="btn btn-icon btn-primary" style="margin: 0px;"  | ||||||
|  |                 (click)="refreshCommonFilterColumns()" [disabled]="!commonFilterData.apiUrl"> | ||||||
|  |                 <clr-icon shape="redo"></clr-icon> | ||||||
|  |               </button> | ||||||
|  |             </span> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |        | ||||||
|  |       <!-- Common Filter Fields List --> | ||||||
|  |       <div class="clr-row" style="margin-top: 15px;"> | ||||||
|  |         <div class="clr-col-sm-12"> | ||||||
|  |           <h5>Common Filters</h5> | ||||||
|  |            | ||||||
|  |           <!-- Add Common Filter Button --> | ||||||
|  |           <button class="btn btn-sm btn-primary" (click)="addCommonFilter()" style="margin-top: 10px; margin-bottom: 10px;"> | ||||||
|  |             <clr-icon shape="plus"></clr-icon> Add Filter | ||||||
|  |           </button> | ||||||
|  |            | ||||||
|  |           <!-- Common Filter Fields List --> | ||||||
|  |           <div *ngFor="let filter of commonFilterData.filters; let i = index"  | ||||||
|  |                style="margin-bottom: 10px; padding: 8px; border: 1px solid #eee; border-radius: 4px; background-color: #f9f9f9;"> | ||||||
|  |             <div style="display: flex; justify-content: space-between; align-items: center;"> | ||||||
|  |               <span>Filter {{i + 1}}</span> | ||||||
|  |               <button class="btn btn-icon btn-danger btn-sm" (click)="removeCommonFilter(i)"> | ||||||
|  |                 <clr-icon shape="trash"></clr-icon> | ||||||
|  |               </button> | ||||||
|  |             </div> | ||||||
|  |              | ||||||
|  |             <div class="clr-row" style="margin-top: 8px;"> | ||||||
|  |               <div class="clr-col-sm-5"> | ||||||
|  |                 <select [(ngModel)]="filter.field" [ngModelOptions]="{standalone: true}" class="clr-select"> | ||||||
|  |                   <option value="">Select Field</option> | ||||||
|  |                   <option *ngFor="let column of commonFilterColumnData" [value]="column">{{column}}</option> | ||||||
|  |                 </select> | ||||||
|  |               </div> | ||||||
|  |                | ||||||
|  |               <div class="clr-col-sm-5"> | ||||||
|  |                 <input type="text" [(ngModel)]="filter.value" [ngModelOptions]="{standalone: true}"  | ||||||
|  |                        class="clr-input" placeholder="Filter Value" /> | ||||||
|  |               </div> | ||||||
|  |                | ||||||
|  |               <div class="clr-col-sm-2"> | ||||||
|  |                 <button class="btn btn-icon btn-danger btn-sm" (click)="removeCommonFilter(i)"> | ||||||
|  |                   <clr-icon shape="trash"></clr-icon> | ||||||
|  |                 </button> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |     </form> | ||||||
|  |   </div> | ||||||
|  |   <div class="modal-footer"> | ||||||
|  |     <button type="button" class="btn btn-outline" (click)="commonFilterModalOpen = false">Cancel</button> | ||||||
|  |     <button type="button" class="btn btn-primary" (click)="saveCommonFilter()">Save</button> | ||||||
|  |   </div> | ||||||
|  | </clr-modal> | ||||||
|  | |||||||
| @ -40,7 +40,9 @@ export class EditnewdashComponent implements OnInit { | |||||||
|   editId: number; |   editId: number; | ||||||
|   toggle: boolean; |   toggle: boolean; | ||||||
|   modeledit: boolean = false; |   modeledit: boolean = false; | ||||||
|  |   commonFilterModalOpen: boolean = false; // Add common filter modal state
 | ||||||
|   public entryForm: FormGroup; |   public entryForm: FormGroup; | ||||||
|  |   public commonFilterForm: FormGroup; // Add common filter form
 | ||||||
| 
 | 
 | ||||||
|   WidgetsMock: WidgetModel[] = [ |   WidgetsMock: WidgetModel[] = [ | ||||||
|     { |     { | ||||||
| @ -118,6 +120,17 @@ export class EditnewdashComponent implements OnInit { | |||||||
|   model: any; |   model: any; | ||||||
|   linesdata: any; |   linesdata: any; | ||||||
|   id: any; |   id: any; | ||||||
|  | 
 | ||||||
|  |   // Add common filter data property
 | ||||||
|  |   commonFilterData = { | ||||||
|  |     connection: '', | ||||||
|  |     apiUrl: '', | ||||||
|  |     filters: [] as any[] | ||||||
|  |   }; | ||||||
|  |    | ||||||
|  |   // Add common filter column data property
 | ||||||
|  |   commonFilterColumnData: any[] = []; | ||||||
|  | 
 | ||||||
|   gadgetsEditdata = { |   gadgetsEditdata = { | ||||||
|     donut: '', |     donut: '', | ||||||
|     chartlegend: '', |     chartlegend: '', | ||||||
| @ -146,12 +159,17 @@ export class EditnewdashComponent implements OnInit { | |||||||
|     drilldownFilters: [] as any[], // Add separate drilldown filters
 |     drilldownFilters: [] as any[], // Add separate drilldown filters
 | ||||||
|     // Multi-layer drilldown configurations
 |     // Multi-layer drilldown configurations
 | ||||||
|     drilldownLayers: [] as any[], |     drilldownLayers: [] as any[], | ||||||
|  |     // Common filter property
 | ||||||
|  |     commonFilterEnabled: false | ||||||
|   }; |   }; | ||||||
|    | 
 | ||||||
|   // Add sureconnect data property
 |   // Add sureconnect data property
 | ||||||
|   sureconnectData: any[] = []; |   sureconnectData: any[] = []; | ||||||
|   layerColumnData: { [key: number]: any[] } = {}; // Add layer column data property
 |   layerColumnData: { [key: number]: any[] } = {}; // Add layer column data property
 | ||||||
| 
 | 
 | ||||||
|  |   // Add drilldown column data property
 | ||||||
|  |   drilldownColumnData = []; // Add drilldown column data property
 | ||||||
|  | 
 | ||||||
|   constructor(private route: ActivatedRoute, |   constructor(private route: ActivatedRoute, | ||||||
|     private router: Router, |     private router: Router, | ||||||
|     private dashboardService: Dashboard3Service, |     private dashboardService: Dashboard3Service, | ||||||
| @ -224,8 +242,17 @@ export class EditnewdashComponent implements OnInit { | |||||||
|       // Note: Dynamic drilldown layers and filters will be handled separately since they're complex objects
 |       // Note: Dynamic drilldown layers and filters will be handled separately since they're complex objects
 | ||||||
|     }); |     }); | ||||||
|      |      | ||||||
|  |     // Initialize common filter form
 | ||||||
|  |     this.commonFilterForm = this._fb.group({ | ||||||
|  |       connection: [''], | ||||||
|  |       apiUrl: [''] | ||||||
|  |     }); | ||||||
|  |      | ||||||
|     // Load sureconnect data first, then load dashboard data
 |     // Load sureconnect data first, then load dashboard data
 | ||||||
|     this.loadSureconnectData(); |     this.loadSureconnectData(); | ||||||
|  |      | ||||||
|  |     // Load common filter data if it exists
 | ||||||
|  |     this.loadCommonFilterData(); | ||||||
|   } |   } | ||||||
|    |    | ||||||
|   // Add method to load sureconnect data
 |   // Add method to load sureconnect data
 | ||||||
| @ -241,7 +268,14 @@ export class EditnewdashComponent implements OnInit { | |||||||
|       this.getData(); |       this.getData(); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 |    | ||||||
|  |   // Add method to load common filter data
 | ||||||
|  |   loadCommonFilterData() { | ||||||
|  |     // In a real implementation, this would fetch common filter data from the server
 | ||||||
|  |     // For now, we'll initialize with empty values
 | ||||||
|  |     console.log('Loading common filter data'); | ||||||
|  |   } | ||||||
|  |    | ||||||
|   toggleMenu() { |   toggleMenu() { | ||||||
|     this.toggle = !this.toggle; |     this.toggle = !this.toggle; | ||||||
|   } |   } | ||||||
| @ -499,6 +533,10 @@ export class EditnewdashComponent implements OnInit { | |||||||
|     if (item.showlabel === undefined) { item.showlabel = true; } |     if (item.showlabel === undefined) { item.showlabel = true; } | ||||||
|     if (item.chartcolor === undefined) { item.chartcolor = true; } |     if (item.chartcolor === undefined) { item.chartcolor = true; } | ||||||
|     if (item.chartlegend === undefined) { item.chartlegend = true; } |     if (item.chartlegend === undefined) { item.chartlegend = true; } | ||||||
|  |     // Initialize common filter property if not present
 | ||||||
|  |     if (item['commonFilterEnabled'] === undefined) {  | ||||||
|  |       this.gadgetsEditdata['commonFilterEnabled'] = false;  | ||||||
|  |     } | ||||||
|     this.getStores(); |     this.getStores(); | ||||||
|      |      | ||||||
|     // Set default connection if none is set and we have connections
 |     // Set default connection if none is set and we have connections
 | ||||||
| @ -662,6 +700,7 @@ export class EditnewdashComponent implements OnInit { | |||||||
|         xyz.baseFilters = this.gadgetsEditdata.baseFilters; // Add base filters
 |         xyz.baseFilters = this.gadgetsEditdata.baseFilters; // Add base filters
 | ||||||
|         xyz.drilldownFilters = this.gadgetsEditdata.drilldownFilters; // Add drilldown filters
 |         xyz.drilldownFilters = this.gadgetsEditdata.drilldownFilters; // Add drilldown filters
 | ||||||
|         xyz.drilldownLayers = this.gadgetsEditdata.drilldownLayers; |         xyz.drilldownLayers = this.gadgetsEditdata.drilldownLayers; | ||||||
|  |         xyz.commonFilterEnabled = this.gadgetsEditdata.commonFilterEnabled; // Add common filter property
 | ||||||
|          |          | ||||||
|         console.log(xyz); |         console.log(xyz); | ||||||
|         return xyz; |         return xyz; | ||||||
| @ -755,6 +794,7 @@ export class EditnewdashComponent implements OnInit { | |||||||
|         updatedItem.baseFilters = this.gadgetsEditdata.baseFilters; // Add base filters
 |         updatedItem.baseFilters = this.gadgetsEditdata.baseFilters; // Add base filters
 | ||||||
|         updatedItem.drilldownFilters = this.gadgetsEditdata.drilldownFilters; // Add drilldown filters
 |         updatedItem.drilldownFilters = this.gadgetsEditdata.drilldownFilters; // Add drilldown filters
 | ||||||
|         updatedItem.drilldownLayers = this.gadgetsEditdata.drilldownLayers; |         updatedItem.drilldownLayers = this.gadgetsEditdata.drilldownLayers; | ||||||
|  |         updatedItem.commonFilterEnabled = this.gadgetsEditdata.commonFilterEnabled; // Add common filter property
 | ||||||
|          |          | ||||||
|         console.log('Updated item:', updatedItem); |         console.log('Updated item:', updatedItem); | ||||||
|         return updatedItem; |         return updatedItem; | ||||||
| @ -820,7 +860,6 @@ export class EditnewdashComponent implements OnInit { | |||||||
|   } |   } | ||||||
|   selectedyAxis; |   selectedyAxis; | ||||||
|   columnData; |   columnData; | ||||||
|   drilldownColumnData = []; // Add drilldown column data property
 |  | ||||||
| 
 | 
 | ||||||
|   getColumns(id, table) { |   getColumns(id, table) { | ||||||
|     const connectionId = this.gadgetsEditdata.connection ? parseInt(this.gadgetsEditdata.connection, 10) : undefined; |     const connectionId = this.gadgetsEditdata.connection ? parseInt(this.gadgetsEditdata.connection, 10) : undefined; | ||||||
| @ -1017,4 +1056,97 @@ export class EditnewdashComponent implements OnInit { | |||||||
|   removeLayerFilter(layerIndex: number, filterIndex: number) { |   removeLayerFilter(layerIndex: number, filterIndex: number) { | ||||||
|     this.gadgetsEditdata.drilldownLayers[layerIndex].filters.splice(filterIndex, 1); |     this.gadgetsEditdata.drilldownLayers[layerIndex].filters.splice(filterIndex, 1); | ||||||
|   } |   } | ||||||
|  |    | ||||||
|  |   // Add method to open common filter modal
 | ||||||
|  |   openCommonFilterModal() { | ||||||
|  |     this.commonFilterModalOpen = true; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to add a common filter
 | ||||||
|  |   addCommonFilter() { | ||||||
|  |     const newFilter = { | ||||||
|  |       field: '', | ||||||
|  |       value: '' | ||||||
|  |     }; | ||||||
|  |     this.commonFilterData.filters.push(newFilter); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to remove a common filter
 | ||||||
|  |   removeCommonFilter(index: number) { | ||||||
|  |     this.commonFilterData.filters.splice(index, 1); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to refresh common filter columns
 | ||||||
|  |   refreshCommonFilterColumns() { | ||||||
|  |     if (this.commonFilterData.apiUrl) { | ||||||
|  |       const connectionId = this.commonFilterData.connection ? parseInt(this.commonFilterData.connection, 10) : undefined; | ||||||
|  |       this.alertService.getColumnfromurl(this.commonFilterData.apiUrl, connectionId).subscribe(data => { | ||||||
|  |         console.log('Common filter column data:', data); | ||||||
|  |         this.commonFilterColumnData = data; | ||||||
|  |       }, (error) => { | ||||||
|  |         console.log('Error fetching common filter columns:', error); | ||||||
|  |         this.commonFilterColumnData = []; | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to save common filter
 | ||||||
|  |   saveCommonFilter() { | ||||||
|  |     // Here we would typically make an API call to save the common filter
 | ||||||
|  |     // For now, we'll just close the modal
 | ||||||
|  |     console.log('Saving common filter:', this.commonFilterData); | ||||||
|  |      | ||||||
|  |     // Update all charts that have common filter enabled
 | ||||||
|  |     this.updateChartsWithCommonFilter(); | ||||||
|  |      | ||||||
|  |     this.commonFilterModalOpen = false; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to update charts with common filter data
 | ||||||
|  |   updateChartsWithCommonFilter() { | ||||||
|  |     // This method will be called when common filter is saved
 | ||||||
|  |     // It will update all charts that have common filter enabled
 | ||||||
|  |     console.log('Updating charts with common filter data'); | ||||||
|  |      | ||||||
|  |     // Update the dashboardArray to reflect changes
 | ||||||
|  |     this.dashboardArray = this.dashboardArray.map(item => { | ||||||
|  |       if (item.commonFilterEnabled) { | ||||||
|  |         // Update the chart with common filter data
 | ||||||
|  |         return { | ||||||
|  |           ...item, | ||||||
|  |           table: this.commonFilterData.apiUrl, | ||||||
|  |           connection: this.commonFilterData.connection, | ||||||
|  |           baseFilters: [...this.commonFilterData.filters] | ||||||
|  |         }; | ||||||
|  |       } | ||||||
|  |       return item; | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  |     // Also update the dashboardCollection to persist changes
 | ||||||
|  |     this.dashboardCollection.dashboard = this.dashboardCollection.dashboard.map(item => { | ||||||
|  |       if (item.commonFilterEnabled) { | ||||||
|  |         // Update the chart with common filter data
 | ||||||
|  |         return { | ||||||
|  |           ...item, | ||||||
|  |           table: this.commonFilterData.apiUrl, | ||||||
|  |           connection: this.commonFilterData.connection, | ||||||
|  |           baseFilters: [...this.commonFilterData.filters] | ||||||
|  |         } as DashboardContentModel; | ||||||
|  |       } | ||||||
|  |       return item; | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  |    | ||||||
|  |   // Add method to handle common filter toggle
 | ||||||
|  |   onCommonFilterToggle() { | ||||||
|  |     console.log('Common filter toggled:', this.gadgetsEditdata.commonFilterEnabled); | ||||||
|  |      | ||||||
|  |     if (this.gadgetsEditdata.commonFilterEnabled) { | ||||||
|  |       // When enabling common filter, save current values and apply common filter data
 | ||||||
|  |       this.gadgetsEditdata.table = this.commonFilterData.apiUrl; | ||||||
|  |       this.gadgetsEditdata.connection = this.commonFilterData.connection; | ||||||
|  |       this.gadgetsEditdata.baseFilters = [...this.commonFilterData.filters]; | ||||||
|  |     } | ||||||
|  |     // When disabling, the user can edit the filters normally
 | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -320,7 +320,7 @@ export class BarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|       drilldownConfig.apiUrl, 'bar',  |       drilldownConfig.apiUrl, 'bar',  | ||||||
|       this.drilldownXAxis, this.drilldownYAxis,  |       this.drilldownXAxis, this.drilldownYAxis,  | ||||||
|       this.connection,  |       this.connection,  | ||||||
|       parameterField, parameterValue, |       '', parameterValue, | ||||||
|       drilldownFilterParams |       drilldownFilterParams | ||||||
|     ).subscribe( |     ).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|  | |||||||
| @ -307,32 +307,13 @@ export class BubbleChartComponent implements OnInit, OnChanges { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/bubble?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/bubble?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'bubble', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'bubble', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -402,32 +402,13 @@ export class DoughnutChartComponent implements OnInit, OnChanges, AfterViewCheck | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/doughnut?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/doughnut?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'doughnut', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'doughnut', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -298,32 +298,13 @@ export class DynamicChartComponent implements OnInit, OnChanges { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/dynamic?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/dynamic?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'dynamic', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'dynamic', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -289,32 +289,13 @@ export class FinancialChartComponent implements OnInit, OnChanges { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/financial?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/financial?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'financial', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'financial', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -313,32 +313,13 @@ export class LineChartComponent implements OnInit, OnChanges { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/line?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/line?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'line', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'line', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -362,32 +362,13 @@ export class PieChartComponent implements OnInit, OnChanges, AfterViewChecked { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/pie?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/pie?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'pie', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'pie', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -1,13 +1,12 @@ | |||||||
| import { Component, Input, OnInit, OnChanges, OnDestroy, SimpleChanges } from '@angular/core'; | import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core'; | ||||||
| import { Dashboard3Service } from '../../../../../../services/builder/dashboard3.service'; | import { Dashboard3Service } from 'src/app/services/builder/dashboard3.service'; | ||||||
| import { Subscription } from 'rxjs'; |  | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
|   selector: 'app-polar-chart', |   selector: 'app-polar-chart', | ||||||
|   templateUrl: './polar-chart.component.html', |   templateUrl: './polar-chart.component.html', | ||||||
|   styleUrls: ['./polar-chart.component.scss'] |   styleUrls: ['./polar-chart.component.scss'] | ||||||
| }) | }) | ||||||
| export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | export class PolarChartComponent implements OnInit, OnChanges { | ||||||
|   @Input() xAxis: string; |   @Input() xAxis: string; | ||||||
|   @Input() yAxis: string | string[]; |   @Input() yAxis: string | string[]; | ||||||
|   @Input() table: string; |   @Input() table: string; | ||||||
| @ -36,24 +35,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
| 
 | 
 | ||||||
|   constructor(private dashboardService: Dashboard3Service) { } |   constructor(private dashboardService: Dashboard3Service) { } | ||||||
| 
 | 
 | ||||||
|   public polarAreaChartLabels: string[] = [ 'Download Sales', 'In-Store Sales', 'Mail Sales', 'Telesales', 'Corporate Sales' ]; |  | ||||||
|   public polarAreaChartData: any = [ |  | ||||||
|     { data: [ 300, 500, 100, 40, 120 ], label: 'Series 1'} |  | ||||||
|   ]; |  | ||||||
|   public polarAreaChartType: string = 'polarArea'; |  | ||||||
|    |  | ||||||
|   // Multi-layer drilldown state tracking
 |  | ||||||
|   drilldownStack: any[] = []; // Stack to track drilldown navigation history
 |  | ||||||
|   currentDrilldownLevel: number = 0; // Current drilldown level (0 = base level)
 |  | ||||||
|   originalPolarAreaChartLabels: string[] = []; |  | ||||||
|   originalPolarAreaChartData: any = []; |  | ||||||
|    |  | ||||||
|   // No data state
 |  | ||||||
|   noDataAvailable: boolean = false; |  | ||||||
|    |  | ||||||
|   // Flag to prevent infinite loops
 |  | ||||||
|   private isFetchingData: boolean = false; |  | ||||||
| 
 |  | ||||||
|   ngOnInit(): void { |   ngOnInit(): void { | ||||||
|     // Initialize with default data
 |     // Initialize with default data
 | ||||||
|     this.fetchChartData(); |     this.fetchChartData(); | ||||||
| @ -84,7 +65,26 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|       this.fetchChartData(); |       this.fetchChartData(); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |    | ||||||
|  |   public polarAreaChartLabels: string[] = [ 'Download Sales', 'In-Store Sales', 'Mail Sales', 'Telesales', 'Corporate Sales' ]; | ||||||
|  |   public polarAreaChartData: any = [ | ||||||
|  |     { data: [ 300, 500, 100, 40, 120 ], label: 'Series 1'} | ||||||
|  |   ]; | ||||||
| 
 | 
 | ||||||
|  |   public polarAreaChartType: string = 'polarArea'; | ||||||
|  |    | ||||||
|  |   // Multi-layer drilldown state tracking
 | ||||||
|  |   drilldownStack: any[] = []; // Stack to track drilldown navigation history
 | ||||||
|  |   currentDrilldownLevel: number = 0; // Current drilldown level (0 = base level)
 | ||||||
|  |   originalPolarAreaChartLabels: string[] = []; | ||||||
|  |   originalPolarAreaChartData: any = []; | ||||||
|  |    | ||||||
|  |   // No data state
 | ||||||
|  |   noDataAvailable: boolean = false; | ||||||
|  |    | ||||||
|  |   // Flag to prevent infinite loops
 | ||||||
|  |   private isFetchingData: boolean = false; | ||||||
|  |    | ||||||
|   fetchChartData(): void { |   fetchChartData(): void { | ||||||
|     // Set flag to prevent recursive calls
 |     // Set flag to prevent recursive calls
 | ||||||
|     this.isFetchingData = true; |     this.isFetchingData = true; | ||||||
| @ -133,8 +133,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|             this.noDataAvailable = true; |             this.noDataAvailable = true; | ||||||
|             this.polarAreaChartLabels = []; |             this.polarAreaChartLabels = []; | ||||||
|             this.polarAreaChartData = []; |             this.polarAreaChartData = []; | ||||||
|             // Validate and sanitize data to show default data
 |  | ||||||
|             this.validateChartData(); |  | ||||||
|             // Reset flag after fetching
 |             // Reset flag after fetching
 | ||||||
|             this.isFetchingData = false; |             this.isFetchingData = false; | ||||||
|             return; |             return; | ||||||
| @ -145,36 +143,26 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|             // For polar charts, we need to extract the data differently
 |             // For polar charts, we need to extract the data differently
 | ||||||
|             // The first dataset's data array contains the values for the polar chart
 |             // The first dataset's data array contains the values for the polar chart
 | ||||||
|             this.noDataAvailable = data.chartLabels.length === 0; |             this.noDataAvailable = data.chartLabels.length === 0; | ||||||
|             this.polarAreaChartLabels = data.chartLabels || []; |             this.polarAreaChartLabels = data.chartLabels; | ||||||
|             if (data.chartData && data.chartData.length > 0) { |             if (data.chartData && data.chartData.length > 0) { | ||||||
|               this.polarAreaChartData = data.chartData[0].data.map(value => { |               this.polarAreaChartData = data.chartData[0].data.map(value => { | ||||||
|                 // Convert to number if it's not already
 |                 // Convert to number if it's not already
 | ||||||
|                 const numValue = Number(value); |                 return isNaN(Number(value)) ? 0 : Number(value); | ||||||
|                 return isNaN(numValue) ? 0 : numValue; |  | ||||||
|               }); |               }); | ||||||
|             } else { |             } else { | ||||||
|               this.polarAreaChartData = []; |               this.polarAreaChartData = []; | ||||||
|             } |             } | ||||||
|             // Ensure labels and data arrays have the same length
 |  | ||||||
|             this.syncLabelAndDataArrays(); |  | ||||||
|             // Validate and sanitize data
 |  | ||||||
|             this.validateChartData(); |  | ||||||
|             // Trigger change detection
 |             // Trigger change detection
 | ||||||
|             this.polarAreaChartData = [...this.polarAreaChartData]; |             this.polarAreaChartData = [...this.polarAreaChartData]; | ||||||
|             console.log('Updated polar chart with data:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); |             console.log('Updated polar chart with data:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); | ||||||
|           } else if (data && data.labels && data.data) { |           } else if (data && data.labels && data.data) { | ||||||
|             // Handle the original expected format as fallback
 |             // Handle the original expected format as fallback
 | ||||||
|             this.noDataAvailable = data.labels.length === 0; |             this.noDataAvailable = data.labels.length === 0; | ||||||
|             this.polarAreaChartLabels = data.labels || []; |             this.polarAreaChartLabels = data.labels; | ||||||
|             this.polarAreaChartData = data.data.map(value => { |             this.polarAreaChartData = data.data.map(value => { | ||||||
|               // Convert to number if it's not already
 |               // Convert to number if it's not already
 | ||||||
|               const numValue = Number(value); |               return isNaN(Number(value)) ? 0 : Number(value); | ||||||
|               return isNaN(numValue) ? 0 : numValue; |  | ||||||
|             }); |             }); | ||||||
|             // Ensure labels and data arrays have the same length
 |  | ||||||
|             this.syncLabelAndDataArrays(); |  | ||||||
|             // Validate and sanitize data
 |  | ||||||
|             this.validateChartData(); |  | ||||||
|             // Trigger change detection
 |             // Trigger change detection
 | ||||||
|             this.polarAreaChartData = [...this.polarAreaChartData]; |             this.polarAreaChartData = [...this.polarAreaChartData]; | ||||||
|             console.log('Updated polar chart with legacy data format:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); |             console.log('Updated polar chart with legacy data format:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); | ||||||
| @ -183,8 +171,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|             this.noDataAvailable = true; |             this.noDataAvailable = true; | ||||||
|             this.polarAreaChartLabels = []; |             this.polarAreaChartLabels = []; | ||||||
|             this.polarAreaChartData = []; |             this.polarAreaChartData = []; | ||||||
|             // Validate and sanitize data
 |  | ||||||
|             this.validateChartData(); |  | ||||||
|           } |           } | ||||||
|           // Reset flag after fetching
 |           // Reset flag after fetching
 | ||||||
|           this.isFetchingData = false; |           this.isFetchingData = false; | ||||||
| @ -194,8 +180,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|           this.noDataAvailable = true; |           this.noDataAvailable = true; | ||||||
|           this.polarAreaChartLabels = []; |           this.polarAreaChartLabels = []; | ||||||
|           this.polarAreaChartData = []; |           this.polarAreaChartData = []; | ||||||
|           // Validate and sanitize data to show default data
 |  | ||||||
|           this.validateChartData(); |  | ||||||
|           // Reset flag after fetching
 |           // Reset flag after fetching
 | ||||||
|           this.isFetchingData = false; |           this.isFetchingData = false; | ||||||
|           // Keep default data in case of error
 |           // Keep default data in case of error
 | ||||||
| @ -206,8 +190,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|       this.noDataAvailable = true; |       this.noDataAvailable = true; | ||||||
|       this.polarAreaChartLabels = []; |       this.polarAreaChartLabels = []; | ||||||
|       this.polarAreaChartData = []; |       this.polarAreaChartData = []; | ||||||
|       // Validate and sanitize data to show default data
 |  | ||||||
|       this.validateChartData(); |  | ||||||
|       // Reset flag after fetching
 |       // Reset flag after fetching
 | ||||||
|       this.isFetchingData = false; |       this.isFetchingData = false; | ||||||
|     } |     } | ||||||
| @ -305,32 +287,13 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/polar?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/polar?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'polar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'polar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
| @ -346,36 +309,26 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|           // For polar charts, we need to extract the data differently
 |           // For polar charts, we need to extract the data differently
 | ||||||
|           // The first dataset's data array contains the values for the polar chart
 |           // The first dataset's data array contains the values for the polar chart
 | ||||||
|           this.noDataAvailable = data.chartLabels.length === 0; |           this.noDataAvailable = data.chartLabels.length === 0; | ||||||
|           this.polarAreaChartLabels = data.chartLabels || []; |           this.polarAreaChartLabels = data.chartLabels; | ||||||
|           if (data.chartData && data.chartData.length > 0) { |           if (data.chartData && data.chartData.length > 0) { | ||||||
|             this.polarAreaChartData = data.chartData[0].data.map(value => { |             this.polarAreaChartData = data.chartData[0].data.map(value => { | ||||||
|               // Convert to number if it's not already
 |               // Convert to number if it's not already
 | ||||||
|               const numValue = Number(value); |               return isNaN(Number(value)) ? 0 : Number(value); | ||||||
|               return isNaN(numValue) ? 0 : numValue; |  | ||||||
|             }); |             }); | ||||||
|           } else { |           } else { | ||||||
|             this.polarAreaChartData = []; |             this.polarAreaChartData = []; | ||||||
|           } |           } | ||||||
|           // Ensure labels and data arrays have the same length
 |  | ||||||
|           this.syncLabelAndDataArrays(); |  | ||||||
|           // Validate and sanitize data
 |  | ||||||
|           this.validateChartData(); |  | ||||||
|           // Trigger change detection
 |           // Trigger change detection
 | ||||||
|           this.polarAreaChartData = [...this.polarAreaChartData]; |           this.polarAreaChartData = [...this.polarAreaChartData]; | ||||||
|           console.log('Updated polar chart with drilldown data:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); |           console.log('Updated polar chart with drilldown data:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); | ||||||
|         } else if (data && data.labels && data.data) { |         } else if (data && data.labels && data.data) { | ||||||
|           // Handle the original expected format as fallback
 |           // Handle the original expected format as fallback
 | ||||||
|           this.noDataAvailable = data.labels.length === 0; |           this.noDataAvailable = data.labels.length === 0; | ||||||
|           this.polarAreaChartLabels = data.labels || []; |           this.polarAreaChartLabels = data.labels; | ||||||
|           this.polarAreaChartData = data.data.map(value => { |           this.polarAreaChartData = data.data.map(value => { | ||||||
|             // Convert to number if it's not already
 |             // Convert to number if it's not already
 | ||||||
|             const numValue = Number(value); |             return isNaN(Number(value)) ? 0 : Number(value); | ||||||
|             return isNaN(numValue) ? 0 : numValue; |  | ||||||
|           }); |           }); | ||||||
|           // Ensure labels and data arrays have the same length
 |  | ||||||
|           this.syncLabelAndDataArrays(); |  | ||||||
|           // Validate and sanitize data
 |  | ||||||
|           this.validateChartData(); |  | ||||||
|           // Trigger change detection
 |           // Trigger change detection
 | ||||||
|           this.polarAreaChartData = [...this.polarAreaChartData]; |           this.polarAreaChartData = [...this.polarAreaChartData]; | ||||||
|           console.log('Updated polar chart with drilldown legacy data format:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); |           console.log('Updated polar chart with drilldown legacy data format:', { labels: this.polarAreaChartLabels, data: this.polarAreaChartData }); | ||||||
| @ -384,8 +337,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|           this.noDataAvailable = true; |           this.noDataAvailable = true; | ||||||
|           this.polarAreaChartLabels = []; |           this.polarAreaChartLabels = []; | ||||||
|           this.polarAreaChartData = []; |           this.polarAreaChartData = []; | ||||||
|           // Validate and sanitize data
 |  | ||||||
|           this.validateChartData(); |  | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|       (error) => { |       (error) => { | ||||||
| @ -454,58 +405,6 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |  | ||||||
|    * Validate and sanitize chart data |  | ||||||
|    */ |  | ||||||
|   private validateChartData(): void { |  | ||||||
|     // Ensure we have valid arrays
 |  | ||||||
|     if (!Array.isArray(this.polarAreaChartLabels)) { |  | ||||||
|       this.polarAreaChartLabels = []; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (!Array.isArray(this.polarAreaChartData)) { |  | ||||||
|       this.polarAreaChartData = []; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     // If we have no data, show default data
 |  | ||||||
|     if (this.polarAreaChartLabels.length === 0 && this.polarAreaChartData.length === 0) { |  | ||||||
|       // Add default data to ensure chart visibility
 |  | ||||||
|       this.polarAreaChartLabels = ['Download Sales', 'In-Store Sales', 'Mail Sales', 'Telesales', 'Corporate Sales']; |  | ||||||
|       this.polarAreaChartData = [300, 500, 100, 40, 120]; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     // Ensure we have matching arrays
 |  | ||||||
|     if (this.polarAreaChartLabels.length !== this.polarAreaChartData.length) { |  | ||||||
|       const maxLength = Math.max(this.polarAreaChartLabels.length, this.polarAreaChartData.length); |  | ||||||
|       while (this.polarAreaChartLabels.length < maxLength) { |  | ||||||
|         this.polarAreaChartLabels.push(`Label ${this.polarAreaChartLabels.length + 1}`); |  | ||||||
|       } |  | ||||||
|       while (this.polarAreaChartData.length < maxLength) { |  | ||||||
|         this.polarAreaChartData.push(0); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|    |  | ||||||
|   // Ensure labels and data arrays have the same length
 |  | ||||||
|   private syncLabelAndDataArrays(): void { |  | ||||||
|     if (this.polarAreaChartLabels && this.polarAreaChartData) { |  | ||||||
|       const labelCount = this.polarAreaChartLabels.length; |  | ||||||
|       const dataCount = this.polarAreaChartData.length; |  | ||||||
|        |  | ||||||
|       if (labelCount > dataCount) { |  | ||||||
|         // Add zeros to data array
 |  | ||||||
|         while (this.polarAreaChartData.length < labelCount) { |  | ||||||
|           this.polarAreaChartData.push(0); |  | ||||||
|         } |  | ||||||
|       } else if (dataCount > labelCount) { |  | ||||||
|         // Add labels to label array
 |  | ||||||
|         while (this.polarAreaChartLabels.length < dataCount) { |  | ||||||
|           this.polarAreaChartLabels.push(`Item ${this.polarAreaChartLabels.length + 1}`); |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   // events
 |   // events
 | ||||||
|   public chartClicked(e: any): void { |   public chartClicked(e: any): void { | ||||||
|     console.log('Polar chart clicked:', e); |     console.log('Polar chart clicked:', e); | ||||||
| @ -594,8 +493,4 @@ export class PolarChartComponent implements OnInit, OnChanges, OnDestroy { | |||||||
|   public chartHovered(e: any): void { |   public chartHovered(e: any): void { | ||||||
|     console.log(e); |     console.log(e); | ||||||
|   } |   } | ||||||
|    |  | ||||||
|   ngOnDestroy(): void { |  | ||||||
|     // Clean up any subscriptions if needed
 |  | ||||||
|   } |  | ||||||
| } | } | ||||||
| @ -298,32 +298,13 @@ export class RadarChartComponent implements OnInit, OnChanges { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // Convert drilldownFilters to filter parameters for drilldown level
 |  | ||||||
|     let drilldownFilterParams = ''; |  | ||||||
|     if (this.drilldownFilters && this.drilldownFilters.length > 0) { |  | ||||||
|       const filterObj = {}; |  | ||||||
|       this.drilldownFilters.forEach(filter => { |  | ||||||
|         if (filter.field && filter.value) { |  | ||||||
|           filterObj[filter.field] = filter.value; |  | ||||||
|         } |  | ||||||
|       }); |  | ||||||
|       if (Object.keys(filterObj).length > 0) { |  | ||||||
|         drilldownFilterParams = JSON.stringify(filterObj); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     console.log('Drilldown filter parameters:', drilldownFilterParams); |  | ||||||
|      |  | ||||||
|     // Use drilldown filters if available, otherwise use layer filters
 |  | ||||||
|     const finalFilterParams = drilldownFilterParams || filterParams; |  | ||||||
|     console.log('Final filter parameters:', finalFilterParams); |  | ||||||
|      |  | ||||||
|     // Log the URL that will be called
 |     // Log the URL that will be called
 | ||||||
|     const url = `chart/getdashjson/radar?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; |     const url = `chart/getdashjson/radar?tableName=${actualApiUrl}&xAxis=${drilldownConfig.xAxis}&yAxes=${drilldownConfig.yAxis}${this.connection ? `&sureId=${this.connection}` : ''}`; | ||||||
|     console.log('Drilldown data URL:', url); |     console.log('Drilldown data URL:', url); | ||||||
|      |      | ||||||
|     // Fetch data from the dashboard service with parameter field and value
 |     // Fetch data from the dashboard service with parameter field and value
 | ||||||
|     // Backend handles filtering, we just pass the parameter field and value
 |     // Backend handles filtering, we just pass the parameter field and value
 | ||||||
|     this.dashboardService.getChartData(actualApiUrl, 'radar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, finalFilterParams).subscribe( |     this.dashboardService.getChartData(actualApiUrl, 'radar', drilldownConfig.xAxis, drilldownConfig.yAxis, this.connection, parameterField, parameterValue, filterParams).subscribe( | ||||||
|       (data: any) => { |       (data: any) => { | ||||||
|         console.log('Received drilldown data:', data); |         console.log('Received drilldown data:', data); | ||||||
|         if (data === null) { |         if (data === null) { | ||||||
|  | |||||||
| @ -515,4 +515,4 @@ export class ScatterChartComponent implements OnInit, OnChanges { | |||||||
|   public chartHovered(e: any): void { |   public chartHovered(e: any): void { | ||||||
|     console.log(e); |     console.log(e); | ||||||
|   } |   } | ||||||
| } | }   | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user